-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
/
page_resolver.py
113 lines (91 loc) · 3.42 KB
/
page_resolver.py
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
# -*- coding: utf-8 -*-
from cms.exceptions import NoHomeFound
from cms.models.pagemodel import Page
from django.conf import settings
from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse
from django.db.models.query_utils import Q
import urllib
import re
ADMIN_PAGE_RE_PATTERN = ur'cms/page/(\d+)'
ADMIN_PAGE_RE = re.compile(ADMIN_PAGE_RE_PATTERN)
def get_page_from_path(path, preview=False):
if 'django.contrib.admin' in settings.INSTALLED_APPS:
admin_base = reverse('admin:index').lstrip('/')
else:
admin_base = None
site = Site.objects.get_current()
# Check if this is called from an admin request
if admin_base and path.startswith(admin_base):
# if so, get the page ID to query the page
match = ADMIN_PAGE_RE.search(path)
if not match:
page = None
else:
try:
page = Page.objects.get(pk=match.group(1))
except Page.DoesNotExist:
page = None
return page
if not settings.CMS_MODERATOR or preview:
# We do not use moderator
pages = Page.objects.drafts()
else:
pages = Page.objects.public()
if not preview:
pages = pages.published()
pages = pages.filter(site=site)
# Check if there are any pages
if not pages.all_root():
return None
# get the home page (needed to get the page)
try:
home = pages.get_home()
except NoHomeFound:
home = None
# if there is no path (slashes stripped) and we found a home, this is the
# home page.
if not path and home:
page = home
return page
# title_set__path=path should be clear, get the pages where the path of the
# title object is equal to our path.
if settings.CMS_FLAT_URLS:
q = Q(title_set__slug=path)
else:
q = Q(title_set__path=path)
try:
page = pages.filter(q).distinct().get()
except Page.DoesNotExist:
return None
return page
def get_page_from_request(request, use_path=None):
"""
Gets the current page from a request object.
URLs can be of the following form (this should help understand the code):
http://server.whatever.com/<some_path>/"pages-root"/some/page/slug
<some_path>: This can be anything, and should be stripped when resolving
pages names. This means the CMS is not installed at the root of the
server's URLs.
"pages-root" This is the root of Django urls for the CMS. It is, in essence
an empty page slug (slug == '')
The page slug can then be resolved to a Page model object
"""
pages_root = urllib.unquote(reverse("pages-root"))
# The following is used by cms.middleware.page.CurrentPageMiddleware
if hasattr(request, '_current_page_cache'):
return request._current_page_cache
# TODO: Isn't there a permission check needed here?
preview = 'preview' in request.GET and request.user.is_staff
# If use_path is given, someone already did the path cleaning
if use_path:
path = use_path
else:
# otherwise strip off the non-cms part of the URL
path = request.path[len(pages_root):]
# and strip any final slash
if path.endswith("/"):
path = path[:-1]
page = get_page_from_path(path, preview)
request._current_page_cache = page
return page