Fixed #8995 -- Added support for HTTPS in sitemaps.
Modularized tests and did a bit of cleanup while I was in the area. git-svn-id: http://code.djangoproject.com/svn/django/trunk@17409 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
123f567093
commit
a4b472dd80
|
@ -40,6 +40,10 @@ class Sitemap(object):
|
||||||
# http://sitemaps.org/protocol.php#index.
|
# http://sitemaps.org/protocol.php#index.
|
||||||
limit = 50000
|
limit = 50000
|
||||||
|
|
||||||
|
# If protocol is None, the URLs in the sitemap will use the protocol
|
||||||
|
# with which the sitemap was requested.
|
||||||
|
protocol = None
|
||||||
|
|
||||||
def __get(self, name, obj, default=None):
|
def __get(self, name, obj, default=None):
|
||||||
try:
|
try:
|
||||||
attr = getattr(self, name)
|
attr = getattr(self, name)
|
||||||
|
@ -61,7 +65,14 @@ class Sitemap(object):
|
||||||
return self._paginator
|
return self._paginator
|
||||||
paginator = property(_get_paginator)
|
paginator = property(_get_paginator)
|
||||||
|
|
||||||
def get_urls(self, page=1, site=None):
|
def get_urls(self, page=1, site=None, protocol=None):
|
||||||
|
# Determine protocol
|
||||||
|
if self.protocol is not None:
|
||||||
|
protocol = self.protocol
|
||||||
|
if protocol is None:
|
||||||
|
protocol = 'http'
|
||||||
|
|
||||||
|
# Determine domain
|
||||||
if site is None:
|
if site is None:
|
||||||
if Site._meta.installed:
|
if Site._meta.installed:
|
||||||
try:
|
try:
|
||||||
|
@ -69,11 +80,15 @@ class Sitemap(object):
|
||||||
except Site.DoesNotExist:
|
except Site.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
if site is None:
|
if site is None:
|
||||||
raise ImproperlyConfigured("In order to use Sitemaps you must either use the sites framework or pass in a Site or RequestSite object in your view code.")
|
raise ImproperlyConfigured("In order to use Sitemaps "
|
||||||
|
"you must either use the sites framework "
|
||||||
|
"or pass in a Site or RequestSite object "
|
||||||
|
"in your view code.")
|
||||||
|
domain = site.domain
|
||||||
|
|
||||||
urls = []
|
urls = []
|
||||||
for item in self.paginator.page(page).object_list:
|
for item in self.paginator.page(page).object_list:
|
||||||
loc = "http://%s%s" % (site.domain, self.__get('location', item))
|
loc = "%s://%s%s" % (protocol, domain, self.__get('location', item))
|
||||||
priority = self.__get('priority', item, None)
|
priority = self.__get('priority', item, None)
|
||||||
url_info = {
|
url_info = {
|
||||||
'item': item,
|
'item': item,
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
from django.contrib.sitemaps.tests.basic import *
|
from .flatpages import FlatpagesSitemapTests
|
||||||
|
from .generic import GenericViewsSitemapTests
|
||||||
|
from .http import HTTPSitemapTests
|
||||||
|
from .https import HTTPSSitemapTests, HTTPSDetectionSitemapTests
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.contrib.sites.models import Site
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
|
||||||
|
class SitemapTestsBase(TestCase):
|
||||||
|
protocol = 'http'
|
||||||
|
domain = 'example.com' if Site._meta.installed else 'testserver'
|
||||||
|
urls = 'django.contrib.sitemaps.tests.urls.http'
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.base_url = '%s://%s' % (self.protocol, self.domain)
|
||||||
|
self.old_USE_L10N = settings.USE_L10N
|
||||||
|
self.old_TEMPLATE_DIRS = settings.TEMPLATE_DIRS
|
||||||
|
settings.TEMPLATE_DIRS = (
|
||||||
|
os.path.join(os.path.dirname(__file__), 'templates'),
|
||||||
|
)
|
||||||
|
self.old_Site_meta_installed = Site._meta.installed
|
||||||
|
# Create a user that will double as sitemap content
|
||||||
|
User.objects.create_user('testuser', 'test@example.com', 's3krit')
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
settings.USE_L10N = self.old_USE_L10N
|
||||||
|
settings.TEMPLATE_DIRS = self.old_TEMPLATE_DIRS
|
||||||
|
Site._meta.installed = self.old_Site_meta_installed
|
|
@ -0,0 +1,37 @@
|
||||||
|
from django.conf import settings
|
||||||
|
from django.utils.unittest import skipUnless
|
||||||
|
|
||||||
|
from .base import SitemapTestsBase
|
||||||
|
|
||||||
|
class FlatpagesSitemapTests(SitemapTestsBase):
|
||||||
|
|
||||||
|
@skipUnless("django.contrib.flatpages" in settings.INSTALLED_APPS,
|
||||||
|
"django.contrib.flatpages app not installed.")
|
||||||
|
def test_flatpage_sitemap(self):
|
||||||
|
"Basic FlatPage sitemap test"
|
||||||
|
|
||||||
|
# Import FlatPage inside the test so that when django.contrib.flatpages
|
||||||
|
# is not installed we don't get problems trying to delete Site
|
||||||
|
# objects (FlatPage has an M2M to Site, Site.delete() tries to
|
||||||
|
# delete related objects, but the M2M table doesn't exist.
|
||||||
|
from django.contrib.flatpages.models import FlatPage
|
||||||
|
|
||||||
|
public = FlatPage.objects.create(
|
||||||
|
url=u'/public/',
|
||||||
|
title=u'Public Page',
|
||||||
|
enable_comments=True,
|
||||||
|
registration_required=False,
|
||||||
|
)
|
||||||
|
public.sites.add(settings.SITE_ID)
|
||||||
|
private = FlatPage.objects.create(
|
||||||
|
url=u'/private/',
|
||||||
|
title=u'Private Page',
|
||||||
|
enable_comments=True,
|
||||||
|
registration_required=True
|
||||||
|
)
|
||||||
|
private.sites.add(settings.SITE_ID)
|
||||||
|
response = self.client.get('/flatpages/sitemap.xml')
|
||||||
|
# Public flatpage should be in the sitemap
|
||||||
|
self.assertContains(response, '<loc>%s%s</loc>' % (self.base_url, public.url))
|
||||||
|
# Private flatpage should not be in the sitemap
|
||||||
|
self.assertNotContains(response, '<loc>%s%s</loc>' % (self.base_url, private.url))
|
|
@ -0,0 +1,17 @@
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
from .base import SitemapTestsBase
|
||||||
|
|
||||||
|
class GenericViewsSitemapTests(SitemapTestsBase):
|
||||||
|
|
||||||
|
def test_generic_sitemap(self):
|
||||||
|
"A minimal generic sitemap can be rendered"
|
||||||
|
response = self.client.get('/generic/sitemap.xml')
|
||||||
|
expected = ''
|
||||||
|
for username in User.objects.values_list("username", flat=True):
|
||||||
|
expected += "<url><loc>%s/users/%s/</loc></url>" % (self.base_url, username)
|
||||||
|
self.assertEqual(response.content, """<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
|
%s
|
||||||
|
</urlset>
|
||||||
|
""" % expected)
|
|
@ -1,39 +1,16 @@
|
||||||
import os
|
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.contrib.sitemaps import Sitemap, GenericSitemap
|
from django.contrib.sitemaps import Sitemap, GenericSitemap
|
||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.test import TestCase
|
|
||||||
from django.utils.unittest import skipUnless
|
from django.utils.unittest import skipUnless
|
||||||
from django.utils.formats import localize
|
from django.utils.formats import localize
|
||||||
from django.utils.translation import activate, deactivate
|
from django.utils.translation import activate, deactivate
|
||||||
|
|
||||||
|
from .base import SitemapTestsBase
|
||||||
|
|
||||||
class SitemapTests(TestCase):
|
class HTTPSitemapTests(SitemapTestsBase):
|
||||||
urls = 'django.contrib.sitemaps.tests.urls'
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
if Site._meta.installed:
|
|
||||||
self.base_url = 'http://example.com'
|
|
||||||
else:
|
|
||||||
self.base_url = 'http://testserver'
|
|
||||||
self.old_USE_L10N = settings.USE_L10N
|
|
||||||
self.old_Site_meta_installed = Site._meta.installed
|
|
||||||
self.old_TEMPLATE_DIRS = settings.TEMPLATE_DIRS
|
|
||||||
self.old_Site_meta_installed = Site._meta.installed
|
|
||||||
settings.TEMPLATE_DIRS = (
|
|
||||||
os.path.join(os.path.dirname(__file__), 'templates'),
|
|
||||||
)
|
|
||||||
# Create a user that will double as sitemap content
|
|
||||||
User.objects.create_user('testuser', 'test@example.com', 's3krit')
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
settings.USE_L10N = self.old_USE_L10N
|
|
||||||
Site._meta.installed = self.old_Site_meta_installed
|
|
||||||
settings.TEMPLATE_DIRS = self.old_TEMPLATE_DIRS
|
|
||||||
Site._meta.installed = self.old_Site_meta_installed
|
|
||||||
|
|
||||||
def test_simple_sitemap_index(self):
|
def test_simple_sitemap_index(self):
|
||||||
"A simple sitemap index can be rendered"
|
"A simple sitemap index can be rendered"
|
||||||
|
@ -54,6 +31,15 @@ class SitemapTests(TestCase):
|
||||||
</sitemapindex>
|
</sitemapindex>
|
||||||
""" % self.base_url)
|
""" % self.base_url)
|
||||||
|
|
||||||
|
def test_simple_sitemap_section(self):
|
||||||
|
"A simple sitemap section can be rendered"
|
||||||
|
response = self.client.get('/simple/sitemap-simple.xml')
|
||||||
|
self.assertEqual(response.content, """<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
|
<url><loc>%s/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url>
|
||||||
|
</urlset>
|
||||||
|
""" % (self.base_url, date.today()))
|
||||||
|
|
||||||
def test_simple_sitemap(self):
|
def test_simple_sitemap(self):
|
||||||
"A simple sitemap can be rendered"
|
"A simple sitemap can be rendered"
|
||||||
response = self.client.get('/simple/sitemap.xml')
|
response = self.client.get('/simple/sitemap.xml')
|
||||||
|
@ -88,48 +74,6 @@ class SitemapTests(TestCase):
|
||||||
self.assertContains(response, '<lastmod>%s</lastmod>' % date.today())
|
self.assertContains(response, '<lastmod>%s</lastmod>' % date.today())
|
||||||
deactivate()
|
deactivate()
|
||||||
|
|
||||||
def test_generic_sitemap(self):
|
|
||||||
"A minimal generic sitemap can be rendered"
|
|
||||||
response = self.client.get('/generic/sitemap.xml')
|
|
||||||
expected = ''
|
|
||||||
for username in User.objects.values_list("username", flat=True):
|
|
||||||
expected += "<url><loc>%s/users/%s/</loc></url>" % (self.base_url, username)
|
|
||||||
self.assertEqual(response.content, """<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
||||||
%s
|
|
||||||
</urlset>
|
|
||||||
""" % expected)
|
|
||||||
|
|
||||||
@skipUnless("django.contrib.flatpages" in settings.INSTALLED_APPS, "django.contrib.flatpages app not installed.")
|
|
||||||
def test_flatpage_sitemap(self):
|
|
||||||
"Basic FlatPage sitemap test"
|
|
||||||
|
|
||||||
# Import FlatPage inside the test so that when django.contrib.flatpages
|
|
||||||
# is not installed we don't get problems trying to delete Site
|
|
||||||
# objects (FlatPage has an M2M to Site, Site.delete() tries to
|
|
||||||
# delete related objects, but the M2M table doesn't exist.
|
|
||||||
from django.contrib.flatpages.models import FlatPage
|
|
||||||
|
|
||||||
public = FlatPage.objects.create(
|
|
||||||
url=u'/public/',
|
|
||||||
title=u'Public Page',
|
|
||||||
enable_comments=True,
|
|
||||||
registration_required=False,
|
|
||||||
)
|
|
||||||
public.sites.add(settings.SITE_ID)
|
|
||||||
private = FlatPage.objects.create(
|
|
||||||
url=u'/private/',
|
|
||||||
title=u'Private Page',
|
|
||||||
enable_comments=True,
|
|
||||||
registration_required=True
|
|
||||||
)
|
|
||||||
private.sites.add(settings.SITE_ID)
|
|
||||||
response = self.client.get('/flatpages/sitemap.xml')
|
|
||||||
# Public flatpage should be in the sitemap
|
|
||||||
self.assertContains(response, '<loc>%s%s</loc>' % (self.base_url, public.url))
|
|
||||||
# Private flatpage should not be in the sitemap
|
|
||||||
self.assertNotContains(response, '<loc>%s%s</loc>' % (self.base_url, private.url))
|
|
||||||
|
|
||||||
def test_requestsite_sitemap(self):
|
def test_requestsite_sitemap(self):
|
||||||
# Make sure hitting the flatpages sitemap without the sites framework
|
# Make sure hitting the flatpages sitemap without the sites framework
|
||||||
# installed doesn't raise an exception
|
# installed doesn't raise an exception
|
||||||
|
@ -141,7 +85,8 @@ class SitemapTests(TestCase):
|
||||||
</urlset>
|
</urlset>
|
||||||
""" % date.today())
|
""" % date.today())
|
||||||
|
|
||||||
@skipUnless("django.contrib.sites" in settings.INSTALLED_APPS, "django.contrib.sites app not installed.")
|
@skipUnless("django.contrib.sites" in settings.INSTALLED_APPS,
|
||||||
|
"django.contrib.sites app not installed.")
|
||||||
def test_sitemap_get_urls_no_site_1(self):
|
def test_sitemap_get_urls_no_site_1(self):
|
||||||
"""
|
"""
|
||||||
Check we get ImproperlyConfigured if we don't pass a site object to
|
Check we get ImproperlyConfigured if we don't pass a site object to
|
|
@ -0,0 +1,51 @@
|
||||||
|
from datetime import date
|
||||||
|
|
||||||
|
from django.test.utils import override_settings
|
||||||
|
|
||||||
|
from .base import SitemapTestsBase
|
||||||
|
|
||||||
|
class HTTPSSitemapTests(SitemapTestsBase):
|
||||||
|
protocol = 'https'
|
||||||
|
urls = 'django.contrib.sitemaps.tests.urls.https'
|
||||||
|
|
||||||
|
def test_secure_sitemap_index(self):
|
||||||
|
"A secure sitemap index can be rendered"
|
||||||
|
response = self.client.get('/secure/index.xml')
|
||||||
|
self.assertEqual(response.content, """<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
|
<sitemap><loc>%s/secure/sitemap-simple.xml</loc></sitemap>
|
||||||
|
</sitemapindex>
|
||||||
|
""" % self.base_url)
|
||||||
|
|
||||||
|
def test_secure_sitemap_section(self):
|
||||||
|
"A secure sitemap section can be rendered"
|
||||||
|
response = self.client.get('/secure/sitemap-simple.xml')
|
||||||
|
self.assertEqual(response.content, """<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
|
<url><loc>%s/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url>
|
||||||
|
</urlset>
|
||||||
|
""" % (self.base_url, date.today()))
|
||||||
|
|
||||||
|
#@override_settings(SECURE_PROXY_SSL_HEADER=False)
|
||||||
|
class HTTPSDetectionSitemapTests(SitemapTestsBase):
|
||||||
|
extra = {'wsgi.url_scheme': 'https'}
|
||||||
|
|
||||||
|
def test_sitemap_index_with_https_request(self):
|
||||||
|
"A sitemap index requested in HTTPS is rendered with HTTPS links"
|
||||||
|
response = self.client.get('/simple/index.xml', **self.extra)
|
||||||
|
self.assertEqual(response.content, """<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
|
<sitemap><loc>%s/simple/sitemap-simple.xml</loc></sitemap>
|
||||||
|
</sitemapindex>
|
||||||
|
""" % self.base_url.replace('http://', 'https://'))
|
||||||
|
|
||||||
|
def test_sitemap_section_with_https_request(self):
|
||||||
|
"A sitemap section requested in HTTPS is rendered with HTTPS links"
|
||||||
|
response = self.client.get('/simple/sitemap-simple.xml', **self.extra)
|
||||||
|
self.assertEqual(response.content, """<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
|
<url><loc>%s/location/</loc><lastmod>%s</lastmod><changefreq>never</changefreq><priority>0.5</priority></url>
|
||||||
|
</urlset>
|
||||||
|
""" % (self.base_url.replace('http://', 'https://'), date.today()))
|
||||||
|
|
||||||
|
HTTPSDetectionSitemapTests = override_settings(SECURE_PROXY_SSL_HEADER=False)(HTTPSDetectionSitemapTests)
|
|
@ -18,9 +18,7 @@ simple_sitemaps = {
|
||||||
}
|
}
|
||||||
|
|
||||||
generic_sitemaps = {
|
generic_sitemaps = {
|
||||||
'generic': GenericSitemap({
|
'generic': GenericSitemap({'queryset': User.objects.all()}),
|
||||||
'queryset': User.objects.all()
|
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
flatpage_sitemaps = {
|
flatpage_sitemaps = {
|
|
@ -0,0 +1,16 @@
|
||||||
|
from django.conf.urls import patterns
|
||||||
|
|
||||||
|
from .http import SimpleSitemap
|
||||||
|
|
||||||
|
class HTTPSSitemap(SimpleSitemap):
|
||||||
|
protocol = 'https'
|
||||||
|
|
||||||
|
secure_sitemaps = {
|
||||||
|
'simple': HTTPSSitemap,
|
||||||
|
}
|
||||||
|
|
||||||
|
urlpatterns = patterns('django.contrib.sitemaps.views',
|
||||||
|
(r'^secure/index\.xml$', 'index', {'sitemaps': secure_sitemaps}),
|
||||||
|
(r'^secure/sitemap-(?P<section>.+)\.xml$', 'sitemap',
|
||||||
|
{'sitemaps': secure_sitemaps}),
|
||||||
|
)
|
|
@ -7,40 +7,47 @@ from django.template.response import TemplateResponse
|
||||||
def index(request, sitemaps,
|
def index(request, sitemaps,
|
||||||
template_name='sitemap_index.xml', mimetype='application/xml',
|
template_name='sitemap_index.xml', mimetype='application/xml',
|
||||||
sitemap_url_name='django.contrib.sitemaps.views.sitemap'):
|
sitemap_url_name='django.contrib.sitemaps.views.sitemap'):
|
||||||
current_site = get_current_site(request)
|
req_protocol = 'https' if request.is_secure() else 'http'
|
||||||
|
req_site = get_current_site(request)
|
||||||
|
|
||||||
sites = []
|
sites = []
|
||||||
protocol = request.is_secure() and 'https' or 'http'
|
|
||||||
for section, site in sitemaps.items():
|
for section, site in sitemaps.items():
|
||||||
site.request = request
|
|
||||||
if callable(site):
|
if callable(site):
|
||||||
pages = site().paginator.num_pages
|
site = site()
|
||||||
else:
|
protocol = req_protocol if site.protocol is None else site.protocol
|
||||||
pages = site.paginator.num_pages
|
sitemap_url = urlresolvers.reverse(
|
||||||
sitemap_url = urlresolvers.reverse(sitemap_url_name, kwargs={'section': section})
|
sitemap_url_name, kwargs={'section': section})
|
||||||
sites.append('%s://%s%s' % (protocol, current_site.domain, sitemap_url))
|
absolute_url = '%s://%s%s' % (protocol, req_site.domain, sitemap_url)
|
||||||
if pages > 1:
|
sites.append(absolute_url)
|
||||||
for page in range(2, pages+1):
|
for page in range(2, site.paginator.num_pages + 1):
|
||||||
sites.append('%s://%s%s?p=%s' % (protocol, current_site.domain, sitemap_url, page))
|
sites.append('%s?p=%s' % (absolute_url, page))
|
||||||
return TemplateResponse(request, template_name, {'sitemaps': sites}, content_type=mimetype)
|
|
||||||
|
return TemplateResponse(request, template_name, {'sitemaps': sites},
|
||||||
|
content_type=mimetype)
|
||||||
|
|
||||||
def sitemap(request, sitemaps, section=None,
|
def sitemap(request, sitemaps, section=None,
|
||||||
template_name='sitemap.xml', mimetype='application/xml'):
|
template_name='sitemap.xml', mimetype='application/xml'):
|
||||||
maps, urls = [], []
|
req_protocol = 'https' if request.is_secure() else 'http'
|
||||||
|
req_site = get_current_site(request)
|
||||||
|
|
||||||
if section is not None:
|
if section is not None:
|
||||||
if section not in sitemaps:
|
if section not in sitemaps:
|
||||||
raise Http404("No sitemap available for section: %r" % section)
|
raise Http404("No sitemap available for section: %r" % section)
|
||||||
maps.append(sitemaps[section])
|
maps = [sitemaps[section]]
|
||||||
else:
|
else:
|
||||||
maps = sitemaps.values()
|
maps = sitemaps.values()
|
||||||
page = request.GET.get("p", 1)
|
page = request.GET.get("p", 1)
|
||||||
current_site = get_current_site(request)
|
|
||||||
|
urls = []
|
||||||
for site in maps:
|
for site in maps:
|
||||||
try:
|
try:
|
||||||
if callable(site):
|
if callable(site):
|
||||||
site = site()
|
site = site()
|
||||||
urls.extend(site.get_urls(page=page, site=current_site))
|
urls.extend(site.get_urls(page=page, site=req_site,
|
||||||
|
protocol=req_protocol))
|
||||||
except EmptyPage:
|
except EmptyPage:
|
||||||
raise Http404("Page %s empty" % page)
|
raise Http404("Page %s empty" % page)
|
||||||
except PageNotAnInteger:
|
except PageNotAnInteger:
|
||||||
raise Http404("No page '%s'" % page)
|
raise Http404("No page '%s'" % page)
|
||||||
return TemplateResponse(request, template_name, {'urlset': urls}, content_type=mimetype)
|
return TemplateResponse(request, template_name, {'urlset': urls},
|
||||||
|
content_type=mimetype)
|
||||||
|
|
|
@ -161,6 +161,9 @@ Sitemap class reference
|
||||||
the ``get_absolute_url()`` method on each object as returned by
|
the ``get_absolute_url()`` method on each object as returned by
|
||||||
:attr:`~Sitemap.items()`.
|
:attr:`~Sitemap.items()`.
|
||||||
|
|
||||||
|
To specify a protocol other than ``'http'``, use
|
||||||
|
:attr:`~Sitemap.protocol`.
|
||||||
|
|
||||||
.. attribute:: Sitemap.lastmod
|
.. attribute:: Sitemap.lastmod
|
||||||
|
|
||||||
**Optional.** Either a method or attribute.
|
**Optional.** Either a method or attribute.
|
||||||
|
@ -193,7 +196,7 @@ Sitemap class reference
|
||||||
* ``'yearly'``
|
* ``'yearly'``
|
||||||
* ``'never'``
|
* ``'never'``
|
||||||
|
|
||||||
.. method:: Sitemap.priority
|
.. attribute:: Sitemap.priority
|
||||||
|
|
||||||
**Optional.** Either a method or attribute.
|
**Optional.** Either a method or attribute.
|
||||||
|
|
||||||
|
@ -208,6 +211,18 @@ Sitemap class reference
|
||||||
|
|
||||||
.. _sitemaps.org documentation: http://www.sitemaps.org/protocol.html#prioritydef
|
.. _sitemaps.org documentation: http://www.sitemaps.org/protocol.html#prioritydef
|
||||||
|
|
||||||
|
.. attribute:: Sitemap.protocol
|
||||||
|
|
||||||
|
.. versionadded:: 1.4
|
||||||
|
|
||||||
|
**Optional.**
|
||||||
|
|
||||||
|
This attribute defines the protocol (``'http'`` or ``'https'``) of the
|
||||||
|
URLs in the sitemap. If it isn't set, the protocol with which the
|
||||||
|
sitemap was requested is used. If the sitemap is built outside the
|
||||||
|
context of a request, the default is ``'http'``.
|
||||||
|
|
||||||
|
|
||||||
Shortcuts
|
Shortcuts
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
|
|
@ -562,6 +562,10 @@ Django 1.4 also includes several smaller improvements worth noting:
|
||||||
just like with regular formsets. However, initial values only apply to extra
|
just like with regular formsets. However, initial values only apply to extra
|
||||||
forms i.e. those which are not bound to an existing model instance.
|
forms i.e. those which are not bound to an existing model instance.
|
||||||
|
|
||||||
|
* The sitemaps framework can now handle HTTPS links using the new
|
||||||
|
:attr:`Sitemap.protocol <django.contrib.sitemaps.Sitemap.protocol>` class
|
||||||
|
attribute.
|
||||||
|
|
||||||
Backwards incompatible changes in 1.4
|
Backwards incompatible changes in 1.4
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue