kopia lustrzana https://github.com/wagtail/wagtail
217 wiersze
6.7 KiB
Python
217 wiersze
6.7 KiB
Python
from django import template
|
|
from django.shortcuts import resolve_url
|
|
from django.template.defaulttags import token_kwargs
|
|
from django.template.loader import render_to_string
|
|
from django.utils.encoding import force_str
|
|
from django.utils.functional import Promise
|
|
from django.utils.html import conditional_escape
|
|
|
|
from wagtail import VERSION, __version__
|
|
from wagtail.models import Page, Site
|
|
from wagtail.rich_text import RichText, expand_db_html
|
|
from wagtail.utils.version import get_main_version
|
|
|
|
register = template.Library()
|
|
|
|
|
|
@register.simple_tag(takes_context=True)
|
|
def pageurl(context, page, fallback=None):
|
|
"""
|
|
Outputs a page's URL as relative (/foo/bar/) if it's within the same site as the
|
|
current page, or absolute (http://example.com/foo/bar/) if not.
|
|
If kwargs contains a fallback view name and page is None, the fallback view url will be returned.
|
|
"""
|
|
if page is None and fallback:
|
|
return resolve_url(fallback)
|
|
|
|
if not isinstance(page, Page):
|
|
raise ValueError("pageurl tag expected a Page object, got %r" % page)
|
|
|
|
return page.get_url(request=context.get("request"))
|
|
|
|
|
|
@register.simple_tag(takes_context=True)
|
|
def fullpageurl(context, page, fallback=None):
|
|
"""
|
|
Outputs a page's absolute URL (http://example.com/foo/bar/)
|
|
If kwargs contains a fallback view name and page is None, the fallback view url will be returned.
|
|
"""
|
|
if page is None and fallback:
|
|
fallback_url = resolve_url(fallback)
|
|
if fallback_url and "request" in context and fallback_url[0] == "/":
|
|
fallback_url = context["request"].build_absolute_uri(fallback_url)
|
|
return fallback_url
|
|
|
|
if not isinstance(page, Page):
|
|
raise ValueError("fullpageurl tag expected a Page object, got %r" % page)
|
|
|
|
return page.get_full_url(request=context.get("request"))
|
|
|
|
|
|
@register.simple_tag(takes_context=True)
|
|
def slugurl(context, slug):
|
|
"""
|
|
Returns the URL for the page that has the given slug.
|
|
|
|
First tries to find a page on the current site. If that fails or a request
|
|
is not available in the context, then returns the URL for the first page
|
|
that matches the slug on any site.
|
|
"""
|
|
|
|
page = None
|
|
try:
|
|
site = Site.find_for_request(context["request"])
|
|
current_site = site
|
|
except KeyError:
|
|
# No site object found - allow the fallback below to take place.
|
|
pass
|
|
else:
|
|
if current_site is not None:
|
|
page = Page.objects.in_site(current_site).filter(slug=slug).first()
|
|
|
|
# If no page is found, fall back to searching the whole tree.
|
|
if page is None:
|
|
page = Page.objects.filter(slug=slug).first()
|
|
|
|
if page:
|
|
# call pageurl() instead of page.relative_url() here so we get the ``accepts_kwarg`` logic
|
|
return pageurl(context, page)
|
|
|
|
|
|
@register.simple_tag
|
|
def wagtail_version():
|
|
return __version__
|
|
|
|
|
|
@register.simple_tag
|
|
def wagtail_documentation_path():
|
|
major, minor, patch, release, num = VERSION
|
|
if release == "final":
|
|
return "https://docs.wagtail.org/en/v%s" % __version__
|
|
else:
|
|
return "https://docs.wagtail.org/en/latest"
|
|
|
|
|
|
@register.simple_tag
|
|
def wagtail_release_notes_path():
|
|
return "%s.html" % get_main_version(VERSION)
|
|
|
|
|
|
@register.simple_tag
|
|
def wagtail_feature_release_whats_new_link():
|
|
major, minor, patch, release, num = VERSION
|
|
if release == "final":
|
|
return f"https://guide.wagtail.org/en-{major}.{minor}.x/releases/new-in-wagtail-{major}-{minor}/"
|
|
return "https://guide.wagtail.org/en-latest/releases/latest/"
|
|
|
|
|
|
@register.simple_tag
|
|
def wagtail_feature_release_editor_guide_link():
|
|
major, minor, patch, release, num = VERSION
|
|
if release == "final":
|
|
return f"https://guide.wagtail.org/en-{major}.{minor}.x/"
|
|
return "https://guide.wagtail.org/"
|
|
|
|
|
|
@register.filter
|
|
def richtext(value):
|
|
if isinstance(value, RichText):
|
|
# passing a RichText value through the |richtext filter should have no effect
|
|
return value
|
|
elif value is None:
|
|
html = ""
|
|
else:
|
|
if isinstance(value, Promise):
|
|
value = str(value)
|
|
if isinstance(value, str):
|
|
html = expand_db_html(value)
|
|
else:
|
|
raise TypeError(
|
|
"'richtext' template filter received an invalid value; expected string, got {}.".format(
|
|
type(value)
|
|
)
|
|
)
|
|
return render_to_string("wagtailcore/shared/richtext.html", {"html": html})
|
|
|
|
|
|
class IncludeBlockNode(template.Node):
|
|
def __init__(self, block_var, extra_context, use_parent_context):
|
|
self.block_var = block_var
|
|
self.extra_context = extra_context
|
|
self.use_parent_context = use_parent_context
|
|
|
|
def render(self, context):
|
|
try:
|
|
value = self.block_var.resolve(context)
|
|
except template.VariableDoesNotExist:
|
|
return ""
|
|
|
|
if hasattr(value, "render_as_block"):
|
|
if self.use_parent_context:
|
|
new_context = context.flatten()
|
|
else:
|
|
new_context = {}
|
|
|
|
if self.extra_context:
|
|
for var_name, var_value in self.extra_context.items():
|
|
new_context[var_name] = var_value.resolve(context)
|
|
|
|
output = value.render_as_block(context=new_context)
|
|
else:
|
|
output = value
|
|
|
|
if context.autoescape:
|
|
return conditional_escape(output)
|
|
else:
|
|
return force_str(output)
|
|
|
|
|
|
@register.tag
|
|
def include_block(parser, token):
|
|
"""
|
|
Render the passed item of StreamField content, passing the current template context
|
|
if there's an identifiable way of doing so (i.e. if it has a `render_as_block` method).
|
|
"""
|
|
tokens = token.split_contents()
|
|
|
|
try:
|
|
tag_name = tokens.pop(0)
|
|
block_var_token = tokens.pop(0)
|
|
except IndexError:
|
|
raise template.TemplateSyntaxError(
|
|
"%r tag requires at least one argument" % tag_name
|
|
)
|
|
|
|
block_var = parser.compile_filter(block_var_token)
|
|
|
|
if tokens and tokens[0] == "with":
|
|
tokens.pop(0)
|
|
extra_context = token_kwargs(tokens, parser)
|
|
else:
|
|
extra_context = None
|
|
|
|
use_parent_context = True
|
|
if tokens and tokens[0] == "only":
|
|
tokens.pop(0)
|
|
use_parent_context = False
|
|
|
|
if tokens:
|
|
raise template.TemplateSyntaxError(
|
|
f"Unexpected argument to {tag_name!r} tag: {tokens[0]!r}"
|
|
)
|
|
|
|
return IncludeBlockNode(block_var, extra_context, use_parent_context)
|
|
|
|
|
|
@register.simple_tag(takes_context=True)
|
|
def wagtail_site(context):
|
|
"""
|
|
Returns the Site object for the given request
|
|
"""
|
|
try:
|
|
request = context["request"]
|
|
except KeyError:
|
|
return None
|
|
|
|
return Site.find_for_request(request=request)
|