Skip to content
This repository has been archived by the owner on Sep 6, 2019. It is now read-only.

Commit

Permalink
Merge branch 'feature/issue-21-script-attributes' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
sergei-maertens committed Sep 19, 2016
2 parents 39604ee + 7723e3a commit 6beecc6
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 10 deletions.
15 changes: 15 additions & 0 deletions docs/usage.rst
Expand Up @@ -55,6 +55,21 @@ use the ``CachedStaticFilesStorage``, you will get the hashed path:
aren't removed from the manifest file.


The tag accepts any number of (custom) attributes you may want to add, making it
possible to load scripts async, or specify html ids for example.

.. code-block:: django
{% load system_tags %}
{% systemjs_import 'my/awesome/app.js' async id="my-awesome-app" %}
this will output (in production mode)

.. code-block:: html

<script type="text/javascript" async id="my-awesome-app" src="/static/SYSTEMJS/my/awesome/app.12ab459edf22.js"></script>


Management commands
===================

Expand Down
39 changes: 32 additions & 7 deletions systemjs/templatetags/system_tags.py
@@ -1,20 +1,28 @@
from __future__ import unicode_literals

import posixpath
import re

from django import template
from django.conf import settings
from django.contrib.staticfiles.storage import staticfiles_storage
from django.forms.utils import flatatt
from django.template.base import token_kwargs

from systemjs.base import System

register = template.Library()


# Regex for token keyword arguments
kwarg_re = re.compile(r"(?:(\w+)=)?(.+)")


class SystemImportNode(template.Node):

def __init__(self, path):
def __init__(self, path, tag_attrs=None):
self.path = path
self.tag_attrs = tag_attrs

def render(self, context):
"""
Expand All @@ -32,19 +40,36 @@ def render(self, context):
# else: create a bundle
rel_path = System.get_bundle_path(module_path)
url = staticfiles_storage.url(rel_path)
return """<script type="text/javascript" src="{url}"></script>""".format(url=url)

tag_attrs = {'type': 'text/javascript'}
for key, value in self.tag_attrs.items():
if not isinstance(value, bool):
value = value.resolve(context)
tag_attrs[key] = value

return """<script{attrs} src="{url}"></script>""".format(
url=url, attrs=flatatt(tag_attrs)
)

@classmethod
def handle_token(cls, parser, token):
bits = token.split_contents()
attrs = {}

if len(bits) < 2:
raise template.TemplateSyntaxError("'%s' takes at least one argument (js module)" % bits[0])

if len(bits) != 2:
raise template.TemplateSyntaxError(
"'%s' takes at least one argument (js module, without extension)" % bits[0])
if len(bits) > 2:
for bit in bits[2:]:
# First we try to extract a potential kwarg from the bit
kwarg = token_kwargs([bit], parser)
if kwarg:
attrs.update(kwarg)
else:
attrs[bit] = True # for flatatt

# for 'as varname' support, check django.templatetags.static
path = parser.compile_filter(bits[1])
return cls(path)
return cls(path, tag_attrs=attrs)


@register.tag
Expand Down
14 changes: 11 additions & 3 deletions tests/tests/test_templatetags.py
Expand Up @@ -35,9 +35,6 @@ def test_incorrect_number_arguments(self):
with self.assertRaises(TemplateSyntaxError):
django_engine.from_string("""{% load system_tags %}{% systemjs_import %}""")

with self.assertRaises(TemplateSyntaxError):
django_engine.from_string("""{% load system_tags %}{% systemjs_import 'foo' 'bar' %}""")

@override_settings(SYSTEMJS_ENABLED=False, SYSTEMJS_DEFAULT_JS_EXTENSIONS=False)
def test_debug_module_without_extension_no_default(self):
rendered = self._render()
Expand All @@ -55,3 +52,14 @@ def test_debug_module_without_extension_default_js(self):
self.template = django_engine.from_string("""{% load system_tags %}{% systemjs_import 'myapp/main.js' %}""")
rendered = self._render()
self.assertEqual(rendered, """<script type="text/javascript">System.import('myapp/main.js');</script>""")

@override_settings(SYSTEMJS_ENABLED=True, SYSTEMJS_OUTPUT_DIR='SJ')
def test_script_tag_attributes(self):
template = """{% load system_tags %}{% systemjs_import 'myapp/main' async foo="bar" %}"""
template = django_engine.from_string(template)
rendered = template.render(self.context)
expected_url = urljoin(settings.STATIC_URL, 'SJ/myapp/main.js')
self.assertHTMLEqual(
rendered,
"""<script async foo="bar" type="text/javascript" src="{0}"></script>""".format(expected_url)
)

0 comments on commit 6beecc6

Please sign in to comment.