mirror of
https://github.com/django/django.git
synced 2025-10-24 22:26:08 +00:00
Fixed #2628 -- Added django.contrib.sitemap. Thanks for the patch, Dan Watson
git-svn-id: http://code.djangoproject.com/svn/django/trunk@3694 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
90
django/contrib/sitemap/__init__.py
Normal file
90
django/contrib/sitemap/__init__.py
Normal file
@@ -0,0 +1,90 @@
|
||||
from django.core import urlresolvers
|
||||
import urllib
|
||||
|
||||
PING_URL = "http://www.google.com/webmasters/sitemaps/ping"
|
||||
|
||||
class SitemapNotFound(Exception):
|
||||
pass
|
||||
|
||||
def ping_google(sitemap_url=None, ping_url=PING_URL):
|
||||
"""
|
||||
Alerts Google that the sitemap for the current site has been updated.
|
||||
If sitemap_url is provided, it should be an absolute path to the sitemap
|
||||
for this site -- e.g., '/sitemap.xml'. If sitemap_url is not provided, this
|
||||
function will attempt to deduce it by using urlresolvers.reverse().
|
||||
"""
|
||||
if sitemap_url is None:
|
||||
try:
|
||||
# First, try to get the "index" sitemap URL.
|
||||
sitemap_url = urlresolvers.reverse('django.contrib.sitemap.views.index')
|
||||
except urlresolvers.NoReverseMatch:
|
||||
try:
|
||||
# Next, try for the "global" sitemap URL.
|
||||
sitemap_url = urlresolvers.reverse('django.contrib.sitemap.views.sitemap')
|
||||
except urlresolvers.NoReverseMatch:
|
||||
pass
|
||||
|
||||
if sitemap_url is None:
|
||||
raise SitemapNotFound("You didn't provide a sitemap_url, and the sitemap URL couldn't be auto-detected.")
|
||||
|
||||
from django.contrib.sites.models import Site
|
||||
current_site = Site.objects.get_current()
|
||||
url = "%s%s" % (current_site.domain, sitemap)
|
||||
params = urllib.urlencode({'sitemap':url})
|
||||
urllib.urlopen("%s?%s" % (ping_url, params))
|
||||
|
||||
class Sitemap:
|
||||
def __get(self, name, obj, default=None):
|
||||
try:
|
||||
attr = getattr(self, name)
|
||||
except AttributeError:
|
||||
return default
|
||||
if callable(attr):
|
||||
return attr(obj)
|
||||
return attr
|
||||
|
||||
def items(self):
|
||||
return []
|
||||
|
||||
def location(self, obj):
|
||||
return obj.get_absolute_url()
|
||||
|
||||
def get_urls(self):
|
||||
from django.contrib.sites.models import Site
|
||||
current_site = Site.objects.get_current()
|
||||
urls = []
|
||||
for item in self.items():
|
||||
loc = "http://%s%s" % (current_site.domain, self.__get('location', item))
|
||||
url_info = {
|
||||
'location': loc,
|
||||
'lastmod': self.__get('lastmod', item, None),
|
||||
'changefreq': self.__get('changefreq', item, None),
|
||||
'priority': self.__get('priority', item, None)
|
||||
}
|
||||
urls.append(url_info)
|
||||
return urls
|
||||
|
||||
class FlatpageSitemap(Sitemap):
|
||||
def items(self):
|
||||
from django.contrib.sites.models import Site
|
||||
current_site = Site.objects.get_current()
|
||||
return current_site.flatpage_set.all()
|
||||
|
||||
class GenericSitemap(Sitemap):
|
||||
priority = None
|
||||
changefreq = None
|
||||
|
||||
def __init__(self, info_dict, priority=None, changefreq=None):
|
||||
self.queryset = info_dict['queryset']
|
||||
self.date_field = info_dict.get('date_field', None)
|
||||
self.priority = priority
|
||||
self.changefreq = changefreq
|
||||
|
||||
def items(self):
|
||||
# Make sure to return a clone; we don't want premature evaluation.
|
||||
return self.queryset.filter()
|
||||
|
||||
def lastmod(self, item):
|
||||
if self.date_field is not None:
|
||||
return getattr(item, self.date_field)
|
||||
return None
|
||||
11
django/contrib/sitemap/templates/sitemap.xml
Normal file
11
django/contrib/sitemap/templates/sitemap.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.google.com/schemas/sitemap/0.84">
|
||||
{% for url in urlset %}
|
||||
<url>
|
||||
<loc>{{ url.location|escape }}</loc>
|
||||
{% if url.lastmod %}<lastmod>{{ url.lastmod|date:"Y-m-d" }}</lastmod>{% endif %}
|
||||
{% if url.changefreq %}<changefreq>{{ url.changefreq }}</changefreq>{% endif %}
|
||||
{% if url.priority %}<priority>{{ url.priority }}</priority>{% endif %}
|
||||
</url>
|
||||
{% endfor %}
|
||||
</urlset>
|
||||
8
django/contrib/sitemap/templates/sitemap_index.xml
Normal file
8
django/contrib/sitemap/templates/sitemap_index.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<sitemapindex xmlns="http://www.google.com/schemas/sitemap/0.84">
|
||||
{% for location in sitemaps %}
|
||||
<sitemap>
|
||||
<loc>{{ location|escape }}</loc>
|
||||
</sitemap>
|
||||
{% endfor %}
|
||||
</sitemapindex>
|
||||
30
django/contrib/sitemap/views.py
Normal file
30
django/contrib/sitemap/views.py
Normal file
@@ -0,0 +1,30 @@
|
||||
from django.http import HttpResponse, Http404
|
||||
from django.template import loader
|
||||
from django.contrib.sites.models import Site
|
||||
from django.core import urlresolvers
|
||||
|
||||
def index(request, sitemaps):
|
||||
current_site = Site.objects.get_current()
|
||||
sites = []
|
||||
protocol = request.is_secure() and 'https' or 'http'
|
||||
for section in sitemaps.keys():
|
||||
sitemap_url = urlresolvers.reverse('django.contrib.sitemap.views.sitemap', kwargs={'section': section})
|
||||
sites.append('%s://%s%s' % (protocol, current_site.domain, sitemap_url))
|
||||
xml = loader.render_to_string('sitemap_index.xml', {'sitemaps': sites})
|
||||
return HttpResponse(xml, mimetype='application/xml')
|
||||
|
||||
def sitemap(request, sitemaps, section=None):
|
||||
maps, urls = [], []
|
||||
if section is not None:
|
||||
if not sitemaps.has_key(section):
|
||||
raise Http404("No sitemap available for section: %r" % section)
|
||||
maps.append(sitemaps[section])
|
||||
else:
|
||||
maps = sitemaps.values()
|
||||
for site in maps:
|
||||
if callable(site):
|
||||
urls.extend(site().get_urls())
|
||||
else:
|
||||
urls.extend(site.get_urls())
|
||||
xml = loader.render_to_string('sitemap.xml', {'urlset': urls})
|
||||
return HttpResponse(xml, mimetype='application/xml')
|
||||
Reference in New Issue
Block a user