Fixed #22782 -- Added i18n attr to Sitemap class

It makes possible to have your sitemap in multiple languages when
using i18n in URLs.
This commit is contained in:
Luan Pablo 2014-06-06 15:47:15 -03:00 committed by Tim Graham
parent 78c32f1caa
commit 407d070329
7 changed files with 75 additions and 2 deletions

View File

@ -484,6 +484,7 @@ answer newbie questions, and generally made Django that much better:
Christian Oudard <christian.oudard@gmail.com>
oggie rob <oz.robharvey@gmail.com>
oggy <ognjen.maric@gmail.com>
Luan Pablo <luanpab@gmail.com>
Tomek Paczkowski <tomek@hauru.eu>
Jens Page
Guillaume Pannatier <guillaume.pannatier@gmail.com>

View File

@ -1,6 +1,8 @@
from django.apps import apps as django_apps
from django.conf import settings
from django.core import urlresolvers, paginator
from django.core.exceptions import ImproperlyConfigured
from django.utils import translation
from django.utils.six.moves.urllib.parse import urlencode
from django.utils.six.moves.urllib.request import urlopen
@ -89,6 +91,19 @@ class Sitemap(object):
raise ImproperlyConfigured("To use sitemaps, either enable the sites framework or pass a Site/RequestSite object in your view.")
domain = site.domain
if getattr(self, 'i18n', False):
urls = []
current_lang_code = translation.get_language()
for lang_code, lang_name in settings.LANGUAGES:
translation.activate(lang_code)
urls += self._urls(page, protocol, domain)
translation.activate(current_lang_code)
else:
urls = self._urls(page, protocol, domain)
return urls
def _urls(self, page, protocol, domain):
urls = []
latest_lastmod = None
all_items_lastmod = True # track if all items have a lastmod

View File

@ -1,5 +1,6 @@
from django.apps import apps
from django.core.cache import cache
from django.core.urlresolvers import reverse
from django.db import models
from django.test import TestCase, override_settings
@ -17,6 +18,16 @@ class TestModel(models.Model):
return '/testmodel/%s/' % self.id
class I18nTestModel(models.Model):
name = models.CharField(max_length=100)
class Meta:
app_label = 'sitemaps'
def get_absolute_url(self):
return reverse('i18n_testmodel', args=[self.id])
@override_settings(ROOT_URLCONF='django.contrib.sitemaps.tests.urls.http')
class SitemapTestsBase(TestCase):
protocol = 'http'
@ -28,3 +39,4 @@ class SitemapTestsBase(TestCase):
cache.clear()
# Create an object for sitemap content.
TestModel.objects.create(name='Test Object')
I18nTestModel.objects.create(name='Test Object')

View File

@ -171,3 +171,14 @@ class HTTPSitemapTests(SitemapTestsBase):
def test_empty_sitemap(self):
response = self.client.get('/empty/sitemap.xml')
self.assertEqual(response.status_code, 200)
@override_settings(LANGUAGES=(('en', 'English'), ('pt', 'Portuguese')))
def test_simple_i18nsitemap_index(self):
"A simple i18n sitemap index can be rendered"
response = self.client.get('/simple/i18n.xml')
expected_content = """<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<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>
</urlset>
""".format(self.base_url)
self.assertXMLEqual(response.content.decode('utf-8'), expected_content)

View File

@ -1,9 +1,11 @@
from datetime import datetime
from django.conf.urls import url
from django.conf.urls.i18n import i18n_patterns
from django.contrib.sitemaps import Sitemap, GenericSitemap, FlatPageSitemap, views
from django.http import HttpResponse
from django.views.decorators.cache import cache_page
from django.contrib.sitemaps.tests.base import TestModel
from django.contrib.sitemaps.tests.base import I18nTestModel, TestModel
class SimpleSitemap(Sitemap):
@ -16,6 +18,15 @@ class SimpleSitemap(Sitemap):
return [object()]
class SimpleI18nSitemap(Sitemap):
changefreq = "never"
priority = 0.5
i18n = True
def items(self):
return I18nTestModel.objects.all()
class EmptySitemap(Sitemap):
changefreq = "never"
priority = 0.5
@ -42,10 +53,18 @@ class FixedLastmodMixedSitemap(Sitemap):
return [o1, o2]
def testmodelview(request, id):
return HttpResponse()
simple_sitemaps = {
'simple': SimpleSitemap,
}
simple_i18nsitemaps = {
'simple': SimpleI18nSitemap,
}
empty_sitemaps = {
'empty': EmptySitemap,
}
@ -74,6 +93,7 @@ urlpatterns = [
url(r'^simple/sitemap-(?P<section>.+)\.xml$', views.sitemap,
{'sitemaps': simple_sitemaps}, name='django.contrib.sitemaps.views.sitemap'),
url(r'^simple/sitemap\.xml$', views.sitemap, {'sitemaps': simple_sitemaps}),
url(r'^simple/i18n\.xml$', views.sitemap, {'sitemaps': simple_i18nsitemaps}),
url(r'^simple/custom-sitemap\.xml$', views.sitemap,
{'sitemaps': simple_sitemaps, 'template_name': 'custom_sitemap.xml'}),
url(r'^empty/sitemap\.xml$', views.sitemap, {'sitemaps': empty_sitemaps}),
@ -86,3 +106,7 @@ urlpatterns = [
url(r'^cached/sitemap-(?P<section>.+)\.xml', cache_page(1)(views.sitemap),
{'sitemaps': simple_sitemaps}, name='cached_sitemap')
]
urlpatterns += i18n_patterns(
url(r'^i18n/testmodel/(?P<id>\d+)/$', testmodelview, name='i18n_testmodel'),
)

View File

@ -232,6 +232,15 @@ Sitemap class reference
sitemap was requested is used. If the sitemap is built outside the
context of a request, the default is ``'http'``.
.. attribute:: Sitemap.i18n
.. versionadded:: 1.8
**Optional.**
A boolean attribute that defines if the URLs of this sitemap should
be generated using all of your :setting:`LANGUAGES`. The default is
``False``.
Shortcuts
=========

View File

@ -83,7 +83,8 @@ Minor features
:mod:`django.contrib.sitemaps`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* ...
* The new :attr:`Sitemap.i18n <django.contrib.sitemaps.Sitemap.i18n>` attribute
allows you to generate a sitemap based on the :setting:`LANGUAGES` setting.
:mod:`django.contrib.sites`
^^^^^^^^^^^^^^^^^^^^^^^^^^^