1 | =====================
|
---|
2 | The sitemap framework
|
---|
3 | =====================
|
---|
4 |
|
---|
5 | Django comes with a high-level sitemap-generating framework that makes
|
---|
6 | creating `Google Sitemap`_ XML files easy.
|
---|
7 |
|
---|
8 | .. _Google Sitemap: http://www.google.com/webmasters/sitemaps/docs/en/protocol.html
|
---|
9 |
|
---|
10 | The "sitemap" framework
|
---|
11 | =======================
|
---|
12 |
|
---|
13 | Overview
|
---|
14 | --------
|
---|
15 |
|
---|
16 | The sitemap-generating framework is based largely off of Django's
|
---|
17 | `syndication framework`_. You tell the framework what you want to include
|
---|
18 | in your sitemap by creating ``Sitemap`` classes and pointing to them
|
---|
19 | in your URLconf_.
|
---|
20 |
|
---|
21 | .. _syndication framework: http://www.djangoproject.com/documentation/syndication/
|
---|
22 | .. _URLconf: http://www.djangoproject.com/documentation/url_dispatch/
|
---|
23 |
|
---|
24 | Installation
|
---|
25 | ------------
|
---|
26 |
|
---|
27 | To install the sitemap app, follow these steps:
|
---|
28 |
|
---|
29 | 1. Add ``'django.contrib.sitemap'`` to your INSTALLED_APPS_ setting.
|
---|
30 | 2. Make sure ``'django.template.loaders.app_directories.load_template_source'``
|
---|
31 | is in your TEMPLATE_LOADERS_ setting.
|
---|
32 |
|
---|
33 | .. _INSTALLED_APPS: http://www.djangoproject.com/documentation/settings/#installed-apps
|
---|
34 | .. _TEMPLATE_LOADERS: http://www.djangoproject.com/documentation/settings/#template-loaders
|
---|
35 |
|
---|
36 | Initialization
|
---|
37 | --------------
|
---|
38 |
|
---|
39 | To activate sitemap generation on your Django site, add this line to your
|
---|
40 | URLconf_:
|
---|
41 |
|
---|
42 | ( r'^sitemap.xml$', 'django.contrib.sitemap.views.sitemap', {'sitemaps': sitemaps} )
|
---|
43 |
|
---|
44 | This will tell Django to build a sitemap when a client accesses ``/sitemap.xml``.
|
---|
45 | The name of the sitemap is not important, but the location is. Google will only
|
---|
46 | index links in your sitemap for the current URL level and below. For instance, if
|
---|
47 | ``sitemap.xml`` lives in your root directory, it may reference any URL in your
|
---|
48 | site. However, if your sitemap lives at ``/content/sitemap.xml``, it may only
|
---|
49 | reference URLs under ``/content/``.
|
---|
50 |
|
---|
51 | The sitemap view takes an extra argument: ``{'sitemaps': sitemaps}``. ``sitemaps``
|
---|
52 | should be a dictionary that maps a short section label (i.e. ``blog`` or ``news``)
|
---|
53 | to its ``Sitemap`` class (i.e. ``BlogSitemap`` or ``NewsSitemap``). It may also map
|
---|
54 | to an instance of a ``Sitemap`` class (i.e. ``BlogSitemap(some_var)``).
|
---|
55 |
|
---|
56 | .. _URLconf: http://www.djangoproject.com/documentation/url_dispatch/
|
---|
57 |
|
---|
58 | Sitemap Classes
|
---|
59 | ---------------
|
---|
60 |
|
---|
61 | A ``Sitemap`` class is a simple python class that represents a "section" of
|
---|
62 | entries in your sitemap. In the simplest case, all these sections get lumped
|
---|
63 | together in one ``sitemap.xml``. It is also possible to use the framework to
|
---|
64 | generate a sitemap index that references individual sitemap files, one per
|
---|
65 | section.
|
---|
66 |
|
---|
67 | ``Sitemap`` classes must subclass ``django.contrib.sitemap.Sitemap``. They can
|
---|
68 | live anywhere in your codebase.
|
---|
69 |
|
---|
70 | A simple example
|
---|
71 | ----------------
|
---|
72 |
|
---|
73 | Let's assume you have an ``Entry`` model in your blog, and you want to include
|
---|
74 | all the individual links to your blog entries in your sitemap::
|
---|
75 |
|
---|
76 | from django.contrib.sitemap import Sitemap
|
---|
77 | from myproject.blog.models import Entry
|
---|
78 |
|
---|
79 | class BlogSitemap(Sitemap):
|
---|
80 | changefreq = "never"
|
---|
81 | priority = 0.5
|
---|
82 |
|
---|
83 | def items(self):
|
---|
84 | return Entry.objects.filter(is_draft=False)
|
---|
85 |
|
---|
86 | def lastmod(self, obj):
|
---|
87 | return obj.pub_date
|
---|
88 |
|
---|
89 | Note:
|
---|
90 |
|
---|
91 | * ``changefreq`` and ``priority`` are class attributes corresponding to
|
---|
92 | ``<changefreq>`` and ``<priority>`` elements, respectively. They could be
|
---|
93 | made callable as functions, as ``lastmod`` was in the example.
|
---|
94 | * ``items()`` is simply a method that returns a list of objects. The objects
|
---|
95 | returned will get passed to any callable methods corresponding to a sitemap
|
---|
96 | property (``location``, ``lastmod``, ``changefreq``, and ``priority``).
|
---|
97 | * ``lastmod`` should return a ``datetime`` object.
|
---|
98 | * There is no ``location`` method. ``Sitemap`` provides a default implementation
|
---|
99 | for you that calls ``get_absolute_url()`` on each object and returns the result.
|
---|
100 |
|
---|
101 | Shortcuts
|
---|
102 | ---------
|
---|
103 |
|
---|
104 | The sitemap framework provides a couple convenience classes for common cases:
|
---|
105 |
|
---|
106 | * FlatpageSitemap
|
---|
107 | * GenericSitemap
|
---|
108 |
|
---|
109 | The ``FlatpageSitemap`` class looks at all flatpages_ defined for the current ``SITE_ID``
|
---|
110 | (see the sites_ documentation) and creates an entry in the sitemap. These entries include
|
---|
111 | only the ``location`` attribute.
|
---|
112 |
|
---|
113 | The ``GenericSitemap`` class works with any `generic views`_ you already have. To use
|
---|
114 | it, create an instance, passing in the same ``info_dict`` you pass to the
|
---|
115 | generic views. The only requirement is that the dict have a ``queryset`` entry.
|
---|
116 | It may also have a ``date_field`` entry that specifies a date field for objects
|
---|
117 | retrieved from the ``queryset``. This will be used for the ``lastmod`` attribute in
|
---|
118 | the generated sitemap. You may also pass ``priority`` and ``changefreq`` keyword
|
---|
119 | arguments to the ``GenericSitemap`` constructor to specify these attributes for all
|
---|
120 | URLs.
|
---|
121 |
|
---|
122 | Here's an example of a URLconf_ using both::
|
---|
123 |
|
---|
124 | from django.conf.urls.defaults import *
|
---|
125 | from django.contrib.sitemap import FlatpageSitemap, GenericSitemap
|
---|
126 | from myproject.blog.models import Entry
|
---|
127 |
|
---|
128 | info_dict = {
|
---|
129 | 'queryset': Entry.objects.all(),
|
---|
130 | 'date_field': 'pub_date',
|
---|
131 | }
|
---|
132 |
|
---|
133 | sitemaps = {
|
---|
134 | 'flatpages': FlatpageSitemap,
|
---|
135 | 'blog': GenericSitemap(info_dict, priority=0.6),
|
---|
136 | }
|
---|
137 |
|
---|
138 | urlpatterns = patterns('',
|
---|
139 | # ... some generic view using info_dict
|
---|
140 | ( r'^sitemap.xml$', 'django.contrib.sitemap.views.sitemap', {'sitemaps': sitemaps} )
|
---|
141 | )
|
---|
142 |
|
---|
143 | .. _flatpages: http://www.djangoproject.com/documentation/flatpages/
|
---|
144 | .. _sites: http://www.djangoproject.com/documentation/sites/
|
---|
145 | .. _generic views: http://www.djangoproject.com/documentation/generic_views/
|
---|
146 | .. _URLconf: http://www.djangoproject.com/documentation/url_dispatch/
|
---|
147 |
|
---|
148 | Creating a sitemap index
|
---|
149 | ------------------------
|
---|
150 |
|
---|
151 | The sitemap framework also has the ability to create a sitemap index
|
---|
152 | that references individual sitemap files, one per each section defined
|
---|
153 | in your ``sitemaps`` dict. The only differences in usage are:
|
---|
154 |
|
---|
155 | * You use two views in your URLconf: ``django.contrib.sitemap.views.index``
|
---|
156 | and ``django.contrib.sitemap.views.sitemap``
|
---|
157 | * The ``django.contrib.sitemap.views.sitemap`` view should take a
|
---|
158 | ``section`` keyword argument.
|
---|
159 |
|
---|
160 | Here is what the relevant URLconf lines would look like for the example above::
|
---|
161 |
|
---|
162 | ( r'^sitemap.xml$', 'django.contrib.sitemap.views.index', {'sitemaps': sitemaps} )
|
---|
163 | ( r'^sitemap-(?P<section>.+).xml$', 'django.contrib.sitemap.views.sitemap', {'sitemaps': sitemaps} )
|
---|
164 |
|
---|
165 | This will automatically generate a ``sitemap.xml`` file that references
|
---|
166 | both ``sitemap-flatpages.xml`` and ``sitemap-blog.xml``. The ``Sitemap``
|
---|
167 | classes and the ``sitemaps`` dict don't change at all.
|
---|
168 |
|
---|
169 | Pinging Google
|
---|
170 | --------------
|
---|
171 |
|
---|
172 | For sites with dynamic content, it may be desirable to "ping" Google when
|
---|
173 | your sitemap changes, to let them know to re-index your site. The framework
|
---|
174 | provides a function to do just that: ``ping_google()``. This will automatically
|
---|
175 | determine your sitemap URL and send a ping to Google.
|
---|
176 |
|
---|
177 | One useful way to call ``ping_google()`` is from a model's ``save()`` method::
|
---|
178 |
|
---|
179 | from django.contrib.sitemap import ping_google
|
---|
180 |
|
---|
181 | def save(self):
|
---|
182 | super(Entry, self).save()
|
---|
183 | try:
|
---|
184 | ping_google()
|
---|
185 | except:
|
---|
186 | pass
|
---|
187 |
|
---|
188 | A more efficient solution, however, would be to call ``ping_google()`` from a
|
---|
189 | cron script, or some other scheduled task.
|
---|