You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Most of the examples I have seen rely on building the entire HTML front end via the python interface. Is there a way to use a pre-defined HTML5 template and substitute the graphs in there?
This way one can prototype the interface independently of the dash logic.
Since Plotly dash is built on flask, any chance jinja2 templating will be
in the works?
On Sun, Jun 25, 2017 at 11:59 PM Zafarali Ahmed ***@***.***> wrote:
Most of the examples I have seen rely on building the entire HTML front
end via the python interface. Is there a way to use a pre-defined HTML5
template and substitute the graphs in there?
This way one can prototype the interface independently of the dash logic.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#44>, or mute the thread
<https://github.com/notifications/unsubscribe-auth/AF1yH8Nbtf1nOwkXmyHkKPkKitQBZIzrks5sHyyegaJpZM4OE2k0>
.
--
Cedric Yau
cedricyau@gmail.com
Reacted by Jason K. Moore, Artificer, tomwarrens, scott corley and Maz
There isn't any plan to do this right now. While the dash_html_components components render themselves directly as html components, the dash_core_components components can't be rendered with just HTML tags (unless we switched them to web components). This limits the extent to which a Dash app could be mocked up entirely in HTML.
Writing web markup with Python classes may seem pretty odd at first, but there are actually a lot of really great things that you can do it with it:
You can use list concatenation and python code to generate markup. This markup can be reused and imported in other Dash programs. For example, see the Table example in the getting started section. You could write a generic app.layout template in Dash and then re-use it in the rest of your projects or share it with your team members (since it's just Python code)
You can easily embed in real data into your prototypes. Tables made out of DataFrames, Dropdowns populated with the unique values of a DataFrame column or the column names, a graph with real data, etc.
This way one can prototype the interface independently of the dash logic.
The "logic" of a Dash app is separated from the initial "view" of the app already. The app's app.layout property defines what the app looks like, and the app.callbacks define the logic of the app, or how the app responds to changes.
Another note - one could also write a Dash component that takes a raw HTML string and renders it with React's dangerouslySetInnerHTML. It could look something like:
RawHTML('''
<table>
[...]
</table>
''')
and then if you wanted Jinja templating, you could run your string through Jinja before passing into the component, like:
I would argue its extremely useful to be able to generate HTML using other means than just dash_html_components. I'm personally not a fan of templates such as Jinja, but I do love the dominate library. Its syntax is concise and the use of with keyword makes your code much more elegant and readable than the current approach of dash_html_components. If I had to design something similar to Dash from scratch, I would certainly try to build on top of dominate (basically just extend it to allow plugging in dash_core_components and other things).
Apart from these aesthetic considerations, dash_html_components enforces some unreasonable restrictions on the allowed set of HTML element attributes, This does not make sense in a modern web front-end development where almost every fancy library requires you to set some custom HTML attributes. The only way I can get around it is by adding the attributes using javascript on the client side... I do not see the point in these restrictions. That's great that Dash allows you to do a lot with just Python, but I don't see why it should restrict you if you want to do more with 3rd party client-side libraries,
TL;DR I do think it should be possible to plug in HTML code generated elsewhere into Dash. Seamless support for dominate would be awesome, but even just the RawHTML suggested above is good enough because it'll get the job done.
Reacted by javValverde, Peter Desmet, Mike DePalatis, ndebrabander, AnjunaGlobal, Rob Kimball, Thomas Thelen, codeit, Jose Magana, Eric and 6 more
one alternative might be to ditch dash for just flask and plotly (which are core components of dash anyway) and build on top of that. back in the days @chriddyp showed us how it's done here.
I ran into this myself on a personal project where I wanted to render HTML from a third-party source and converting it to the dash-html-components library would've been too complex.
I still stand by the belief that dash-html-components is a great way to render complex HTML as you are writing code in Python. This automatically provides us with:
Flexible, powerful templating (since it's just Python)
Reusable, portable components (since you can encapsulate components as functions and import them)
Further, you can easily re-use components that you have created since it's just regular Python!
dash_html_components enforces some unreasonable restrictions on the allowed set of HTML element attributes,
As far as I'm aware, this is just related to Dash not currently supporting data-* and aria-* attributes. This is more of a bug than a limitation, and it will be supported in the future.
@chriddyp, if I understand you correctly, what you say about Reusable, portable components and Nice argument validation refers mostly to dash_core_components (especially the former), i.e. Python wrappers for React components. And this is of course really valuable and is basically the reason I use Dash,
My point, however, is that writing plain HTML is way too verbose with dash_html_components. In my view, both Jinja2 and dominate library provide more elegant way to template your HTML code. Dash is great for simple MI (Tableau-like) tasks, but as soon as you need something more complex it starts getting in your way.
Imagine a complex web app where you'd like to use a few Plotly graphs here and there. And suppose you want the cross-filtering on those graphs, which is a breeze with Dash. But because the graphs are scattered over distant parts of your HTML DOM, it forces you to implement the whole DOM structure via dash_html_components (whereas what you really want is to simply inject a few Dash Core Components in various places of you web app). Another example is where you have two unrelated pieces on the same page which are most easily implemented with Dash, but again, these pieces are located in completely different parts of DOM. And no, iframe is not a good solution to this. It is not even a feasible solution in the first case, and is a very poor solution to the second one. SEO considerations aside, I often want to interact with Dash part of my web app from outside (i.e. from plain javascript), and I want to do it directly without the need for postMessage etc.
I'm not too familiar with React, but let me summarize why I think dash_html_components exist:
We need to have a single top-level React component (in Dash front-end)
It is nice to have the ability to modify any part of your HTML markup through Dash Python callbacks/React,
After brief googling I came across the project aknuds1/html-to-react which seems like it could be solution to this problem. I can imagine the following workflow (I'm going to use Jinja2 as an example, but this would allow us to create HTML markup any way we like, including e.g. dominate):
I write a Jinja2 template which is a mixture regular Flask HTML templating and dash_core_components. Where a Dash Core Component gets injected into the HTML the following happens:
a) It returns simple div with a unique id, such as <div id='dash-core-component-wldjakle'>
b) The actual Dash Component (which is what is currently being returned) is simply stored somewhere in Dash application instance.
As a result, the layout is no longer a hierarchy of Components, but rather a plain HTML string.
When the response is sent back to Dash front-end, it contains the following:
a) The string with layout HTML which we discussed above
b) All Components which we have stored in Dash application, serialized to JSON - this is similar to what the current rendering method returns, but instead of creating a large nested object, it would just be a list of components.
The following would happen on the front-end:
a) HTML string gets parsed with aknuds1/html-to-react library (it's easy to convert it from a Node module to plain javascript with e.g. Browserify or Webpack). It creates React DOM structure.
b) All Dash Core Components can be injected into this DOM structure by replacing their placeholder divs (which can be identified by unique ids).
Unless I'm missing something, as a result of this we'd get the same React DOM structure as we currently do. We satisfy both initial requirements - we still have just one top-level React component, and all plain HTML elements are part of React system, so could be easily interacted with from Dash Python callbacks.
Only other thing I can think of which is currently done on Python side is validation of all component ids between registered callbacks and layout. While no longer possible to do on the Python side (unless you parse HTML to DOM with e.g. lxml parser, which is also easy enough), it could be easily done on front-end side once html is converted to React DOM.
I've described what happens with initial layout, but the exact same thing could be applied to Dash callbacks which return children for some element.
With this approach you no longer need dash_html_components at all, so one less thing to maintain. If you want to generate DOM in Python, just use dominate - it's more elegant, flexible and very mature/robust. If you want to preserve backwards compatibility you could keep dash_html_components interface and just make it use dominate underneath (which should be extremely trivial).
Finally, not related to the above - for those who are happy to use dash_html_components, it would still be really handy if they supported with syntax similar to dominate - it would make the code much more compact, elegant and readable.
Reacted by Tim Stallmann, cnblevins, AnjunaGlobal, nirvana-msu, ÓscarGF, Jason K. Moore, codeit, Robin Du, Artificer, Isaac Backus and 12 more
It is just a proof-of-concept that could benefit a lot from the ideas above. My original idea was to be able to inject Dash components into Jinja templates but I ended up specifying my own sort of "templating format".
Reacted by miraculixx, Gang Chen, Eric, Niko Föhr and Maz
I totally agree with @nirvana-msu. Yes, we do have dash-html-components, which is pretty handy at creating html components. But what about html structure? As far as I can see, most of the show and tell projects are merely "stacks" of html components. How do we control the structure of our application? In the layout page of your tutorial, I can only find out a layout that is controlled by style={'columnCount': 2}. What if we need more than this?
On my current project, I want to add bootstrap support for the application. This is the part of the code for a corner of the page:
This is almost HTML, but you have to close all tags (but <hr /> is recognized), attributes can take Python values, and you can embed Python code. It gets compiled into a sequence of calls to Dash constructor functions (html.Div(className='content', children=[html.Div(...)])).
One use case for raw HTML is to generate an interactive (e.g. clickable) SVG canvas and integrate it. From what I see, this is completely impossible at the moment.
Activity
cedricyau commentedon Jun 26, 2017
chriddyp commentedon Jun 26, 2017
There isn't any plan to do this right now. While the
dash_html_componentscomponents render themselves directly as html components, thedash_core_componentscomponents can't be rendered with just HTML tags (unless we switched them to web components). This limits the extent to which a Dash app could be mocked up entirely in HTML.Writing web markup with Python classes may seem pretty odd at first, but there are actually a lot of really great things that you can do it with it:
app.layouttemplate in Dash and then re-use it in the rest of your projects or share it with your team members (since it's just Python code)The "logic" of a Dash app is separated from the initial "view" of the app already. The app's
app.layoutproperty defines what the app looks like, and theapp.callbacksdefine the logic of the app, or how the app responds to changes.chriddyp commentedon Jun 26, 2017
Closing this for now since it's not on the immediate roadmap, but certainly always happy to hear more thoughts or feedback :)
chriddyp commentedon Jun 30, 2017
Another note - one could also write a Dash component that takes a raw HTML string and renders it with React's
dangerouslySetInnerHTML. It could look something like:and then if you wanted Jinja templating, you could run your string through Jinja before passing into the component, like:
Here's how to create custom components in Dash: https://plot.ly/dash/plugins.
nirvana-msu commentedon Oct 13, 2017
I would argue its extremely useful to be able to generate HTML using other means than just
dash_html_components. I'm personally not a fan of templates such asJinja, but I do love the dominate library. Its syntax is concise and the use ofwithkeyword makes your code much more elegant and readable than the current approach ofdash_html_components. If I had to design something similar to Dash from scratch, I would certainly try to build on top ofdominate(basically just extend it to allow plugging indash_core_componentsand other things).Apart from these aesthetic considerations,
dash_html_componentsenforces some unreasonable restrictions on the allowed set of HTML element attributes, This does not make sense in a modern web front-end development where almost every fancy library requires you to set some custom HTML attributes. The only way I can get around it is by adding the attributes using javascript on the client side... I do not see the point in these restrictions. That's great that Dash allows you to do a lot with just Python, but I don't see why it should restrict you if you want to do more with 3rd party client-side libraries,TL;DR I do think it should be possible to plug in HTML code generated elsewhere into Dash. Seamless support for
dominatewould be awesome, but even just theRawHTMLsuggested above is good enough because it'll get the job done.adrianoesch commentedon Dec 4, 2017
one alternative might be to ditch dash for just flask and plotly (which are core components of dash anyway) and build on top of that. back in the days @chriddyp showed us how it's done here.
chriddyp commentedon Dec 7, 2017
I ran into this myself on a personal project where I wanted to render HTML from a third-party source and converting it to the
dash-html-componentslibrary would've been too complex.I have created a
DangerouslySetInnerHTMLcomponent that you can use now https://github.com/plotly/dash-dangerously-set-inner-html. However, I recommend using thedash-html-componentsas much as possible.I still stand by the belief that
dash-html-componentsis a great way to render complex HTML as you are writing code in Python. This automatically provides us with:For example, conditional formatting a table to create a component like

is trivial (see https://community.plot.ly/t/coloured-text-in-a-table-conditional-formatting/7112/8?u=chriddyp)
Further, you can easily re-use components that you have created since it's just regular Python!
As far as I'm aware, this is just related to Dash not currently supporting
data-*andaria-*attributes. This is more of a bug than a limitation, and it will be supported in the future.nirvana-msu commentedon Jan 3, 2018
@chriddyp, if I understand you correctly, what you say about
Reusable, portable componentsandNice argument validationrefers mostly todash_core_components(especially the former), i.e. Python wrappers for React components. And this is of course really valuable and is basically the reason I use Dash,My point, however, is that writing plain HTML is way too verbose with
dash_html_components. In my view, bothJinja2anddominatelibrary provide more elegant way to template your HTML code. Dash is great for simple MI (Tableau-like) tasks, but as soon as you need something more complex it starts getting in your way.Imagine a complex web app where you'd like to use a few
Plotlygraphs here and there. And suppose you want the cross-filtering on those graphs, which is a breeze with Dash. But because the graphs are scattered over distant parts of your HTML DOM, it forces you to implement the whole DOM structure viadash_html_components(whereas what you really want is to simply inject a few Dash Core Components in various places of you web app). Another example is where you have two unrelated pieces on the same page which are most easily implemented with Dash, but again, these pieces are located in completely different parts of DOM. And no,iframeis not a good solution to this. It is not even a feasible solution in the first case, and is a very poor solution to the second one. SEO considerations aside, I often want to interact with Dash part of my web app from outside (i.e. from plain javascript), and I want to do it directly without the need forpostMessageetc.I'm not too familiar with React, but let me summarize why I think
dash_html_componentsexist:After brief googling I came across the project aknuds1/html-to-react which seems like it could be solution to this problem. I can imagine the following workflow (I'm going to use
Jinja2as an example, but this would allow us to create HTML markup any way we like, including e.g.dominate):Jinja2template which is a mixture regular Flask HTML templating anddash_core_components. Where a Dash Core Component gets injected into the HTML the following happens:a) It returns simple div with a unique id, such as
<div id='dash-core-component-wldjakle'>b) The actual Dash Component (which is what is currently being returned) is simply stored somewhere in Dash application instance.
As a result, the
layoutis no longer a hierarchy of Components, but rather a plain HTML string.When the response is sent back to Dash front-end, it contains the following:
a) The string with layout HTML which we discussed above
b) All Components which we have stored in Dash application, serialized to JSON - this is similar to what the current rendering method returns, but instead of creating a large nested object, it would just be a list of components.
The following would happen on the front-end:
a) HTML string gets parsed with aknuds1/html-to-react library (it's easy to convert it from a Node module to plain javascript with e.g. Browserify or Webpack). It creates React DOM structure.
b) All Dash Core Components can be injected into this DOM structure by replacing their placeholder divs (which can be identified by unique ids).
Unless I'm missing something, as a result of this we'd get the same React DOM structure as we currently do. We satisfy both initial requirements - we still have just one top-level React component, and all plain HTML elements are part of React system, so could be easily interacted with from Dash Python callbacks.
Only other thing I can think of which is currently done on Python side is validation of all component ids between registered callbacks and layout. While no longer possible to do on the Python side (unless you parse HTML to DOM with e.g.
lxmlparser, which is also easy enough), it could be easily done on front-end side once html is converted to React DOM.I've described what happens with initial layout, but the exact same thing could be applied to Dash callbacks which return
childrenfor some element.With this approach you no longer need
dash_html_componentsat all, so one less thing to maintain. If you want to generate DOM in Python, just usedominate- it's more elegant, flexible and very mature/robust. If you want to preserve backwards compatibility you could keepdash_html_componentsinterface and just make it usedominateunderneath (which should be extremely trivial).Finally, not related to the above - for those who are happy to use
dash_html_components, it would still be really handy if they supportedwithsyntax similar todominate- it would make the code much more compact, elegant and readable.masdeseiscaracteres commentedon Apr 15, 2018
I wrote something to address this very same concern:
https://github.com/masdeseiscaracteres/dash-html-template
It is just a proof-of-concept that could benefit a lot from the ideas above. My original idea was to be able to inject Dash components into Jinja templates but I ended up specifying my own sort of "templating format".
ssword commentedon May 8, 2018
I totally agree with @nirvana-msu. Yes, we do have dash-html-components, which is pretty handy at creating html components. But what about html structure? As far as I can see, most of the show and tell projects are merely "stacks" of html components. How do we control the structure of our application? In the layout page of your tutorial, I can only find out a layout that is controlled by
style={'columnCount': 2}. What if we need more than this?On my current project, I want to add bootstrap support for the application. This is the part of the code for a corner of the page:
I am new to this, maybe I am on the wrong track, but I don't know how else I can do it.
rvsingh011 commentedon Jul 25, 2018
Same problem, When we want a full fledged application. We need a lot of html.
jkseppan commentedon Apr 20, 2019
Here's my attempt at turning an HTML-like language with embedded Python into calls to Dash constructors: https://github.com/jkseppan/htexpr/
With that you can write @ssword's example like this:
This is almost HTML, but you have to close all tags (but
<hr />is recognized), attributes can take Python values, and you can embed Python code. It gets compiled into a sequence of calls to Dash constructor functions (html.Div(className='content', children=[html.Div(...)])).Forum post: https://community.plot.ly/t/htexpr-write-dash-layouts-in-html-syntax/21669
add test of #44
amitripshtos commentedon Apr 13, 2020
Great work @jkseppan, really helpful for me since writing HTML is much faster for me.
commit generated files to the repo (plotly#44)
commit generated files to the repo (plotly#44)
commit generated files to the repo (#44)
SarenT commentedon Sep 29, 2025
One use case for raw HTML is to generate an interactive (e.g. clickable) SVG canvas and integrate it. From what I see, this is completely impossible at the moment.