-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
allow optional header and footer #171
Conversation
this depends on html components having a HTML serializer, see plotly/dash-html-components#29
Relevant community forum threads that this PR would solve:
Many thanks to the dash community for these feature requests and discussions ❤️ |
I really like this; it opens up quite a lot of flexibility. The main thought I have is that it's likely that a common use case will be adding one or more CSS files as tags and nothing else, in which case there's a bit of overhead in creating a list of potentially multiple |
Question: If the resources linked by @app.server.route('/static/<path:path>')
def static_file(path):
static_folder = os.path.join(os.getcwd(), 'static')
return send_from_directory(static_folder, path) If yes, could that be more obvious in the documentation? |
It is still necessary and yes, we should make it more obvious :) |
Thanks @chriddyp ! Do you need to use the below options if using local scripts? (taken from this example) app.css.config.serve_locally = True
app.scripts.config.serve_locally = True |
This would no longer conflict. Whatever you specify in app.head = [
html.Link(
href='https://codepen.io/chriddyp/pen/bWLwgP.css',
rel='stylesheet'
),
html.Link(
href='/static/my-local-stylesheet.css',
rel='stylesheet'
),
] With this addition, we would remove the |
This commit seems very useful. However, I recieved the error below when trying this out. My test implied pasting: app.head = [ into the first app example in: This gave me the error below. Am I missing something. Any ideas? 127.0.0.1 - - [05/Dec/2017 09:20:39] "GET / HTTP/1.1" 500 - |
We did something similar - we subclassed from Dash to override index() to use our own "template.html" file. Wouldn't ability to pass a custom html template string be more generic, compared to .head() and .footer() methods? I'd like to stay within Python as much as any other pythonista, but ability to just copy-paste some html/js/css is tempting, given how easy it is. Or may be we can have both..? |
yeah we're also overriding the default |
Adding a custom CSS stylesheet seems like a fairly common need though yeah?
Although I guess it's possible many people are just using inline styles. I
would be frustrated by this, but I gather that there are a lot of people
taking to Dash who don't have prior web dev experience.
…On Tue, 12 Dec 2017 at 01:29 Eugene Yunak ***@***.***> wrote:
yeah we're also overriding the default index(). that said, i think it's
unnecessary for most users and those advanced enough to require it can
easily subclass, no?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#171 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ACs1GCTwG3PW3XLEXWlZ1WSODGw1yPlcks5s_TxLgaJpZM4QxLbO>
.
|
Overriding the index method has the drawback of having to know the internals of that method and replicating the logic in the derived class. It works for now but I would also be up for a proper API directly exposed by Dash. |
will it be merged at some point? |
@21stio it looks like the CI build failed when it was merged in @chriddyp can you take a look? I was looking for exactly this feature; it looks like its failing on a Python 3 compatibility with basestring. |
def convert_to_html(element): | ||
if isinstance(element, Component): | ||
element_html = element.to_html5() | ||
elif isinstance(element, basestring): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
failing in python3. need:
from past.builtins import basestring # pip install future
I love Dash but as a data scientist with no CSS experience this whole CSS thing is very frustrating particularly when there are no clear examples of how use local CSS files. In R Shiny stuff just works and don have to worry about style sheets. But I prefer Python and was hoping Dash could be my salvation. I want to recreate this bootstrap demo (https://getbootstrap.com/docs/4.0/examples/dashboard/) in Dash but cant get past the first hurdle of using the appropriate CSS's. This or a simple demo showing how to use different CSS locally would be great. |
@ploncker - Could you please open this issue in the community forum? I'd like to reserve comments in this PR about the actual PR. For example, see https://community.plot.ly/t/how-do-i-use-dash-to-add-local-css/4914/22 or https://community.plot.ly/t/serve-locally-option-with-additional-scripts-and-style-sheets/6974/6?u=chriddyp. |
@chriddyp - I've just come across this and it would be great for a number of reasons:
I have currently worked around this with the following monkey patch: import dash_renderer, six, types # noqa
def _generate_css_dist_html(self):
links = self._collect_and_register_resources(self.css.get_all_css())
return '\n'.join('<link rel="stylesheet" {}>'.format(' '.join('{}="{}"'.format(k, v) for k, v in (
[('href', link)] if isinstance(link, six.string_types) else sorted(link.items())
))) for link in links)
def _generate_scripts_html(self):
srcs = self._collect_and_register_resources(
self.scripts._resources._filter_resources(dash_renderer._js_dist_dependencies) +
self.scripts.get_all_scripts() +
self.scripts._resources._filter_resources(dash_renderer._js_dist),
)
return '\n'.join('<script {}></script>'.format(' '.join('{}="{}"'.format(k, v) for k, v in (
[('src', src)] if isinstance(src, six.string_types) else sorted(src.items())
))) for src in srcs)
# XXX: Temporary hack to allow attributes on <link> and <script>.
# See https://github.com/plotly/dash/pull/171 for alternate solution in development.
app._generate_css_dist_html = types.MethodType(_generate_css_dist_html, app)
app._generate_scripts_html = types.MethodType(_generate_scripts_html, app) This allows me to do something like the following: app.css.append_css({'external_url': (
{'href': '/static/fds/less/default.less', 'type': 'text/less'},
)})
app.scripts.append_script({'external_url': (
{
'src': 'https://unpkg.com/less@2.7.2/dist/less.min.js',
'integrity': 'sha384-tNVWZNCzgnTSr8HLSfGS6L7pO03KOgRXJsprbx6bitch1BMri1brpoPxtyY4pDqn',
'crossorigin': 'anonymous',
},
)}) While these changes may not seem necessary because of the proposed changes in this PR, they are still worth considering as it would also benefit adding subresource integrity hashes to the dependencies added by What are your thoughts? |
This is really good feedback. In some separate discussions with @nicolaskruchten , we discussed how this method obscures things about how Dash's components work: suddenly only some components could work in Taking this feedback, I propose 2 solutions for adding local CSS and JS to apps in #265. Let's continue the discussion there! |
it seems no any change when i try to change the favicon. app.head = [
html.Link(
href='https://www.sportsingapore.gov.sg/SSC.png',
rel='icon'
),
] |
I ran into this PR trying to add social media tags to a dash app (https://css-tricks.com/essential-meta-tags-social-media/ for instance). It would have nicely solved my need. |
@GaelVaroquaux this can be done using the solution linked above #265 which was implemented in #286 ... The docs are here https://dash.plot.ly/external-resources under "Customizing Dash's HTML Index Template" |
@nicolaskruchten : that's exactly what I was looking for. I somehow missed it in the thread above. Thanks a lot!! |
You're welcome! We should try to get more into the habit of coming back to old issues and posting a "canonical response" like this, to ensure no one is left behind :) Thanks for pinging us on this one! |
Actually, the challenge is that the beautiful solution that I was looking for was somewhat at the bottom of the page, so I didn't see it at first look on that page. I've been asking for a templating engine for dash for a few days, I finally found it :). |
use dash loosen-testing-reqs branch and fix linting
use dash loosen-testing-reqs branch and fix linting
This PR depends on html components having a HTML serializer, see
plotly/dash-html-components#29
This PR simplifies adding custom JavaScript and CSS to Dash apps - a more flexible and declarative alternative to
app.css.append_css
andapp.scripts.append_script
Example usage:
app.head
andapp.footer
can also be functions, which enables setting variables dynamically based off of the URL (i.e. unique page titles)Unlike
app.layout
,app.head
andapp.footer
are templated directly into the HTML (as HTML!) rather than generated in Dash’s front-end. This allows the components to be rendered immediately on page load rather than after page load (required for things like page title and meta descriptions and for preventing a “Flash of Unstyled Content” https://en.wikipedia.org/wiki/Flash_of_unstyled_content).This makes the components in
app.head
andapp.footer
different than the components inapp.layout
. In particular:app.head
orapp.footer
dash_html_components
can be applied to theapp.head
andapp.footer
as these are the only valid HTML tags (a `dash_core_components.Graph is not a valid HTML tag, it’s a rich component generated by React.js with dynamic javascript and CSS)Fixes ##170 and several issues brought up in the dash community forum (https://community.plot.ly/c/dash)