From 6b3c68ef4e5de2485f40f797ce0d03ad3468ce19 Mon Sep 17 00:00:00 2001 From: martinRenou Date: Thu, 3 Feb 2022 11:40:36 +0100 Subject: [PATCH] Lab theme handling --- setup.cfg | 3 ++- share/jupyter/voila/templates/lab/page.html | 3 ++- voila/app.py | 12 ++++++++++++ voila/server_extension.py | 12 ++++++++++++ voila/utils.py | 21 ++++++++++++++++++++- 5 files changed, 48 insertions(+), 3 deletions(-) diff --git a/setup.cfg b/setup.cfg index 8f500656d..8bd1e10a3 100644 --- a/setup.cfg +++ b/setup.cfg @@ -33,9 +33,10 @@ packages = find: python_requires = >=3.7 install_requires = jupyter_server>=0.3.0,<2.0.0 + jupyterlab_server>=2.3.0,<3 jupyter_client>=6.1.3,<8 nbclient>=0.4.0,<0.6 - nbconvert>=6.0.0,<7 + nbconvert>=6.4.2,<7 websockets>=9.0 traitlets>=5.0.3,<6 diff --git a/share/jupyter/voila/templates/lab/page.html b/share/jupyter/voila/templates/lab/page.html index acb13d752..a3148cdb8 100644 --- a/share/jupyter/voila/templates/lab/page.html +++ b/share/jupyter/voila/templates/lab/page.html @@ -8,6 +8,7 @@ {{ include_css("static/index.css") }} {{ include_css("static/theme-light.css") }} {% else %} - + {{ include_css("static/index.css") }} + {{ include_lab_theme(theme) }} {% endif %} {% endblock %} diff --git a/voila/app.py b/voila/app.py index 8cf6a5bce..fd92f78cd 100644 --- a/voila/app.py +++ b/voila/app.py @@ -44,6 +44,8 @@ from jupyter_server.utils import url_path_join, run_sync from jupyter_server.services.config import ConfigManager +from jupyterlab_server.themes_handler import ThemesHandler + from jupyter_client.kernelspec import KernelSpecManager from jupyter_core.paths import jupyter_config_path, jupyter_path @@ -481,6 +483,16 @@ def start(self): 'default_filename': 'index.html' }, ), + ( + url_path_join(self.server_url, r'/voila/themes/(.*)'), + ThemesHandler, + { + 'themes_url': '/voila/themes', + 'path': '', + 'labextensions_path': jupyter_path('labextensions'), + 'no_cache_paths': ['/'] + }, + ), (url_path_join(self.server_url, r'/voila/api/shutdown/(.*)'), VoilaShutdownKernelHandler) ]) diff --git a/voila/server_extension.py b/voila/server_extension.py index 4279372c7..9d3498777 100644 --- a/voila/server_extension.py +++ b/voila/server_extension.py @@ -15,6 +15,8 @@ from jupyter_server.utils import url_path_join from jupyter_server.base.handlers import path_regex, FileFindHandler +from jupyterlab_server.themes_handler import ThemesHandler + from .paths import ROOT, collect_template_paths, collect_static_paths, jupyter_path from .handler import VoilaHandler from .treehandler import VoilaTreeHandler @@ -67,6 +69,16 @@ def _load_jupyter_server_extension(server_app): (url_path_join(base_url, '/voila'), VoilaTreeHandler, tree_handler_conf), (url_path_join(base_url, '/voila/tree' + path_regex), VoilaTreeHandler, tree_handler_conf), (url_path_join(base_url, '/voila/templates/(.*)'), TemplateStaticFileHandler), + ( + url_path_join(base_url, r'/voila/themes/(.*)'), + ThemesHandler, + { + 'themes_url': '/voila/themes', + 'path': '', + 'labextensions_path': jupyter_path('labextensions'), + 'no_cache_paths': ['/'] + }, + ), (url_path_join(base_url, '/voila/static/(.*)'), MultiStaticFileHandler, {'paths': static_paths}), (url_path_join(base_url, r'/voila/api/shutdown/(.*)'), VoilaShutdownKernelHandler), ( diff --git a/voila/utils.py b/voila/utils.py index 257e5225a..da5f6ef7f 100644 --- a/voila/utils.py +++ b/voila/utils.py @@ -18,6 +18,10 @@ import jinja2 +from nbconvert.exporters.html import find_lab_theme + +from jupyterlab_server.themes_handler import ThemesHandler + from .static_file_handler import TemplateStaticFileHandler @@ -125,9 +129,24 @@ def include_url(template_name, base_url, name): return jinja2.Markup(make_url(template_name, base_url, name)) +def include_lab_theme(base_url, name): + # Try to find the theme with the given name, looking through the labextensions + theme_name, _ = find_lab_theme(name) + + settings = { + 'static_url_prefix': f'{base_url}voila/themes/', + 'static_path': None # not used in TemplateStaticFileHandler.get_absolute_path + } + url = ThemesHandler.make_static_url(settings, f'{theme_name}/index.css') + + code = f'' + return jinja2.Markup(code) + + def create_include_assets_functions(template_name, base_url): return { "include_css": partial(include_css, template_name, base_url), "include_js": partial(include_js, template_name, base_url), - "include_url": partial(include_url, template_name, base_url) + "include_url": partial(include_url, template_name, base_url), + "include_lab_theme": partial(include_lab_theme, base_url) }