I am building a website with Wagtail/Django.
Most of my pages consist of some text followed by a graph or table generated with Bokeh.
The way I found to add the Bokeh and codes to each page is by using custom template tags. I have created a function that outputs the Bokeh code and I call this function using a template tag.
Therefore a typical template in this site looks like:
{% load customtemplatetag %}
{% block content %}
<div class="container py-4">
<h1>
{{ page.header|richtext }}
</h1>
<p class="lead">
{{ page.plead|richtext }}
</p>
{% bokehgraph as bokehg %}
{{ bokehg.1| safe }}
{{ bokehg.0| safe }}
</div>
{% endblock %}
Therefore, I have a page model with a dedicated template for each different type of Bokeh Output.
It does not feels like the best way of doing it.
Is there any way I can use the same model with different templates, or maybe a totally different approach that will enable me to use less page models and less templates?
Edit: Following up on the comment from Richard Allen:
I have different template tags that return different graphs. My customtemplatetag file looks like:
register = template.Library()
@register.simple_tag
def bokehgraph():
Loads data from database1
Generates graph with Bokeh
return components(layout)
@register.simple_tag
def bokehgraph2():
Loads data from database2
Generates another graph with Bokeh
return components(layout)
The .1 and .2 attributes are the <div>
and <script>
generate by Bokeh components.
What I need is to be able to select from Wagtail CMS if bokehgraph or bokegraph2 is going to be called for a given page.
The solution that I have now is to have two models, with two templates. One template calls bokegraph and the other calls bokehgraph2.
I'm assuming the two graph types have very different inputs so can't use the same parameter options.
Rather than two page models, it might be a better route to create a StreamField with one block type per graph type (2 for now, but you can add more this way). If you only ever want one graph per page, then you can set the min/max block values. Since you can specify a front-end template for the block, this logic is taken out of the page template.
So if the two graphs are called Type A and Type B, you might do something like:
class TypeAGraphBlock(StructBlock):
... block attributes ...
class Meta:
template = 'blocks/graph_type_a_block.html'
label = _("Type A Graph")
icon = 'some icon'
class TypeBGraphBlock(StructBlock):
... block attributes ...
class Meta:
template = 'blocks/graph_type_b_block.html'
label = _("Type B Graph")
icon = 'some other icon'
class YourPage(Page):
... page attributes ...
graph = StreamField(
[
("type_a_graph", TypeAGraphBlock()),
("type_b_graph", TypeBGraphBlock()),
],
verbose_name="Graph",
min_num=1,
max_num=1,
use_json_field=True
)
... rest of page definition ...