Panel is an extension on top of Bokeh and before any Bokeh model that is part of Bokeh can be rendered panel.js needs to be loaded in some form. In the notebook this relies on the panel/_templates/doc_nb_js.js template which waits until both Bokeh and Panel have been loaded. Additionally I also recently had to add some support to ensure that third party libraries need to be loaded before rendering (as sometimes when using inline resources they would not load in time), see https://github.com/holoviz/panel/pull/1577.
However while this handling is fine for Panel itself it does not work for other extensions (e.g. awesome-panel-extensions). So there are a number of things we can do to make sure further extensions can register themselves both with bokeh and with panel.
The first thing is that bokeh/core/_templates/try_run.js does not even consider third-party extension (including panel) which is why we had to override this template in Panel in the first place. So we should make sure that we upstream a patch into bokeh that ensures that all imported extensions are considered in try_run.js.
In Panel we should have a mechanism for other Panel extensions to register themselves appropriately as well. We have to consider whether this should be via a plugin mechanism or simply discover extensions that have been imported before pn.extension is run.
Secondly we should make sure that the mechanism for ensuring third-party JS libraries are loaded before rendering is also extensible. In all likelihood this should discover all custom models being rendered and then check some attribute on the model to look for any JS libraries that need to be available globally, e.g. something like PlotlyModel.__js_required__ = 'Plotly'. The rendering code can then ensure that 'window.Plotly' is available before rendering the model and do so in a way that is transparent for other downstream libraries.
Currently to make this work the user would have to:
Register their custom model with pn.extension._imports
If not loading the custom extension with pn.extension('custom') manually add the extension to pn.extension._loaded_extensions
Register the global variable on the JS window with pn.extension._globals
Panel is an extension on top of Bokeh and before any Bokeh model that is part of Bokeh can be rendered panel.js needs to be loaded in some form. In the notebook this relies on the
panel/_templates/doc_nb_js.js
template which waits until both Bokeh and Panel have been loaded. Additionally I also recently had to add some support to ensure that third party libraries need to be loaded before rendering (as sometimes when using inline resources they would not load in time), see https://github.com/holoviz/panel/pull/1577.However while this handling is fine for Panel itself it does not work for other extensions (e.g. awesome-panel-extensions). So there are a number of things we can do to make sure further extensions can register themselves both with bokeh and with panel.
The first thing is that
bokeh/core/_templates/try_run.js
does not even consider third-party extension (including panel) which is why we had to override this template in Panel in the first place. So we should make sure that we upstream a patch into bokeh that ensures that all imported extensions are considered in try_run.js.In Panel we should have a mechanism for other Panel extensions to register themselves appropriately as well. We have to consider whether this should be via a plugin mechanism or simply discover extensions that have been imported before pn.extension is run.
Secondly we should make sure that the mechanism for ensuring third-party JS libraries are loaded before rendering is also extensible. In all likelihood this should discover all custom models being rendered and then check some attribute on the model to look for any JS libraries that need to be available globally, e.g. something like
PlotlyModel.__js_required__ = 'Plotly'
. The rendering code can then ensure that 'window.Plotly' is available before rendering the model and do so in a way that is transparent for other downstream libraries.Currently to make this work the user would have to:
pn.extension._imports
pn.extension('custom')
manually add the extension topn.extension._loaded_extensions
window
withpn.extension._globals
Cc: @MarcSkovMadsen