diff --git a/AUTHORS b/AUTHORS
index 472d53c..c86c734 100644
a
|
b
|
answer newbie questions, and generally made Django that much better:
|
483 | 483 | oggie rob <oz.robharvey@gmail.com> |
484 | 484 | oggy <ognjen.maric@gmail.com> |
485 | 485 | Tomek Paczkowski <tomek@hauru.eu> |
| 486 | Luan Pablo <luanpab@gmail.com> |
486 | 487 | Jens Page |
487 | 488 | Guillaume Pannatier <guillaume.pannatier@gmail.com> |
488 | 489 | Jay Parlar <parlar@gmail.com> |
diff --git a/django/contrib/sitemaps/__init__.py b/django/contrib/sitemaps/__init__.py
index 1100712..f4f73ee 100644
a
|
b
|
|
1 | 1 | from django.apps import apps as django_apps |
| 2 | from django.conf import settings |
2 | 3 | from django.core import urlresolvers, paginator |
3 | 4 | from django.core.exceptions import ImproperlyConfigured |
| 5 | from django.utils import translation |
4 | 6 | from django.utils.six.moves.urllib.parse import urlencode |
5 | 7 | from django.utils.six.moves.urllib.request import urlopen |
6 | 8 | |
… |
… |
class Sitemap(object):
|
86 | 88 | except Site.DoesNotExist: |
87 | 89 | pass |
88 | 90 | if site is None: |
89 | | raise ImproperlyConfigured("To use sitemaps, either enable the sites framework or pass a Site/RequestSite object in your view.") |
| 91 | raise ImproperlyConfigured( |
| 92 | "To use sitemaps, either enable the sites framework or " |
| 93 | "pass a Site/RequestSite object in your view." |
| 94 | ) |
90 | 95 | domain = site.domain |
91 | 96 | |
| 97 | if getattr(self, 'i18n', False): |
| 98 | urls = [] |
| 99 | current_lang_code = translation.get_language() |
| 100 | for lang_code, lang_name in settings.LANGUAGES: |
| 101 | translation.activate(lang_code) |
| 102 | urls += self._urls(page, protocol, domain) |
| 103 | translation.activate(current_lang_code) |
| 104 | else: |
| 105 | urls = self._urls(page, protocol, domain) |
| 106 | |
| 107 | return urls |
| 108 | |
| 109 | def _urls(self, page, protocol, domain): |
92 | 110 | urls = [] |
93 | 111 | latest_lastmod = None |
94 | 112 | all_items_lastmod = True # track if all items have a lastmod |
diff --git a/django/contrib/sitemaps/tests/base.py b/django/contrib/sitemaps/tests/base.py
index 2d0a7bf..54446b3 100644
a
|
b
|
|
1 | 1 | from django.apps import apps |
2 | 2 | from django.core.cache import cache |
| 3 | from django.core.urlresolvers import reverse |
3 | 4 | from django.db import models |
4 | 5 | from django.test import TestCase, override_settings |
5 | 6 | |
… |
… |
class TestModel(models.Model):
|
17 | 18 | return '/testmodel/%s/' % self.id |
18 | 19 | |
19 | 20 | |
| 21 | class I18nTestModel(models.Model): |
| 22 | name = models.CharField(max_length=100) |
| 23 | |
| 24 | class Meta: |
| 25 | app_label = 'sitemaps' |
| 26 | |
| 27 | def get_absolute_url(self): |
| 28 | return reverse('i18n_testmodel', args=[self.id]) |
| 29 | |
| 30 | |
20 | 31 | @override_settings(ROOT_URLCONF='django.contrib.sitemaps.tests.urls.http') |
21 | 32 | class SitemapTestsBase(TestCase): |
22 | 33 | protocol = 'http' |
… |
… |
class SitemapTestsBase(TestCase):
|
28 | 39 | cache.clear() |
29 | 40 | # Create an object for sitemap content. |
30 | 41 | TestModel.objects.create(name='Test Object') |
| 42 | I18nTestModel.objects.create(name='Test Object') |
diff --git a/django/contrib/sitemaps/tests/test_http.py b/django/contrib/sitemaps/tests/test_http.py
index 2f9ebd8..bce276d 100644
a
|
b
|
class HTTPSitemapTests(SitemapTestsBase):
|
171 | 171 | def test_empty_sitemap(self): |
172 | 172 | response = self.client.get('/empty/sitemap.xml') |
173 | 173 | self.assertEqual(response.status_code, 200) |
| 174 | |
| 175 | @override_settings(LANGUAGES=(('en', 'English'), ('pt', 'Portuguese'))) |
| 176 | def test_simple_i18nsitemap_index(self): |
| 177 | "A simple i18n sitemap index can be rendered" |
| 178 | response = self.client.get('/simple/i18n.xml') |
| 179 | expected_content = """<?xml version="1.0" encoding="UTF-8"?> |
| 180 | <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> |
| 181 | <url><loc>{0}/en/i18n/testmodel/1/</loc><changefreq>never</changefreq><priority>0.5</priority></url><url><loc>{0}/pt/i18n/testmodel/1/</loc><changefreq>never</changefreq><priority>0.5</priority></url> |
| 182 | </urlset> |
| 183 | """.format(self.base_url) |
| 184 | self.assertXMLEqual(response.content.decode('utf-8'), expected_content) |
diff --git a/django/contrib/sitemaps/tests/urls/http.py b/django/contrib/sitemaps/tests/urls/http.py
index 1ec292c..d7bc829 100644
a
|
b
|
|
1 | 1 | from datetime import datetime |
2 | 2 | from django.conf.urls import url |
| 3 | from django.conf.urls.i18n import i18n_patterns |
3 | 4 | from django.contrib.sitemaps import Sitemap, GenericSitemap, FlatPageSitemap, views |
| 5 | from django.http import HttpResponse |
4 | 6 | from django.views.decorators.cache import cache_page |
5 | 7 | |
6 | | from django.contrib.sitemaps.tests.base import TestModel |
| 8 | from django.contrib.sitemaps.tests.base import I18nTestModel, TestModel |
7 | 9 | |
8 | 10 | |
9 | 11 | class SimpleSitemap(Sitemap): |
… |
… |
class SimpleSitemap(Sitemap):
|
16 | 18 | return [object()] |
17 | 19 | |
18 | 20 | |
| 21 | class SimpleI18nSitemap(Sitemap): |
| 22 | changefreq = "never" |
| 23 | priority = 0.5 |
| 24 | i18n = True |
| 25 | |
| 26 | def items(self): |
| 27 | return I18nTestModel.objects.all() |
| 28 | |
| 29 | |
19 | 30 | class EmptySitemap(Sitemap): |
20 | 31 | changefreq = "never" |
21 | 32 | priority = 0.5 |
… |
… |
class FixedLastmodMixedSitemap(Sitemap):
|
42 | 53 | return [o1, o2] |
43 | 54 | |
44 | 55 | |
| 56 | def testmodelview(request, id): |
| 57 | return HttpResponse() |
| 58 | |
| 59 | |
45 | 60 | simple_sitemaps = { |
46 | 61 | 'simple': SimpleSitemap, |
47 | 62 | } |
48 | 63 | |
| 64 | simple_i18nsitemaps = { |
| 65 | 'simple': SimpleI18nSitemap, |
| 66 | } |
| 67 | |
49 | 68 | empty_sitemaps = { |
50 | 69 | 'empty': EmptySitemap, |
51 | 70 | } |
… |
… |
urlpatterns = [
|
74 | 93 | url(r'^simple/sitemap-(?P<section>.+)\.xml$', views.sitemap, |
75 | 94 | {'sitemaps': simple_sitemaps}), |
76 | 95 | url(r'^simple/sitemap\.xml$', views.sitemap, {'sitemaps': simple_sitemaps}), |
| 96 | url(r'^simple/i18n\.xml$', views.sitemap, {'sitemaps': simple_i18nsitemaps}), |
77 | 97 | url(r'^simple/custom-sitemap\.xml$', views.sitemap, |
78 | 98 | {'sitemaps': simple_sitemaps, 'template_name': 'custom_sitemap.xml'}), |
79 | 99 | url(r'^empty/sitemap\.xml$', views.sitemap, {'sitemaps': empty_sitemaps}), |
… |
… |
urlpatterns = [
|
86 | 106 | url(r'^cached/sitemap-(?P<section>.+)\.xml', cache_page(1)(views.sitemap), |
87 | 107 | {'sitemaps': simple_sitemaps}, name='cached_sitemap') |
88 | 108 | ] |
| 109 | |
| 110 | urlpatterns += i18n_patterns( |
| 111 | url(r'^i18n/testmodel/(?P<id>\d+)/$', testmodelview, name='i18n_testmodel'), |
| 112 | ) |
diff --git a/docs/ref/contrib/sitemaps.txt b/docs/ref/contrib/sitemaps.txt
index 12ed61b..955a325 100644
a
|
b
|
Sitemap class reference
|
231 | 231 | sitemap was requested is used. If the sitemap is built outside the |
232 | 232 | context of a request, the default is ``'http'``. |
233 | 233 | |
| 234 | .. attribute:: Sitemap.i18n |
| 235 | |
| 236 | **Optional.** |
| 237 | |
| 238 | A boolean attribute that defines if the URLs of this class are using i18n. |
| 239 | If ``True`` it will generate your sitemap based on all of your :setting:`LANGUAGES`, |
| 240 | the default is ``False``. |
| 241 | |
| 242 | .. versionadded:: 1.8 |
234 | 243 | |
235 | 244 | Shortcuts |
236 | 245 | ========= |
diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt
index f716c99..df150e0 100644
a
|
b
|
Minor features
|
78 | 78 | :mod:`django.contrib.sitemaps` |
79 | 79 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
80 | 80 | |
81 | | * ... |
| 81 | * Added :attr:`~django.contrib.sitemaps.Sitemap.i18n` class attribute to |
| 82 | :class:`django.contrib.Sitemap`. It is now possible to have all your multiple |
| 83 | language URLs in your sitemap. |
82 | 84 | |
83 | 85 | :mod:`django.contrib.sites` |
84 | 86 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ |