1
1
import sys
2
2
import re
3
3
4
+ from jinja2 import Environment , FileSystemLoader
5
+
4
6
from traitlets import (
5
7
Unicode ,
6
8
List ,
25
27
except KeyError :
26
28
pass
27
29
30
+ #-----------------------------------------------------------------------------
31
+ # Util functions and classes.
32
+ #-----------------------------------------------------------------------------
28
33
29
34
def _preparse_for_subcommand (Application , argv ):
30
35
"""Preparse command line to look for subcommands.
@@ -81,11 +86,52 @@ def _preparse_for_stopping_flags(Application, argv):
81
86
app .exit (0 )
82
87
83
88
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
+
84
127
flags ['no-browser' ]= (
85
128
{'ExtensionApp' : {'open_browser' : True }},
86
129
_ ("Prevent the opening of the default url in the browser." )
87
130
)
88
131
132
+ #-----------------------------------------------------------------------------
133
+ # ExtensionApp
134
+ #-----------------------------------------------------------------------------
89
135
90
136
class ExtensionApp (JupyterApp ):
91
137
"""Base class for configurable Jupyter Server Extension Applications.
@@ -98,6 +144,9 @@ class ExtensionApp(JupyterApp):
98
144
class method. This method can be set as a entry_point in
99
145
the extensions setup.py
100
146
"""
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.
101
150
load_other_extensions = True
102
151
103
152
# Name of the extension
@@ -302,7 +351,6 @@ def _prepare_templates(self):
302
351
self .settings .update ({
303
352
"{}_template_paths" .format (self .extension_name ): self .template_paths
304
353
})
305
- self .initialize_templates ()
306
354
307
355
@staticmethod
308
356
def initialize_server (argv = [], load_other_extensions = True , ** kwargs ):
@@ -405,5 +453,4 @@ def launch_instance(cls, argv=None, **kwargs):
405
453
406
454
extension = cls .load_jupyter_server_extension (serverapp , argv = args , ** kwargs )
407
455
# Start the ioloop.
408
- extension .start ()
409
-
456
+ extension .start ()
0 commit comments