Skip to content

Commit c2c2039

Browse files
committed
add optional header and footer inclusion
this depends on html components having a HTML serializer, see plotly/dash-html-components#29
1 parent 811acb6 commit c2c2039

1 file changed

Lines changed: 48 additions & 6 deletions

File tree

dash/dash.py

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -283,14 +283,16 @@ def index(self, *args, **kwargs):
283283
scripts = self._generate_scripts_html()
284284
css = self._generate_css_dist_html()
285285
config = self._generate_config_html()
286-
title = getattr(self, 'title', 'Dash')
286+
custom_head_html = self._generate_head()
287+
custom_footer_html = self._generate_footer()
288+
287289
return '''
288290
<!DOCTYPE html>
289291
<html>
290292
<head>
291293
<meta charset="UTF-8">
292-
<title>{}</title>
293-
{}
294+
{component_css}
295+
{custom_head_html}
294296
</head>
295297
<body>
296298
<div id="react-entry-point">
@@ -299,12 +301,18 @@ def index(self, *args, **kwargs):
299301
</div>
300302
</div>
301303
<footer>
302-
{}
303-
{}
304+
{config}
305+
{component_scripts}
306+
{custom_footer_html}
304307
</footer>
305308
</body>
306309
</html>
307-
'''.format(title, css, config, scripts)
310+
'''.format(
311+
component_css=css,
312+
config=config,
313+
component_scripts=scripts,
314+
custom_head_html=custom_head_html,
315+
custom_footer_html=custom_footer_html)
308316

309317
def dependencies(self):
310318
return flask.jsonify([
@@ -325,6 +333,40 @@ def react(self, *args, **kwargs):
325333
'Use `callback` instead. `callback` has a new syntax too, '
326334
'so make sure to call `help(app.callback)` to learn more.')
327335

336+
def _generate_footer_or_header_html(self, footer_or_header):
337+
section = getattr(self, footer_or_header)
338+
if isinstance(section, collections.Callable):
339+
section_instance = section()
340+
else:
341+
section_instance = section
342+
343+
def convert_to_html(element):
344+
if isinstance(element, Component):
345+
element_html = element.to_html5()
346+
elif isinstance(element, basestring):
347+
element_html = element
348+
elif element is None:
349+
element_html = ''
350+
return element_html
351+
352+
if isinstance(section_instance, collections.Iterable):
353+
section_html = '\n'.join(
354+
[convert_to_html(element) for element in section_instance])
355+
else:
356+
section_html = convert_to_html(section_instance)
357+
358+
return section_html
359+
360+
def _generate_footer(self):
361+
return self._generate_footer_or_header_html('footer')
362+
363+
def _generate_head(self):
364+
head_html = self._generate_footer_or_header_html('head')
365+
if head_html == '':
366+
head_html = '<title>{}</title>'.format(
367+
getattr(self, 'title', 'Dash'))
368+
return head_html
369+
328370
def _validate_callback(self, output, inputs, state, events):
329371
layout = self._cached_layout or self._layout_value()
330372

0 commit comments

Comments
 (0)