Embed Bokeh plot in static website using jinja2 templating

Hi all, and thanks for developing this great tool :star_struck:

What I’m trying to do

Embed a Bokeh plot on a Lektor website, i.e static website with Jinja2 templating.

I first used components to do this, and then switched to the simpler HTML files approach when getting the error below, to make sure it wasn’t the fancier embedding that was causing the error. I used the examples on the website to implement it.

What didn’t work as expected

Once the Bokeh plot worked well on Jupyter, I executed:

output_file("my/path/gp-plot.html")
show(column(p1, p2, p3))

Then I simply added {% include "gp-plot.html" %} in the HTML file where I want to display the plot.
But when trying to build the website, I get a weird jinja2.exceptions.TemplateSyntaxError: Encountered unknown tag 'b'. :exploding_head:

I’m aware that it may well not be a Bokeh issue, but wanted to get some pointers here, as I hope some people already encountered this error – and it appears only when embedding the plot’s script.

Good to know

The problem seems to come from the script component: when using components to embed, the site building worked when just the div was present.

In case it helps, here is the end of the traceback:

File "/Users/alex_andorra/repos/pollsposition_website/templates/gp-plot.html", line 9, in template

I went and checked line 9 of the generated HTML file, but unfortunately that’s not very informative as it’s the huge part where all the plot’s data are :weary:

I’ve been at it for hours now and can’t figure it out – and I’ve found nothing useful on Google and no similar topics on this Discourse either (my apologies if there actually is such a question already).
Has anyone already encountered that by any chance?

Feel free to ask if anything is unclear, and thanks a lot in advance for your help!

I would not expect this to work. output_file generates a whole entire HTML file with its own head and body, and just including that in the middle of some other page will result in malformed, invalid HTML. This could potentially be workable if you include the output HTML file inside an IFrame instead.

Otherwise, if you want to embed content directly in another page, then you should use one of the APIs intended for that. Apart from components, there is json_item or autoload_static.

Hi @Bryan, and thanks for your answer!
I forgot to mention that I did remove the head and body tags from the file generated by output_file. My goal was to have a more or less exact comparison with components which didn’t work either because of the same parsing error from Jinja2 (which is also why I expected the two other methods you mention to also fail: this seems to be an issue with parsing not with the file generation).


And actually I think I managed to track it down, with help from the jinja community: I’m customizing the plots’ hover tools with {%b %Y} for datetimes, which means this {%b appears in the generated script. And that’s when the error comes out: when including the file on the website, it is being processed as a Jinja template, and Jinja is encountering something that looks like a Jinja tag that it doesn’t recognize (the {%b)!

The solution is to wrap the script file in {% raw %} and {% endraw %}, which tells Jinja to ignore anything within that block even if matches Jinja syntax :tada:


I’m wondering how practical it would be to add a kwarg to components and & co. for these cases – something like flag_raw=True, which would automatically wrap the contents in the appropriate raw tags. How useful and possible would that be in your opinion?

@AlexAndorra The components API is already fairly cluttered, I am a bit reticent to burden it with more. Also, there is no reason that components has to only be used wit Jinja2, so IMO it’s not really a good place to add options to make it do things that are unique and specific to Jinja2 .I think this would be a useful to document though, either in the docstring or the User’s Guide Embedding chapter (or both).

Yeah I understand, and I of course defer to your expertise of the package. I was suggesting this to offer an automated solution to users who encounter this problem – this can very probably be taken care of by each user through a custom python function that goes and modify the HTML generated by Bokeh.

If the problem appears for other templating languages though, then it could be worth adding this :man_shrugging: And in any case I hope my previous post will help people – now there is at least one such reference on the internet about that :sweat_smile:

Take care, and hanks again for your work on Bokeh :star_struck: