mirror of https://github.com/django/django.git
Fixed #18254 -- Added ability to the static template tags to store the result in a contextt variable. Many thanks to Andrei Antoukh for the initial patch.
This commit is contained in:
parent
8dafd04c45
commit
0a68a2994b
|
@ -1,13 +1,37 @@
|
||||||
from django import template
|
from django import template
|
||||||
|
from django.templatetags.static import StaticNode
|
||||||
from django.contrib.staticfiles.storage import staticfiles_storage
|
from django.contrib.staticfiles.storage import staticfiles_storage
|
||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag
|
class StaticFilesNode(StaticNode):
|
||||||
def static(path):
|
|
||||||
|
def url(self, context):
|
||||||
|
path = self.path.resolve(context)
|
||||||
|
return staticfiles_storage.url(path)
|
||||||
|
|
||||||
|
|
||||||
|
@register.tag('static')
|
||||||
|
def do_static(parser, token):
|
||||||
"""
|
"""
|
||||||
A template tag that returns the URL to a file
|
A template tag that returns the URL to a file
|
||||||
using staticfiles' storage backend
|
using staticfiles' storage backend
|
||||||
|
|
||||||
|
Usage::
|
||||||
|
|
||||||
|
{% static path [as varname] %}
|
||||||
|
|
||||||
|
Examples::
|
||||||
|
|
||||||
|
{% static "myapp/css/base.css" %}
|
||||||
|
{% static variable_with_path %}
|
||||||
|
{% static "myapp/css/base.css" as admin_base_css %}
|
||||||
|
{% static variable_with_path as varname %}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return staticfiles_storage.url(path)
|
return StaticFilesNode.handle_token(parser, token)
|
||||||
|
|
||||||
|
|
||||||
|
def static(path):
|
||||||
|
return StaticNode.handle_simple(path)
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
from urlparse import urljoin
|
from urlparse import urljoin
|
||||||
from django import template
|
from django import template
|
||||||
|
from django.template.base import Node
|
||||||
from django.utils.encoding import iri_to_uri
|
from django.utils.encoding import iri_to_uri
|
||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
|
|
||||||
class PrefixNode(template.Node):
|
class PrefixNode(template.Node):
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -48,6 +50,7 @@ class PrefixNode(template.Node):
|
||||||
context[self.varname] = prefix
|
context[self.varname] = prefix
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
@register.tag
|
@register.tag
|
||||||
def get_static_prefix(parser, token):
|
def get_static_prefix(parser, token):
|
||||||
"""
|
"""
|
||||||
|
@ -66,6 +69,7 @@ def get_static_prefix(parser, token):
|
||||||
"""
|
"""
|
||||||
return PrefixNode.handle_token(parser, token, "STATIC_URL")
|
return PrefixNode.handle_token(parser, token, "STATIC_URL")
|
||||||
|
|
||||||
|
|
||||||
@register.tag
|
@register.tag
|
||||||
def get_media_prefix(parser, token):
|
def get_media_prefix(parser, token):
|
||||||
"""
|
"""
|
||||||
|
@ -84,19 +88,70 @@ def get_media_prefix(parser, token):
|
||||||
"""
|
"""
|
||||||
return PrefixNode.handle_token(parser, token, "MEDIA_URL")
|
return PrefixNode.handle_token(parser, token, "MEDIA_URL")
|
||||||
|
|
||||||
@register.simple_tag
|
|
||||||
def static(path):
|
class StaticNode(Node):
|
||||||
|
def __init__(self, varname=None, path=None):
|
||||||
|
if path is None:
|
||||||
|
raise template.TemplateSyntaxError(
|
||||||
|
"Static template nodes must be given a path to return.")
|
||||||
|
self.path = path
|
||||||
|
self.varname = varname
|
||||||
|
|
||||||
|
def url(self, context):
|
||||||
|
path = self.path.resolve(context)
|
||||||
|
return self.handle_simple(path)
|
||||||
|
|
||||||
|
def render(self, context):
|
||||||
|
url = self.url(context)
|
||||||
|
if self.varname is None:
|
||||||
|
return url
|
||||||
|
context[self.varname] = url
|
||||||
|
return ''
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def handle_simple(cls, path):
|
||||||
|
return urljoin(PrefixNode.handle_simple("STATIC_URL"), path)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def handle_token(cls, parser, token):
|
||||||
|
"""
|
||||||
|
Class method to parse prefix node and return a Node.
|
||||||
|
"""
|
||||||
|
bits = token.split_contents()
|
||||||
|
|
||||||
|
if len(bits) < 2:
|
||||||
|
raise template.TemplateSyntaxError(
|
||||||
|
"'%s' takes at least one argument (path to file)" % bits[0])
|
||||||
|
|
||||||
|
path = parser.compile_filter(bits[1])
|
||||||
|
|
||||||
|
if len(bits) >= 2 and bits[-2] == 'as':
|
||||||
|
varname = bits[3]
|
||||||
|
else:
|
||||||
|
varname = None
|
||||||
|
|
||||||
|
return cls(varname, path)
|
||||||
|
|
||||||
|
|
||||||
|
@register.tag('static')
|
||||||
|
def do_static(parser, token):
|
||||||
"""
|
"""
|
||||||
Joins the given path with the STATIC_URL setting.
|
Joins the given path with the STATIC_URL setting.
|
||||||
|
|
||||||
Usage::
|
Usage::
|
||||||
|
|
||||||
{% static path %}
|
{% static path [as varname] %}
|
||||||
|
|
||||||
Examples::
|
Examples::
|
||||||
|
|
||||||
{% static "myapp/css/base.css" %}
|
{% static "myapp/css/base.css" %}
|
||||||
{% static variable_with_path %}
|
{% static variable_with_path %}
|
||||||
|
{% static "myapp/css/base.css" as admin_base_css %}
|
||||||
|
{% static variable_with_path as varname %}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return urljoin(PrefixNode.handle_simple("STATIC_URL"), path)
|
return StaticNode.handle_token(parser, token)
|
||||||
|
|
||||||
|
|
||||||
|
def static(path):
|
||||||
|
return StaticNode.handle_simple(path)
|
||||||
|
|
|
@ -387,6 +387,17 @@ The previous example is equal to calling the ``url`` method of an instance of
|
||||||
useful when using a non-local storage backend to deploy files as documented
|
useful when using a non-local storage backend to deploy files as documented
|
||||||
in :ref:`staticfiles-from-cdn`.
|
in :ref:`staticfiles-from-cdn`.
|
||||||
|
|
||||||
|
.. versionadded:: 1.5
|
||||||
|
|
||||||
|
If you'd like to retrieve a static URL without displaying it, you can use a
|
||||||
|
slightly different call::
|
||||||
|
|
||||||
|
.. code-block:: html+django
|
||||||
|
|
||||||
|
{% load static from staticfiles %}
|
||||||
|
{% static "images/hi.jpg" as myphoto %}
|
||||||
|
<img src="{{ myphoto }}" alt="Hi!" />
|
||||||
|
|
||||||
Other Helpers
|
Other Helpers
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
|
|
@ -2354,6 +2354,17 @@ It is also able to consume standard context variables, e.g. assuming a
|
||||||
{% load static %}
|
{% load static %}
|
||||||
<link rel="stylesheet" href="{% static user_stylesheet %}" type="text/css" media="screen" />
|
<link rel="stylesheet" href="{% static user_stylesheet %}" type="text/css" media="screen" />
|
||||||
|
|
||||||
|
If you'd like to retrieve a static URL without displaying it, you can use a
|
||||||
|
slightly different call::
|
||||||
|
|
||||||
|
.. versionadded:: 1.5
|
||||||
|
|
||||||
|
.. code-block:: html+django
|
||||||
|
|
||||||
|
{% load static %}
|
||||||
|
{% static "images/hi.jpg" as myphoto %}
|
||||||
|
<img src="{{ myphoto }}"></img>
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
The :mod:`staticfiles<django.contrib.staticfiles>` contrib app also ships
|
The :mod:`staticfiles<django.contrib.staticfiles>` contrib app also ships
|
||||||
|
|
|
@ -87,14 +87,16 @@ class BaseStaticFilesTestCase(object):
|
||||||
template = loader.get_template_from_string(template)
|
template = loader.get_template_from_string(template)
|
||||||
return template.render(Context(kwargs)).strip()
|
return template.render(Context(kwargs)).strip()
|
||||||
|
|
||||||
def static_template_snippet(self, path):
|
def static_template_snippet(self, path, asvar=False):
|
||||||
|
if asvar:
|
||||||
|
return "{%% load static from staticfiles %%}{%% static '%s' as var %%}{{ var }}" % path
|
||||||
return "{%% load static from staticfiles %%}{%% static '%s' %%}" % path
|
return "{%% load static from staticfiles %%}{%% static '%s' %%}" % path
|
||||||
|
|
||||||
def assertStaticRenders(self, path, result, **kwargs):
|
def assertStaticRenders(self, path, result, asvar=False, **kwargs):
|
||||||
template = self.static_template_snippet(path)
|
template = self.static_template_snippet(path, asvar)
|
||||||
self.assertEqual(self.render_template(template, **kwargs), result)
|
self.assertEqual(self.render_template(template, **kwargs), result)
|
||||||
|
|
||||||
def assertStaticRaises(self, exc, path, result, **kwargs):
|
def assertStaticRaises(self, exc, path, result, asvar=False, **kwargs):
|
||||||
self.assertRaises(exc, self.assertStaticRenders, path, result, **kwargs)
|
self.assertRaises(exc, self.assertStaticRenders, path, result, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@ -368,6 +370,8 @@ class TestCollectionCachedStorage(BaseCollectionTestCase,
|
||||||
"/static/does/not/exist.png")
|
"/static/does/not/exist.png")
|
||||||
self.assertStaticRenders("test/file.txt",
|
self.assertStaticRenders("test/file.txt",
|
||||||
"/static/test/file.dad0999e4f8f.txt")
|
"/static/test/file.dad0999e4f8f.txt")
|
||||||
|
self.assertStaticRenders("test/file.txt",
|
||||||
|
"/static/test/file.dad0999e4f8f.txt", asvar=True)
|
||||||
self.assertStaticRenders("cached/styles.css",
|
self.assertStaticRenders("cached/styles.css",
|
||||||
"/static/cached/styles.93b1147e8552.css")
|
"/static/cached/styles.93b1147e8552.css")
|
||||||
self.assertStaticRenders("path/",
|
self.assertStaticRenders("path/",
|
||||||
|
|
|
@ -1616,6 +1616,8 @@ class Templates(unittest.TestCase):
|
||||||
'static-prefixtag04': ('{% load static %}{% get_media_prefix as media_prefix %}{{ media_prefix }}', {}, settings.MEDIA_URL),
|
'static-prefixtag04': ('{% load static %}{% get_media_prefix as media_prefix %}{{ media_prefix }}', {}, settings.MEDIA_URL),
|
||||||
'static-statictag01': ('{% load static %}{% static "admin/base.css" %}', {}, urljoin(settings.STATIC_URL, 'admin/base.css')),
|
'static-statictag01': ('{% load static %}{% static "admin/base.css" %}', {}, urljoin(settings.STATIC_URL, 'admin/base.css')),
|
||||||
'static-statictag02': ('{% load static %}{% static base_css %}', {'base_css': 'admin/base.css'}, urljoin(settings.STATIC_URL, 'admin/base.css')),
|
'static-statictag02': ('{% load static %}{% static base_css %}', {'base_css': 'admin/base.css'}, urljoin(settings.STATIC_URL, 'admin/base.css')),
|
||||||
|
'static-statictag03': ('{% load static %}{% static "admin/base.css" as foo %}{{ foo }}', {}, urljoin(settings.STATIC_URL, 'admin/base.css')),
|
||||||
|
'static-statictag04': ('{% load static %}{% static base_css as foo %}{{ foo }}', {'base_css': 'admin/base.css'}, urljoin(settings.STATIC_URL, 'admin/base.css')),
|
||||||
|
|
||||||
# Verbatim template tag outputs contents without rendering.
|
# Verbatim template tag outputs contents without rendering.
|
||||||
'verbatim-tag01': ('{% verbatim %}{{bare }}{% endverbatim %}', {}, '{{bare }}'),
|
'verbatim-tag01': ('{% verbatim %}{{bare }}{% endverbatim %}', {}, '{{bare }}'),
|
||||||
|
|
Loading…
Reference in New Issue