Skip to content

Commit

Permalink
Merge pull request #305 from plotly/add-js-css-init
Browse files Browse the repository at this point in the history
Add `external_js/css_urls` to dash init.
  • Loading branch information
T4rk1n authored Aug 2, 2018
2 parents e3a5486 + 4934c7f commit 1f27bac
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 12 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.23.1 - 2018-08-02
## Added
- Add ie-compat meta tag to the index by default. [#316](https://github.com/plotly/dash/pull/316)
- Add `external_script` and `external_css` keywords to dash `__init__`. [#305](https://github.com/plotly/dash/pull/305)

## 0.23.0 - 2018-08-01
## Added
- Dash components are now generated at build-time and then imported rather than generated when a module is imported. This should reduce the time it takes to import Dash component libraries, and makes Dash compatible with IDEs.
Expand Down
14 changes: 14 additions & 0 deletions dash/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ def interpolate_str(template, **data):
return s


def format_tag(tag_name, attributes, inner='', closed=False, opened=False):
tag = '<{tag} {attributes}'
if closed:
tag += '/>'
elif opened:
tag += '>'
else:
tag += '>' + inner + '</{tag}>'
return tag.format(
tag=tag_name,
attributes=' '.join([
'{}="{}"'.format(k, v) for k, v in attributes.items()]))


class AttributeDict(dict):
"""
Dictionary subclass enabling attribute lookup/assignment of keys/values.
Expand Down
32 changes: 22 additions & 10 deletions dash/dash.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from . import exceptions
from ._utils import AttributeDict as _AttributeDict
from ._utils import interpolate_str as _interpolate
from ._utils import format_tag as _format_tag

_default_index = '''
<!DOCTYPE html>
Expand Down Expand Up @@ -61,7 +62,7 @@


# pylint: disable=too-many-instance-attributes
# pylint: disable=too-many-arguments
# pylint: disable=too-many-arguments, too-many-locals
class Dash(object):
def __init__(
self,
Expand All @@ -75,6 +76,8 @@ def __init__(
compress=True,
meta_tags=None,
index_string=_default_index,
external_scripts=None,
external_stylesheets=None,
**kwargs):

# pylint-disable: too-many-instance-attributes
Expand Down Expand Up @@ -128,6 +131,10 @@ def _handle_error(error):
# static files from the packages
self.css = Css()
self.scripts = Scripts()

self._external_scripts = external_scripts or []
self._external_stylesheets = external_stylesheets or []

self.registered_paths = {}

# urls
Expand Down Expand Up @@ -302,9 +309,12 @@ def _relative_url_path(relative_package_path='', namespace=''):
def _generate_css_dist_html(self):
links = self._collect_and_register_resources(
self.css.get_all_css()
)
) + self._external_stylesheets

return '\n'.join([
'<link rel="stylesheet" href="{}">'.format(link)
_format_tag('link', link, opened=True)
if isinstance(link, dict)
else '<link rel="stylesheet" href="{}">'.format(link)
for link in links
])

Expand All @@ -325,9 +335,12 @@ def _generate_scripts_html(self):
dash_renderer._js_dist
)
)
srcs = srcs[:-1] + self._external_scripts + [srcs[-1]]

return '\n'.join([
'<script src="{}"></script>'.format(src)
_format_tag('script', src)
if isinstance(src, dict)
else '<script src="{}"></script>'.format(src)
for src in srcs
])

Expand All @@ -348,12 +361,11 @@ def _generate_meta_html(self):
if not has_ie_compat:
tags.append('<meta equiv="X-UA-Compatible" content="IE=edge">')
if not has_charset:
tags.append('<meta charset="UTF-8">')
for meta in self._meta_tags:
attributes = []
for k, v in meta.items():
attributes.append('{}="{}"'.format(k, v))
tags.append('<meta {}>'.format(' '.join(attributes)))
tags.append('<meta charset="UTF-8"/>')

tags = tags + [
_format_tag('meta', x, opened=True) for x in self._meta_tags
]

return '\n '.join(tags)

Expand Down
2 changes: 1 addition & 1 deletion dash/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.23.0'
__version__ = '0.23.1'
37 changes: 36 additions & 1 deletion tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -434,4 +434,39 @@ def will_raise():
self.assertTrue('{%config%}' in exc_msg)
self.assertTrue('{%scripts%}' in exc_msg)
time.sleep(0.5)
print('invalid index string')

def test_external_files_init(self):
js_files = [
'https://www.google-analytics.com/analytics.js',
{'src': 'https://cdn.polyfill.io/v2/polyfill.min.js'},
{
'src': 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.core.js',
'integrity': 'sha256-Qqd/EfdABZUcAxjOkMi8eGEivtdTkh3b65xCZL4qAQA=',
'crossorigin': 'anonymous'
}
]
css_files = [
'https://codepen.io/chriddyp/pen/bWLwgP.css',
{
'href': 'https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css',
'rel': 'stylesheet',
'integrity': 'sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO',
'crossorigin': 'anonymous'
}
]

app = dash.Dash(
external_scripts=js_files, external_stylesheets=css_files)

app.layout = html.Div()

self.startServer(app)
time.sleep(0.5)

js_urls = [x['src'] if isinstance(x, dict) else x for x in js_files]
css_urls = [x['href'] if isinstance(x, dict) else x for x in css_files]

for fmt, url in itertools.chain(
(("//script[@src='{}']", x) for x in js_urls),
(("//link[@href='{}']", x) for x in css_urls)):
self.driver.find_element_by_xpath(fmt.format(url))

0 comments on commit 1f27bac

Please sign in to comment.