Reputation: 572
I'm building an html page in Django, which has the following structure:
{% extends 'main/base_template.html' %}
{% load filters %}
{% block main_window %}
<main class="col-md-9 ms-sm-auto col-lg-10 px-md-4">
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">Stuff</h1>
</div>
<div class="row mb-3">
<div class="col-12 col-md-6">
{% include 'main/stuff/stuff_A.html' %}
</div>
<div class="col-12 col-md-6">
{% include 'main/stuff/stuff_B.html' %}
</div>
</div>
<div class="row mb-3">
<div class="col-12 col-md-6">
{% include 'main/stuff/stuff_C.html' %}
</div>
<div class="col-12 col-md-6">
{% include 'main/stuff/stuff_D.html' %}
</div>
</div>
{% endblock %}
And each of the stuff_X html file has the same structure, for example:
<div class="row mb-3">
<div class="table-responsive">
<table class="table table-striped table-sm caption-top" style="width:40em">
<caption>Data</caption>
<thead>
<tr>
<th scope="col">Data1</th>
<th scope="col">Data2</th>
<th scope="col">Data3</th>
</tr>
</thead>
<tbody>
<tr>
<td id="stuff_a_data1" style="width:5em">{{ stuff_a.data1 }}</td>
<td id="stuff_a_data2" style="width:5em">{{ stuff_a.data2 }}</td>
<td id="stuff_a_data3" style="width:5em">{{ stuff_a.data2 }}</td>
</tr>
</tbody>
</table>
</div>
</div>
So the only things that actually change are some ids and the name of the data to be retrieved from the django context.
Are there any mechanisms that allow me to write generic pages for cases like this? Cause currently I am handling 4 (almost) identical pages, adding snippets of code in each of them when I need to modify something.
Thanks in advance!
Upvotes: 1
Views: 385
Reputation: 8202
I think you can generalize {{ stuff_a.data1 }}
to {{ foo.data1}}
by using
{% with stuff_a as foo, 'stuff_a' as foo_id_tag %}
{% include 'main/stuff/foo.html' %}
{% endwith %}
provided that the templates are, indeed, identical in form, or similar enough that you can steer them with {%if ... %}
. (The ids would become id="{{foo_id_tag}}_data1"
etc. )
The other way, which isn't hard, is to use format_html
in your python code to generate stuff which you them pass to the template through the context. Or use a property on the relevant model. Something like
class Foo ( models.Model):
...
@property
def bar (self):
bar = max( self.a*3 - self.b, 0 )
return f"{bar:.4}"
so you can refer to {{foo.bar}}
in your template, which can't itself do even trivial arithmetic on foo's fields.
Edit: I had forgotten that with
functionality has been baked into %include since Django 1.something. So, more elegantly,
{% include 'main/stuff/foo.html' with foo = stuff_a, foo_id_tag = 'stuff_a' %}
Upvotes: 1
Reputation: 83
Not sure if that's what you need but you should be able to concatenate strings with the add template filter:
{% with 'main/stuff/stuff_'|add:your_variable|add:'.html' as filename %}
{% include filename %}
{% endwith %}
You'll need to pass your_variable
from your views.py, obviously.
Upvotes: 1