0
0
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:
Karl Hobley 2014-06-27 15:22:22 +01:00
commit 6e6b85d4f6
8 changed files with 170 additions and 128 deletions

View File

@ -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 %}">

View File

@ -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

View File

@ -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

View 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>')

View File

@ -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

View 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)

View File

@ -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

View 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)