-
Notifications
You must be signed in to change notification settings - Fork 238
Expand file tree
/
Copy pathsitemap.py
More file actions
129 lines (109 loc) · 4.7 KB
/
sitemap.py
File metadata and controls
129 lines (109 loc) · 4.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# ------------------------------------------------------------------------
# ------------------------------------------------------------------------
from django.apps import apps
from django.contrib.sitemaps import Sitemap
from django.db.models import Max
from feincms import settings
# ------------------------------------------------------------------------
class PageSitemap(Sitemap):
"""
The PageSitemap can be used to automatically generate sitemap.xml files
for submission to index engines. See http://www.sitemaps.org/ for details.
"""
def __init__(
self,
navigation_only=False,
max_depth=0,
changefreq=None,
queryset=None,
filter=None,
extended_navigation=False,
page_model=settings.FEINCMS_DEFAULT_PAGE_MODEL,
*args,
**kwargs,
):
"""
The PageSitemap accepts the following parameters for customisation
of the resulting sitemap.xml output:
* navigation_only -- if set to True, only pages that are in_navigation
will appear in the site map.
* max_depth -- if set to a non-negative integer, will limit the sitemap
generated to this page hierarchy depth.
* changefreq -- should be a string or callable specifying the page
update frequency, according to the sitemap protocol.
* queryset -- pass in a query set to restrict the Pages to include
in the site map.
* filter -- pass in a callable that transforms a queryset to filter
out the pages you want to include in the site map.
* extended_navigation -- if set to True, adds pages from any navigation
extensions. If using PagePretender, make sure to include title, url,
level, in_navigation and optionally modification_date.
"""
super().__init__(*args, **kwargs)
self.depth_cutoff = max_depth
self.navigation_only = navigation_only
self.changefreq = changefreq
self.filter = filter
self.extended_navigation = extended_navigation
if queryset is not None:
self.queryset = queryset
else:
Page = apps.get_model(*page_model.split("."))
self.queryset = Page.objects.active()
def items(self):
"""
Consider all pages that are active and that are not a redirect
"""
base_qs = self.queryset
if callable(base_qs):
base_qs = base_qs()
self.max_depth = base_qs.aggregate(Max("level"))["level__max"] or 0
if self.depth_cutoff > 0:
self.max_depth = min(self.depth_cutoff, self.max_depth)
qs = base_qs.filter(redirect_to="")
if self.filter:
qs = self.filter(qs)
if self.navigation_only:
qs = qs.filter(in_navigation=True)
if self.depth_cutoff > 0:
qs = qs.filter(level__lte=self.max_depth - 1)
pages = [p for p in qs if p.is_active()]
if self.extended_navigation:
for idx, page in enumerate(pages):
if self.depth_cutoff > 0 and page.level == self.max_depth:
continue
if getattr(page, "navigation_extension", None):
cnt = 0
for p in page.extended_navigation():
depth_too_deep = (
self.depth_cutoff > 0 and p.level > self.depth_cutoff
)
not_in_nav = self.navigation_only and not p.in_navigation
if depth_too_deep or not_in_nav:
continue
cnt += 1
pages.insert(idx + cnt, p)
if p.level > self.max_depth:
self.max_depth = p.level
self.per_level = 1.0 / (self.max_depth + 1.0)
return pages
def lastmod(self, obj):
return getattr(obj, "modification_date", None)
# the priority is computed of the depth in the tree of a page
# may we should make an extension to give control to the user for priority
def priority(self, obj):
"""
The priority is staggered according to the depth of the page in
the site. Top level get highest priority, then each level is decreased
by per_level.
"""
if getattr(obj, "override_url", "") == "/":
prio = 1.0
else:
prio = 1.0 - (obj.level + 1) * self.per_level
# If the page is in_navigation, then it's more important, so boost
# its importance
if obj.in_navigation:
prio += 1.2 * self.per_level
return "%0.2g" % min(1.0, prio)
# ------------------------------------------------------------------------