Skip to content

Commit b94e432

Browse files
Merge pull request #28 from delsim/frame_identifiers
Parent div and frame identifiers
2 parents 243c886 + 670daf9 commit b94e432

File tree

4 files changed

+135
-5
lines changed

4 files changed

+135
-5
lines changed

demo/demo/templates/demo_one.html

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,25 @@ <h1>Simple App Embedding</h1>
1010
the plotly_app template tag with the name of a dash application represents the simplest use of
1111
the django_plotly_dash framework.
1212
</p>
13+
<p>
14+
The plotly_class tag is also used to wrap the application in css class names based on the
15+
application (django-plotly-dash), the
16+
type of the embedding (iframe), and the slugified version of the app name (simpleexample).
17+
</p>
1318
<div class="card bg-light border-dark">
1419
<div class="card-body">
1520
<p><span>{</span>% load plotly_dash %}</p>
16-
<p><span>{</span>% plotly_app name="SimpleExample" %}</p>
21+
<p>&lt;div class="<span>{</span>% plotly_class name="SimpleExample"%}">
22+
<p class="ml-3"><span>{</span>% plotly_app name="SimpleExample" %}</p>
23+
<p>&lt;\div>
1724
</div>
1825
</div>
1926
<p></p>
2027
<div class="card border-dark">
2128
<div class="card-body">
22-
{%plotly_app name="SimpleExample"%}
29+
<div class="{%plotly_class name="SimpleExample"%}">
30+
{%plotly_app name="SimpleExample"%}
31+
</div>
2332
</div>
2433
</div>
2534
{%endblock%}

django_plotly_dash/dash_wrapper.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
'''dash_wrapper
1+
'''
2+
dash_wrapper
23
34
This module provides a DjangoDash class that can be used to
45
expose a Plotly Dasb application through a Django server
@@ -196,7 +197,7 @@ def before_first_request(self, *args, **kwargs):
196197
pass
197198
def run(self, *args, **kwargs):
198199
pass
199-
def register_blueprint(*args, **kwargs):
200+
def register_blueprint(self, *args, **kwargs):
200201
pass
201202

202203
class WrappedDash(Dash):
@@ -302,7 +303,7 @@ def flask_app(self):
302303
return self._flask_app
303304

304305
def base_url(self):
305-
'Base url of this omponent'
306+
'Base url of this component'
306307
return self._base_pathname
307308

308309
def app_context(self, *args, **kwargs):
@@ -412,3 +413,28 @@ def dispatch_with_args(self, body, argMap):
412413
da.update_current_state(output['id'], output['property'], value)
413414

414415
return res
416+
417+
def slugified_id(self):
418+
'Return the app id in a slug-friendly form'
419+
pre_slugified_id = self._uid
420+
return slugify(pre_slugified_id)
421+
422+
def extra_html_properties(self, prefix=None, postfix=None, template_type=None):
423+
'''
424+
Return extra html properties to allow individual apps to be styled separately.
425+
426+
The content returned from this function is injected unescaped into templates.
427+
'''
428+
429+
prefix = prefix if prefix else "django-plotly-dash"
430+
431+
post_part = "-%s" % postfix if postfix else ""
432+
template_type = template_type if template_type else "iframe"
433+
434+
slugified_id = self.slugified_id()
435+
436+
return "%(prefix)s %(prefix)s-%(template_type)s %(prefix)s-app-%(slugified_id)s%(post_part)s" % {'slugified_id':slugified_id,
437+
'post_part':post_part,
438+
'template_type':template_type,
439+
'prefix':prefix,
440+
}

django_plotly_dash/templatetags/plotly_dash.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,38 @@ def plotly_message_pipe(context, url=None):
7272
'Insert script for providing background websocket connection'
7373
url = url if url else ws_default_url
7474
return locals()
75+
76+
@register.simple_tag()
77+
def plotly_app_identifier(name=None, slug=None, da=None, postfix=None):
78+
'Return a slug-friendly identifier'
79+
if name is not None:
80+
da, app = DashApp.locate_item(name, stateless=True)
81+
82+
if slug is not None:
83+
da, app = DashApp.locate_item(slug, stateless=False)
84+
85+
if not app:
86+
app = da.as_dash_instance()
87+
88+
slugified_id = app.slugified_id()
89+
90+
if postfix:
91+
return "%s-%s" %(slugified_id, postfix)
92+
return slugified_id
93+
94+
@register.simple_tag()
95+
def plotly_class(name=None, slug=None, da=None, prefix=None, postfix=None, template_type=None):
96+
'Return a string of space-separated class names'
97+
98+
if name is not None:
99+
da, app = DashApp.locate_item(name, stateless=True)
100+
101+
if slug is not None:
102+
da, app = DashApp.locate_item(slug, stateless=False)
103+
104+
if not app:
105+
app = da.as_dash_instance()
106+
107+
return app.extra_html_properties(prefix=prefix,
108+
postfix=postfix,
109+
template_type=template_type)

docs/template_tags.rst

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,63 @@ on the page, and its ordering relative to the ``Dash`` instances using updating
5454
the page footer - to avoid delaying the main page load - along
5555
with other scripts is generally advisable.
5656

57+
The ``plotly_app_identifier`` template tag
58+
-----------------------------------------
59+
60+
This tag provides an identifier for an app, in a form that is suitable for use as a classname or identifier
61+
in HTML:
62+
63+
.. code-block:: jinja
64+
65+
{%load plotly_dash%}
66+
67+
{%plotly_app_identifier name="SimpleExample"%}
68+
69+
{%plotly_app_identifier slug="liveoutput-2" postfix="A"%}
70+
71+
The identifier, if the tag is not passed a ``slug``, is the result of passing the identifier of the app through
72+
the ``django.utils.text.slugify`` function.
73+
74+
The tag arguments are:
75+
76+
:name = None: The name of the application, as passed to a ``DjangoDash`` constructor.
77+
:slug = None: The slug of an existing ``DashApp`` instance.
78+
:da = None: An existing ``django_plotly_dash.models.DashApp`` model instance.
79+
:postfix = None: An optional string; if specified it is appended to the identifier with a hyphen.
80+
81+
The validity rules for these arguments are the same as those for the ``plotly_app`` template tag. If
82+
supplied, the ``postfix`` argument
83+
should already be in a slug-friendly form, as no processing is performed on it.
84+
85+
The ``plotly_class`` template tag
86+
-----------------------------------------
87+
88+
Generate a string of class names, suitable for a ``div`` or other element that wraps around ``django-plotly-dash`` template content.
89+
90+
.. code-block:: jinja
91+
92+
{%load plotly_dash%}
93+
94+
<div class="{%plotly_class slug="liveoutput-2" postfix="A"%}">
95+
{%plotly_app slug="liveoutput-2" ratio="0.5" %}
96+
</div>
97+
98+
The identifier, if the tag is not passed a ``slug``, is the result of passing the identifier of the app through
99+
the ``django.utils.text.slugify`` function.
100+
101+
The tag arguments are:
102+
103+
:name = None: The name of the application, as passed to a ``DjangoDash`` constructor.
104+
:slug = None: The slug of an existing ``DashApp`` instance.
105+
:da = None: An existing ``django_plotly_dash.models.DashApp`` model instance.
106+
:prefix = None: Optional prefix to use in place of the text ``django-plotly-dash`` in each class name
107+
:postfix = None: An optional string; if specified it is appended to the app-specific identifier with a hyphen.
108+
:template_type = None: Optional text to use in place of ``iframe`` in the template-specific class name
109+
110+
The tag inserts a string with three class names in it. One is just the ``prefix`` argument, one
111+
has the ``template_type`` appended, and the final one has the app identifier (as generated
112+
by the ``plotly_app_identifier`` tag) and any ``postfix`` appended.
113+
114+
The validity rules for these arguments are the same as those for the ``plotly_app`` and ``plotly_app_identifier`` template tags. Note
115+
that none of the ``prefix``, ``postfix`` and ``template_type`` arguments are modified and they should
116+
already be in a slug-friendly form, or otherwise fit for their intended purpose.

0 commit comments

Comments
 (0)