11import sys
22import re
33
4+ from jinja2 import Environment , FileSystemLoader
5+
46from traitlets import (
57 Unicode ,
68 List ,
2527except KeyError :
2628 pass
2729
30+ #-----------------------------------------------------------------------------
31+ # Util functions and classes.
32+ #-----------------------------------------------------------------------------
2833
2934def _preparse_for_subcommand (Application , argv ):
3035 """Preparse command line to look for subcommands.
@@ -81,11 +86,52 @@ def _preparse_for_stopping_flags(Application, argv):
8186 app .exit (0 )
8287
8388
89+ class ExtensionAppJinjaMixin :
90+ """Use Jinja templates for HTML templates on top of an ExtensionApp."""
91+
92+ jinja2_options = Dict (
93+ help = _ ("""Options to pass to the jinja2 environment for this
94+ extension.
95+ """ )
96+ ).tag (config = True )
97+
98+ def _prepare_templates (self ):
99+ # Add templates to web app settings if extension has templates.
100+ if len (self .template_paths ) > 0 :
101+ self .settings .update ({
102+ "{}_template_paths" .format (self .extension_name ): self .template_paths
103+ })
104+
105+ # Create a jinja environment for logging html templates.
106+ self .jinja2_env = Environment (
107+ loader = FileSystemLoader (self .template_paths ),
108+ extensions = ['jinja2.ext.i18n' ],
109+ autoescape = True ,
110+ ** self .jinja2_options
111+ )
112+
113+ # Get templates defined in a subclass.
114+ self .initialize_templates ()
115+
116+ # Add the jinja2 environment for this extension to the tornado settings.
117+ self .settings .update (
118+ {
119+ "{}_jinja2_env" .format (self .extension_name ): self .jinja2_env
120+ }
121+ )
122+
123+ #-----------------------------------------------------------------------------
124+ # Aliases and Flags
125+ #-----------------------------------------------------------------------------
126+
84127flags ['no-browser' ]= (
85128 {'ExtensionApp' : {'open_browser' : True }},
86129 _ ("Prevent the opening of the default url in the browser." )
87130)
88131
132+ #-----------------------------------------------------------------------------
133+ # ExtensionApp
134+ #-----------------------------------------------------------------------------
89135
90136class ExtensionApp (JupyterApp ):
91137 """Base class for configurable Jupyter Server Extension Applications.
@@ -98,6 +144,9 @@ class ExtensionApp(JupyterApp):
98144 class method. This method can be set as a entry_point in
99145 the extensions setup.py
100146 """
147+ # Subclasses should override this trait. Tells the server if
148+ # this extension allows other other extensions to be loaded
149+ # side-by-side when launched directly.
101150 load_other_extensions = True
102151
103152 # Name of the extension
@@ -302,7 +351,6 @@ def _prepare_templates(self):
302351 self .settings .update ({
303352 "{}_template_paths" .format (self .extension_name ): self .template_paths
304353 })
305- self .initialize_templates ()
306354
307355 @staticmethod
308356 def initialize_server (argv = [], load_other_extensions = True , ** kwargs ):
@@ -405,5 +453,4 @@ def launch_instance(cls, argv=None, **kwargs):
405453
406454 extension = cls .load_jupyter_server_extension (serverapp , argv = args , ** kwargs )
407455 # Start the ioloop.
408- extension .start ()
409-
456+ extension .start ()
0 commit comments