feat(templatetags): fix #143, ability to preload components

This commit is contained in:
David Guillot 2022-04-28 19:45:11 +02:00
parent 021339d4a7
commit f67cd37dea
2 changed files with 107 additions and 6 deletions

View file

@ -30,13 +30,36 @@ def get_components_from_registry(registry):
return components
def get_components_from_preload_str(preload_str):
"""Returns a list of unique components from a comma-separated str"""
components = []
for component_name in preload_str.split(","):
component_name = component_name.strip()
if not component_name:
continue
component_class = registry.get(component_name)
components.append(component_class(component_name))
return components
@register.simple_tag(name="component_dependencies")
def component_dependencies_tag():
def component_dependencies_tag(preload=""):
"""Marks location where CSS link and JS script tags should be rendered."""
if is_dependency_middleware_active():
preloaded_dependencies = []
for component in get_components_from_preload_str(preload):
preloaded_dependencies.append(
RENDERED_COMMENT_TEMPLATE.format(
name=component._component_name
)
)
return mark_safe(
CSS_DEPENDENCY_PLACEHOLDER + JS_DEPENDENCY_PLACEHOLDER
"\n".join(preloaded_dependencies)
+ CSS_DEPENDENCY_PLACEHOLDER
+ JS_DEPENDENCY_PLACEHOLDER
)
else:
rendered_dependencies = []
@ -47,11 +70,20 @@ def component_dependencies_tag():
@register.simple_tag(name="component_css_dependencies")
def component_css_dependencies_tag():
def component_css_dependencies_tag(preload=""):
"""Marks location where CSS link tags should be rendered."""
if is_dependency_middleware_active():
return mark_safe(CSS_DEPENDENCY_PLACEHOLDER)
preloaded_dependencies = []
for component in get_components_from_preload_str(preload):
preloaded_dependencies.append(
RENDERED_COMMENT_TEMPLATE.format(
name=component._component_name
)
)
return mark_safe(
"\n".join(preloaded_dependencies) + CSS_DEPENDENCY_PLACEHOLDER
)
else:
rendered_dependencies = []
for component in get_components_from_registry(registry):
@ -61,11 +93,20 @@ def component_css_dependencies_tag():
@register.simple_tag(name="component_js_dependencies")
def component_js_dependencies_tag():
def component_js_dependencies_tag(preload=""):
"""Marks location where JS script tags should be rendered."""
if is_dependency_middleware_active():
return mark_safe(JS_DEPENDENCY_PLACEHOLDER)
preloaded_dependencies = []
for component in get_components_from_preload_str(preload):
preloaded_dependencies.append(
RENDERED_COMMENT_TEMPLATE.format(
name=component._component_name
)
)
return mark_safe(
"\n".join(preloaded_dependencies) + JS_DEPENDENCY_PLACEHOLDER
)
else:
rendered_dependencies = []
for component in get_components_from_registry(registry):

View file

@ -86,6 +86,42 @@ class ComponentMediaRenderingTests(SimpleTestCase):
count=0,
)
def test_preload_dependencies_render_when_no_components_used(self):
component.registry.register(name="test", component=SimpleComponent)
template = Template(
"{% load component_tags %}{% component_dependencies preload='test' %}"
)
rendered = create_and_process_template_response(template)
self.assertInHTML('<script src="script.js">', rendered, count=1)
self.assertInHTML(
'<link href="style.css" type="text/css" media="all" rel="stylesheet"/>',
rendered,
count=1,
)
def test_preload_js_dependencies_render_when_no_components_used(self):
component.registry.register(name="test", component=SimpleComponent)
template = Template(
"{% load component_tags %}{% component_js_dependencies preload='test' %}"
)
rendered = create_and_process_template_response(template)
self.assertInHTML('<script src="script.js">', rendered, count=1)
def test_preload_css_dependencies_render_when_no_components_used(self):
component.registry.register(name="test", component=SimpleComponent)
template = Template(
"{% load component_tags %}{% component_css_dependencies preload='test' %}"
)
rendered = create_and_process_template_response(template)
self.assertInHTML(
'<link href="style.css" type="text/css" media="all" rel="stylesheet"/>',
rendered,
count=1,
)
def test_single_component_dependencies_render_when_used(self):
component.registry.register(name="test", component=SimpleComponent)
@ -101,6 +137,21 @@ class ComponentMediaRenderingTests(SimpleTestCase):
)
self.assertInHTML('<script src="script.js">', rendered, count=1)
def test_preload_dependencies_render_once_when_used(self):
component.registry.register(name="test", component=SimpleComponent)
template = Template(
"{% load component_tags %}{% component_dependencies preload='test' %}"
"{% component 'test' variable='foo' %}"
)
rendered = create_and_process_template_response(template)
self.assertInHTML(
'<link href="style.css" type="text/css" media="all" rel="stylesheet"/>',
rendered,
count=1,
)
self.assertInHTML('<script src="script.js">', rendered, count=1)
def test_placeholder_removed_when_single_component_rendered(self):
component.registry.register(name="test", component=SimpleComponent)
@ -111,6 +162,15 @@ class ComponentMediaRenderingTests(SimpleTestCase):
rendered = create_and_process_template_response(template)
self.assertNotIn("_RENDERED", rendered)
def test_placeholder_removed_when_preload_rendered(self):
component.registry.register(name="test", component=SimpleComponent)
template = Template(
"{% load component_tags %}{% component_dependencies preload='test' %}"
)
rendered = create_and_process_template_response(template)
self.assertNotIn("_RENDERED", rendered)
def test_single_component_css_dependencies(self):
component.registry.register(name="test", component=SimpleComponent)