mirror of
https://github.com/wagtail/wagtail.git
synced 2024-11-24 10:58:52 +01:00
Merge pull request #336 from kaedroho/feature/template-tags-rationalisation
Template tags rationalisation
This commit is contained in:
commit
6e6b85d4f6
@ -91,6 +91,9 @@ In addition to Django's standard tags and filters, Wagtail provides some of its
|
||||
Images (tag)
|
||||
~~~~~~~~~~~~
|
||||
|
||||
.. versionchanged:: 0.4
|
||||
The 'image_tags' tags library was renamed to 'wagtailimages_tags'
|
||||
|
||||
The ``image`` tag inserts an XHTML-compatible ``img`` element into the page, setting its ``src``, ``width``, ``height`` and ``alt``. See also :ref:`image_tag_alt`.
|
||||
|
||||
The syntax for the tag is thus::
|
||||
@ -101,7 +104,7 @@ For example:
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% load image %}
|
||||
{% load wagtailimages_tags %}
|
||||
...
|
||||
|
||||
{% image self.photo width-400 %}
|
||||
@ -206,7 +209,7 @@ No validation is performed on attributes add in this way by the developer. It's
|
||||
Wagtail can assign the image data to another object using Django's ``as`` syntax:
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
|
||||
{% image self.photo width-400 as tmp_photo %}
|
||||
|
||||
<img src="{{ tmp_photo.src }}" width="{{ tmp_photo.width }}"
|
||||
@ -228,13 +231,16 @@ You can also use the ``attrs`` property as a shorthand to output the ``src``, ``
|
||||
Rich text (filter)
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. versionchanged:: 0.4
|
||||
The 'rich_text' tags library was renamed to 'wagtailcore_tags'
|
||||
|
||||
This filter takes a chunk of HTML content and renders it as safe HTML in the page. Importantly it also expands internal shorthand references to embedded images and links made in the Wagtail editor into fully-baked HTML ready for display.
|
||||
|
||||
Only fields using ``RichTextField`` need this applied in the template.
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% load rich_text %}
|
||||
{% load wagtailcore_tags %}
|
||||
...
|
||||
{{ self.body|richtext }}
|
||||
|
||||
@ -270,6 +276,9 @@ Wagtail embeds and images are included at their full width, which may overflow t
|
||||
Internal links (tag)
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. versionchanged:: 0.4
|
||||
The 'pageurl' tags library was renamed to 'wagtailcore_tags'
|
||||
|
||||
pageurl
|
||||
--------
|
||||
|
||||
@ -277,7 +286,7 @@ Takes a Page object and returns a relative URL (``/foo/bar/``) if within the sam
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% load pageurl %}
|
||||
{% load wagtailcore_tags %}
|
||||
...
|
||||
<a href="{% pageurl self.blog_page %}">
|
||||
|
||||
@ -288,7 +297,7 @@ Takes any ``slug`` as defined in a page's "Promote" tab and returns the URL for
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% load slugurl %}
|
||||
{% load wagtailcore_tags %}
|
||||
...
|
||||
<a href="{% slugurl self.your_slug %}">
|
||||
|
||||
|
@ -1,24 +1,8 @@
|
||||
from django import template
|
||||
import warnings
|
||||
|
||||
from wagtail.wagtailcore.models import Page
|
||||
|
||||
register = template.Library()
|
||||
warnings.warn(
|
||||
"The pageurl tag library has been moved to wagtailcore_tags. "
|
||||
"Use {% load wagtailcore_tags %} instead.", DeprecationWarning)
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
def pageurl(context, page):
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
return page.relative_url(context['request'].site)
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
def slugurl(context, slug):
|
||||
"""Returns the URL for the page that has the given slug."""
|
||||
page = Page.objects.filter(slug=slug).first()
|
||||
|
||||
if page:
|
||||
return page.relative_url(context['request'].site)
|
||||
else:
|
||||
return None
|
||||
from wagtail.wagtailcore.templatetags.wagtailcore_tags import register
|
||||
|
@ -1,11 +1,8 @@
|
||||
from django import template
|
||||
from django.utils.safestring import mark_safe
|
||||
import warnings
|
||||
|
||||
from wagtail.wagtailcore.rich_text import expand_db_html
|
||||
|
||||
register = template.Library()
|
||||
warnings.warn(
|
||||
"The rich_text tag library has been moved to wagtailcore_tags. "
|
||||
"Use {% load wagtailcore_tags %} instead.", DeprecationWarning)
|
||||
|
||||
|
||||
@register.filter
|
||||
def richtext(value):
|
||||
return mark_safe('<div class="rich-text">' + expand_db_html(value) + '</div>')
|
||||
from wagtail.wagtailcore.templatetags.wagtailcore_tags import register
|
||||
|
32
wagtail/wagtailcore/templatetags/wagtailcore_tags.py
Normal file
32
wagtail/wagtailcore/templatetags/wagtailcore_tags.py
Normal file
@ -0,0 +1,32 @@
|
||||
from django import template
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
from wagtail.wagtailcore.models import Page
|
||||
from wagtail.wagtailcore.rich_text import expand_db_html
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
def pageurl(context, page):
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
return page.relative_url(context['request'].site)
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
def slugurl(context, slug):
|
||||
"""Returns the URL for the page that has the given slug."""
|
||||
page = Page.objects.filter(slug=slug).first()
|
||||
|
||||
if page:
|
||||
return page.relative_url(context['request'].site)
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
@register.filter
|
||||
def richtext(value):
|
||||
return mark_safe('<div class="rich-text">' + expand_db_html(value) + '</div>')
|
@ -1,24 +1,8 @@
|
||||
from django import template
|
||||
from django.utils.safestring import mark_safe
|
||||
import warnings
|
||||
|
||||
from wagtail.wagtailembeds import get_embed
|
||||
warnings.warn(
|
||||
"The embed_filters tag library has been moved to wagtailcore_tags. "
|
||||
"Use {% load wagtailembeds_tags %} instead.", DeprecationWarning)
|
||||
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.filter
|
||||
def embed(url, max_width=None):
|
||||
embed = get_embed(url, max_width=max_width)
|
||||
try:
|
||||
if embed is not None:
|
||||
return mark_safe(embed.html)
|
||||
else:
|
||||
return ''
|
||||
except:
|
||||
return ''
|
||||
|
||||
|
||||
@register.filter
|
||||
def embedly(url, max_width=None):
|
||||
return embed(url, max_width)
|
||||
from wagtail.wagtailembeds.templatetags.wagtailembeds_tags import register
|
||||
|
28
wagtail/wagtailembeds/templatetags/wagtailembeds_tags.py
Normal file
28
wagtail/wagtailembeds/templatetags/wagtailembeds_tags.py
Normal file
@ -0,0 +1,28 @@
|
||||
from django import template
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
from wagtail.wagtailembeds import get_embed
|
||||
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.filter
|
||||
def embed(url, max_width=None):
|
||||
embed = get_embed(url, max_width=max_width)
|
||||
try:
|
||||
if embed is not None:
|
||||
return mark_safe(embed.html)
|
||||
else:
|
||||
return ''
|
||||
except:
|
||||
return ''
|
||||
|
||||
|
||||
@register.filter
|
||||
def embedly(url, max_width=None):
|
||||
warnings.warn(
|
||||
"The 'embedly' filter has been renamed. "
|
||||
"Use 'embed' instead.", DeprecationWarning)
|
||||
|
||||
return embed(url, max_width)
|
@ -1,76 +1,8 @@
|
||||
from django import template
|
||||
import warnings
|
||||
|
||||
from wagtail.wagtailimages.models import Filter
|
||||
|
||||
register = template.Library()
|
||||
|
||||
# Local cache of filters, avoid hitting the DB
|
||||
filters = {}
|
||||
warnings.warn(
|
||||
"The image_tags tag library has been moved to wagtailcore_tags. "
|
||||
"Use {% load wagtailimages_tags %} instead.", DeprecationWarning)
|
||||
|
||||
|
||||
@register.tag(name="image")
|
||||
def image(parser, token):
|
||||
bits = token.split_contents()[1:]
|
||||
image_var = bits[0]
|
||||
filter_spec = bits[1]
|
||||
bits = bits[2:]
|
||||
|
||||
if len(bits) == 2 and bits[0] == 'as':
|
||||
# token is of the form {% image self.photo max-320x200 as img %}
|
||||
return ImageNode(image_var, filter_spec, output_var_name=bits[1])
|
||||
else:
|
||||
# token is of the form {% image self.photo max-320x200 %} - all additional tokens
|
||||
# should be kwargs, which become attributes
|
||||
attrs = {}
|
||||
for bit in bits:
|
||||
try:
|
||||
name, value = bit.split('=')
|
||||
except ValueError:
|
||||
raise template.TemplateSyntaxError("'image' tag should be of the form {% image self.photo max-320x200 [ custom-attr=\"value\" ... ] %} or {% image self.photo max-320x200 as img %}")
|
||||
attrs[name] = parser.compile_filter(value) # setup to resolve context variables as value
|
||||
|
||||
return ImageNode(image_var, filter_spec, attrs=attrs)
|
||||
|
||||
|
||||
class ImageNode(template.Node):
|
||||
def __init__(self, image_var_name, filter_spec, output_var_name=None, attrs={}):
|
||||
self.image_var = template.Variable(image_var_name)
|
||||
self.output_var_name = output_var_name
|
||||
self.attrs = attrs
|
||||
|
||||
if filter_spec not in filters:
|
||||
filters[filter_spec], _ = Filter.objects.get_or_create(spec=filter_spec)
|
||||
self.filter = filters[filter_spec]
|
||||
|
||||
def render(self, context):
|
||||
try:
|
||||
image = self.image_var.resolve(context)
|
||||
except template.VariableDoesNotExist:
|
||||
return ''
|
||||
|
||||
if not image:
|
||||
return ''
|
||||
|
||||
try:
|
||||
rendition = image.get_rendition(self.filter)
|
||||
except IOError:
|
||||
# It's fairly routine for people to pull down remote databases to their
|
||||
# local dev versions without retrieving the corresponding image files.
|
||||
# In such a case, we would get an IOError at the point where we try to
|
||||
# create the resized version of a non-existent image. Since this is a
|
||||
# bit catastrophic for a missing image, we'll substitute a dummy
|
||||
# Rendition object so that we just output a broken link instead.
|
||||
Rendition = image.renditions.model # pick up any custom Image / Rendition classes that may be in use
|
||||
rendition = Rendition(image=image, width=0, height=0)
|
||||
rendition.file.name = 'not-found'
|
||||
|
||||
if self.output_var_name:
|
||||
# return the rendition object in the given variable
|
||||
context[self.output_var_name] = rendition
|
||||
return ''
|
||||
else:
|
||||
# render the rendition's image tag now
|
||||
resolved_attrs = {}
|
||||
for key in self.attrs:
|
||||
resolved_attrs[key] = self.attrs[key].resolve(context)
|
||||
return rendition.img_tag(resolved_attrs)
|
||||
from wagtail.wagtailimages.templatetags.wagtailimages_tags import register
|
||||
|
76
wagtail/wagtailimages/templatetags/wagtailimages_tags.py
Normal file
76
wagtail/wagtailimages/templatetags/wagtailimages_tags.py
Normal file
@ -0,0 +1,76 @@
|
||||
from django import template
|
||||
|
||||
from wagtail.wagtailimages.models import Filter
|
||||
|
||||
register = template.Library()
|
||||
|
||||
# Local cache of filters, avoid hitting the DB
|
||||
filters = {}
|
||||
|
||||
|
||||
@register.tag(name="image")
|
||||
def image(parser, token):
|
||||
bits = token.split_contents()[1:]
|
||||
image_var = bits[0]
|
||||
filter_spec = bits[1]
|
||||
bits = bits[2:]
|
||||
|
||||
if len(bits) == 2 and bits[0] == 'as':
|
||||
# token is of the form {% image self.photo max-320x200 as img %}
|
||||
return ImageNode(image_var, filter_spec, output_var_name=bits[1])
|
||||
else:
|
||||
# token is of the form {% image self.photo max-320x200 %} - all additional tokens
|
||||
# should be kwargs, which become attributes
|
||||
attrs = {}
|
||||
for bit in bits:
|
||||
try:
|
||||
name, value = bit.split('=')
|
||||
except ValueError:
|
||||
raise template.TemplateSyntaxError("'image' tag should be of the form {% image self.photo max-320x200 [ custom-attr=\"value\" ... ] %} or {% image self.photo max-320x200 as img %}")
|
||||
attrs[name] = parser.compile_filter(value) # setup to resolve context variables as value
|
||||
|
||||
return ImageNode(image_var, filter_spec, attrs=attrs)
|
||||
|
||||
|
||||
class ImageNode(template.Node):
|
||||
def __init__(self, image_var_name, filter_spec, output_var_name=None, attrs={}):
|
||||
self.image_var = template.Variable(image_var_name)
|
||||
self.output_var_name = output_var_name
|
||||
self.attrs = attrs
|
||||
|
||||
if filter_spec not in filters:
|
||||
filters[filter_spec], _ = Filter.objects.get_or_create(spec=filter_spec)
|
||||
self.filter = filters[filter_spec]
|
||||
|
||||
def render(self, context):
|
||||
try:
|
||||
image = self.image_var.resolve(context)
|
||||
except template.VariableDoesNotExist:
|
||||
return ''
|
||||
|
||||
if not image:
|
||||
return ''
|
||||
|
||||
try:
|
||||
rendition = image.get_rendition(self.filter)
|
||||
except IOError:
|
||||
# It's fairly routine for people to pull down remote databases to their
|
||||
# local dev versions without retrieving the corresponding image files.
|
||||
# In such a case, we would get an IOError at the point where we try to
|
||||
# create the resized version of a non-existent image. Since this is a
|
||||
# bit catastrophic for a missing image, we'll substitute a dummy
|
||||
# Rendition object so that we just output a broken link instead.
|
||||
Rendition = image.renditions.model # pick up any custom Image / Rendition classes that may be in use
|
||||
rendition = Rendition(image=image, width=0, height=0)
|
||||
rendition.file.name = 'not-found'
|
||||
|
||||
if self.output_var_name:
|
||||
# return the rendition object in the given variable
|
||||
context[self.output_var_name] = rendition
|
||||
return ''
|
||||
else:
|
||||
# render the rendition's image tag now
|
||||
resolved_attrs = {}
|
||||
for key in self.attrs:
|
||||
resolved_attrs[key] = self.attrs[key].resolve(context)
|
||||
return rendition.img_tag(resolved_attrs)
|
Loading…
Reference in New Issue
Block a user