Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions demo/demo/templates/demo_one.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,25 @@ <h1>Simple App Embedding</h1>
the plotly_app template tag with the name of a dash application represents the simplest use of
the django_plotly_dash framework.
</p>
<p>
The plotly_class tag is also used to wrap the application in css class names based on the
application (django-plotly-dash), the
type of the embedding (iframe), and the slugified version of the app name (simpleexample).
</p>
<div class="card bg-light border-dark">
<div class="card-body">
<p><span>{</span>% load plotly_dash %}</p>
<p><span>{</span>% plotly_app name="SimpleExample" %}</p>
<p>&lt;div class="<span>{</span>% plotly_class name="SimpleExample"%}">
<p class="ml-3"><span>{</span>% plotly_app name="SimpleExample" %}</p>
<p>&lt;\div>
</div>
</div>
<p></p>
<div class="card border-dark">
<div class="card-body">
{%plotly_app name="SimpleExample"%}
<div class="{%plotly_class name="SimpleExample"%}">
{%plotly_app name="SimpleExample"%}
</div>
</div>
</div>
{%endblock%}
Expand Down
32 changes: 29 additions & 3 deletions django_plotly_dash/dash_wrapper.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
'''dash_wrapper
'''
dash_wrapper

This module provides a DjangoDash class that can be used to
expose a Plotly Dasb application through a Django server
Expand Down Expand Up @@ -196,7 +197,7 @@ def before_first_request(self, *args, **kwargs):
pass
def run(self, *args, **kwargs):
pass
def register_blueprint(*args, **kwargs):
def register_blueprint(self, *args, **kwargs):
pass

class WrappedDash(Dash):
Expand Down Expand Up @@ -302,7 +303,7 @@ def flask_app(self):
return self._flask_app

def base_url(self):
'Base url of this omponent'
'Base url of this component'
return self._base_pathname

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

return res

def slugified_id(self):
'Return the app id in a slug-friendly form'
pre_slugified_id = self._uid
return slugify(pre_slugified_id)

def extra_html_properties(self, prefix=None, postfix=None, template_type=None):
'''
Return extra html properties to allow individual apps to be styled separately.

The content returned from this function is injected unescaped into templates.
'''

prefix = prefix if prefix else "django-plotly-dash"

post_part = "-%s" % postfix if postfix else ""
template_type = template_type if template_type else "iframe"

slugified_id = self.slugified_id()

return "%(prefix)s %(prefix)s-%(template_type)s %(prefix)s-app-%(slugified_id)s%(post_part)s" % {'slugified_id':slugified_id,
'post_part':post_part,
'template_type':template_type,
'prefix':prefix,
}
35 changes: 35 additions & 0 deletions django_plotly_dash/templatetags/plotly_dash.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,38 @@ def plotly_message_pipe(context, url=None):
'Insert script for providing background websocket connection'
url = url if url else ws_default_url
return locals()

@register.simple_tag()
def plotly_app_identifier(name=None, slug=None, da=None, postfix=None):
'Return a slug-friendly identifier'
if name is not None:
da, app = DashApp.locate_item(name, stateless=True)

if slug is not None:
da, app = DashApp.locate_item(slug, stateless=False)

if not app:
app = da.as_dash_instance()

slugified_id = app.slugified_id()

if postfix:
return "%s-%s" %(slugified_id, postfix)
return slugified_id

@register.simple_tag()
def plotly_class(name=None, slug=None, da=None, prefix=None, postfix=None, template_type=None):
'Return a string of space-separated class names'

if name is not None:
da, app = DashApp.locate_item(name, stateless=True)

if slug is not None:
da, app = DashApp.locate_item(slug, stateless=False)

if not app:
app = da.as_dash_instance()

return app.extra_html_properties(prefix=prefix,
postfix=postfix,
template_type=template_type)
60 changes: 60 additions & 0 deletions docs/template_tags.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,63 @@ on the page, and its ordering relative to the ``Dash`` instances using updating
the page footer - to avoid delaying the main page load - along
with other scripts is generally advisable.

The ``plotly_app_identifier`` template tag
-----------------------------------------

This tag provides an identifier for an app, in a form that is suitable for use as a classname or identifier
in HTML:

.. code-block:: jinja

{%load plotly_dash%}

{%plotly_app_identifier name="SimpleExample"%}

{%plotly_app_identifier slug="liveoutput-2" postfix="A"%}

The identifier, if the tag is not passed a ``slug``, is the result of passing the identifier of the app through
the ``django.utils.text.slugify`` function.

The tag arguments are:

:name = None: The name of the application, as passed to a ``DjangoDash`` constructor.
:slug = None: The slug of an existing ``DashApp`` instance.
:da = None: An existing ``django_plotly_dash.models.DashApp`` model instance.
:postfix = None: An optional string; if specified it is appended to the identifier with a hyphen.

The validity rules for these arguments are the same as those for the ``plotly_app`` template tag. If
supplied, the ``postfix`` argument
should already be in a slug-friendly form, as no processing is performed on it.

The ``plotly_class`` template tag
-----------------------------------------

Generate a string of class names, suitable for a ``div`` or other element that wraps around ``django-plotly-dash`` template content.

.. code-block:: jinja

{%load plotly_dash%}

<div class="{%plotly_class slug="liveoutput-2" postfix="A"%}">
{%plotly_app slug="liveoutput-2" ratio="0.5" %}
</div>

The identifier, if the tag is not passed a ``slug``, is the result of passing the identifier of the app through
the ``django.utils.text.slugify`` function.

The tag arguments are:

:name = None: The name of the application, as passed to a ``DjangoDash`` constructor.
:slug = None: The slug of an existing ``DashApp`` instance.
:da = None: An existing ``django_plotly_dash.models.DashApp`` model instance.
:prefix = None: Optional prefix to use in place of the text ``django-plotly-dash`` in each class name
:postfix = None: An optional string; if specified it is appended to the app-specific identifier with a hyphen.
:template_type = None: Optional text to use in place of ``iframe`` in the template-specific class name

The tag inserts a string with three class names in it. One is just the ``prefix`` argument, one
has the ``template_type`` appended, and the final one has the app identifier (as generated
by the ``plotly_app_identifier`` tag) and any ``postfix`` appended.

The validity rules for these arguments are the same as those for the ``plotly_app`` and ``plotly_app_identifier`` template tags. Note
that none of the ``prefix``, ``postfix`` and ``template_type`` arguments are modified and they should
already be in a slug-friendly form, or otherwise fit for their intended purpose.