diff --git a/docs/building_your_site/frontenddevelopers.rst b/docs/building_your_site/frontenddevelopers.rst index b0d332450e..35aa1c8450 100644 --- a/docs/building_your_site/frontenddevelopers.rst +++ b/docs/building_your_site/frontenddevelopers.rst @@ -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 %} @@ -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 %} ... diff --git a/wagtail/wagtailcore/templatetags/pageurl.py b/wagtail/wagtailcore/templatetags/pageurl.py index d3488d9b45..b31756c308 100644 --- a/wagtail/wagtailcore/templatetags/pageurl.py +++ b/wagtail/wagtailcore/templatetags/pageurl.py @@ -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 diff --git a/wagtail/wagtailcore/templatetags/rich_text.py b/wagtail/wagtailcore/templatetags/rich_text.py index d3bc64fddc..ed8ac6f0f0 100644 --- a/wagtail/wagtailcore/templatetags/rich_text.py +++ b/wagtail/wagtailcore/templatetags/rich_text.py @@ -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('
' + expand_db_html(value) + '
') +from wagtail.wagtailcore.templatetags.wagtailcore_tags import register diff --git a/wagtail/wagtailcore/templatetags/wagtailcore_tags.py b/wagtail/wagtailcore/templatetags/wagtailcore_tags.py new file mode 100644 index 0000000000..5e137c7a2e --- /dev/null +++ b/wagtail/wagtailcore/templatetags/wagtailcore_tags.py @@ -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('
' + expand_db_html(value) + '
') diff --git a/wagtail/wagtailembeds/templatetags/embed_filters.py b/wagtail/wagtailembeds/templatetags/embed_filters.py index d916c0ffba..7d3500e581 100644 --- a/wagtail/wagtailembeds/templatetags/embed_filters.py +++ b/wagtail/wagtailembeds/templatetags/embed_filters.py @@ -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 diff --git a/wagtail/wagtailembeds/templatetags/wagtailembeds_tags.py b/wagtail/wagtailembeds/templatetags/wagtailembeds_tags.py new file mode 100644 index 0000000000..aad751c6a6 --- /dev/null +++ b/wagtail/wagtailembeds/templatetags/wagtailembeds_tags.py @@ -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) diff --git a/wagtail/wagtailimages/templatetags/image_tags.py b/wagtail/wagtailimages/templatetags/image_tags.py index 5c72734177..9a96356c9a 100644 --- a/wagtail/wagtailimages/templatetags/image_tags.py +++ b/wagtail/wagtailimages/templatetags/image_tags.py @@ -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 diff --git a/wagtail/wagtailimages/templatetags/wagtailimages_tags.py b/wagtail/wagtailimages/templatetags/wagtailimages_tags.py new file mode 100644 index 0000000000..5c72734177 --- /dev/null +++ b/wagtail/wagtailimages/templatetags/wagtailimages_tags.py @@ -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)