@@ -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