diff --git a/IPython/html/__init__.py b/IPython/html/__init__.py
index 97e2c984b..a58d48267 100644
--- a/IPython/html/__init__.py
+++ b/IPython/html/__init__.py
@@ -4,6 +4,22 @@ import os
# Packagers: modify this line if you store the notebook static files elsewhere
DEFAULT_STATIC_FILES_PATH = os.path.join(os.path.dirname(__file__), "static")
+# Packagers: modify the next line if you store the notebook template files
+# elsewhere
+
+# Include both IPython/html/ and IPython/html/templates/. This makes it
+# possible for users to override a template with a file that inherits from that
+# template.
+#
+# For example, if you want to override a specific block of notebook.html, you
+# can create a file called notebook.html that inherits from
+# templates/notebook.html, and the latter will resolve correctly to the base
+# implementation.
+DEFAULT_TEMPLATE_PATH_LIST = [
+ os.path.dirname(__file__),
+ os.path.join(os.path.dirname(__file__), "templates"),
+]
+
del os
-from .nbextensions import install_nbextension
\ No newline at end of file
+from .nbextensions import install_nbextension
diff --git a/IPython/html/notebookapp.py b/IPython/html/notebookapp.py
index bf7f4f8d5..b6b41bb53 100644
--- a/IPython/html/notebookapp.py
+++ b/IPython/html/notebookapp.py
@@ -51,7 +51,10 @@ from tornado import httpserver
from tornado import web
from tornado.log import LogFormatter, app_log, access_log, gen_log
-from IPython.html import DEFAULT_STATIC_FILES_PATH
+from IPython.html import (
+ DEFAULT_STATIC_FILES_PATH,
+ DEFAULT_TEMPLATE_PATH_LIST,
+)
from .base.handlers import Template404
from .log import log_request
from .services.kernels.kernelmanager import MappingKernelManager
@@ -138,7 +141,10 @@ class NotebookWebApplication(web.Application):
log, base_url, default_url, settings_overrides,
jinja_env_options=None):
- _template_path = settings_overrides.get("template_path", os.path.join(os.path.dirname(__file__), "templates"))
+ _template_path = settings_overrides.get(
+ "template_path",
+ ipython_app.template_file_path,
+ )
if isinstance(_template_path, str):
_template_path = (_template_path,)
template_path = [os.path.expanduser(path) for path in _template_path]
@@ -519,7 +525,20 @@ class NotebookApp(BaseIPythonApplication):
def static_file_path(self):
"""return extra paths + the default location"""
return self.extra_static_paths + [DEFAULT_STATIC_FILES_PATH]
-
+
+ extra_template_paths = List(Unicode, config=True,
+ help="""Extra paths to search for serving jinja templates.
+
+ Can be used to override templates from IPython.html.templates."""
+ )
+ def _extra_template_paths_default(self):
+ return []
+
+ @property
+ def template_file_path(self):
+ """return extra paths + the default locations"""
+ return self.extra_template_paths + DEFAULT_TEMPLATE_PATH_LIST
+
nbextensions_path = List(Unicode, config=True,
help="""paths for Javascript extensions. By default, this is just IPYTHONDIR/nbextensions"""
)