forked from ungleich-public/dynamicweb
98 lines
3.6 KiB
Python
98 lines
3.6 KiB
Python
from django.conf import settings
|
|
from django.http import Http404, HttpResponseRedirect
|
|
from django.template.response import TemplateResponse
|
|
from django.urls import Resolver404, resolve, reverse
|
|
|
|
from cms import __version__, constants
|
|
from cms.cache.page import set_page_cache
|
|
from cms.models import EmptyPageContent
|
|
from cms.utils.page_permissions import user_can_change_page, user_can_view_page
|
|
from cms.utils.urlutils import admin_reverse
|
|
|
|
|
|
def render_page(request, page, current_language, slug=None):
|
|
"""
|
|
Renders a page
|
|
"""
|
|
page_content = page.page_content_cache.get(current_language, page.get_content_obj(current_language))
|
|
context = {}
|
|
context['lang'] = current_language
|
|
context['current_page'] = page
|
|
context['current_pagecontent'] = page_content
|
|
context['has_change_permissions'] = user_can_change_page(request.user, page)
|
|
context['has_view_permissions'] = user_can_view_page(request.user, page)
|
|
|
|
cant_view_page = any([
|
|
not context['has_view_permissions'],
|
|
isinstance(page_content, EmptyPageContent)
|
|
])
|
|
if cant_view_page:
|
|
return _handle_no_page(request)
|
|
|
|
template = page_content.get_template()
|
|
if not template:
|
|
# Render placeholder content with minimal markup
|
|
|
|
from cms.views import render_placeholder_content
|
|
return render_placeholder_content(request, page_content, context)
|
|
response = TemplateResponse(request, template, context)
|
|
response.add_post_render_callback(set_page_cache)
|
|
|
|
# Add headers for X Frame Options - this really should be changed upon moving to class based views
|
|
xframe_options = page.get_xframe_options()
|
|
# xframe_options can be None if there's no xframe information on the page
|
|
# (eg. a top-level page which has xframe options set to "inherit")
|
|
if xframe_options == constants.X_FRAME_OPTIONS_INHERIT or xframe_options is None:
|
|
# This is when we defer to django's own clickjacking handling
|
|
return response
|
|
|
|
# We want to prevent django setting this in their middleware
|
|
response.xframe_options_exempt = True
|
|
|
|
if xframe_options == constants.X_FRAME_OPTIONS_ALLOW:
|
|
# Do nothing, allowed is no header.
|
|
return response
|
|
elif xframe_options == constants.X_FRAME_OPTIONS_SAMEORIGIN:
|
|
response['X-Frame-Options'] = 'SAMEORIGIN'
|
|
elif xframe_options == constants.X_FRAME_OPTIONS_DENY:
|
|
response['X-Frame-Options'] = 'DENY'
|
|
return response
|
|
|
|
|
|
def _handle_no_page(request):
|
|
try:
|
|
match = resolve(request.path)
|
|
except Resolver404 as e:
|
|
raise Http404(dict(path=request.path, tried=e.args[0]['tried'])) from e
|
|
|
|
# redirect to PageContent's changelist if the root page is detected
|
|
if match.url_name == 'pages-root':
|
|
try:
|
|
redirect_url = admin_reverse('cms_pagecontent_changelist')
|
|
return HttpResponseRedirect(redirect_url)
|
|
except Resolver404:
|
|
pass
|
|
raise Http404(dict(path=request.path, tried=match.tried))
|
|
|
|
|
|
def _handle_no_apphook(request):
|
|
context = {
|
|
"absolute_url": request.toolbar.request_path,
|
|
}
|
|
return TemplateResponse(request, "cms/noapphook.html", context)
|
|
|
|
|
|
def _render_welcome_page(request):
|
|
context = {
|
|
'cms_version': __version__,
|
|
'django_debug': settings.DEBUG,
|
|
'next_url': reverse('pages-root'),
|
|
}
|
|
return TemplateResponse(request, "cms/welcome.html", context)
|
|
|
|
|
|
def render_pagecontent(request, pagecontent):
|
|
language = pagecontent.language
|
|
request.current_page = page = pagecontent.page
|
|
page.page_content_cache[language] = pagecontent
|
|
return render_page(request, page, language)
|