Creating an include-able component that takes blocks

Hi there. I’m quite new to Django and trying to work out the best way to achieve the following in the templating engine.

I’d like to create a wrapper for table content (for the sake of including classes standard to our project etc) which can somehow be included inside other templates and provided with “blocks” (not necessarily actually blocks) for the head and body areas.

A sketch of what I’d like the usage to look like would be:

<p>A different bit of the including page</p>

{% include "my_table.html with a_parameter="something" %}

    {% block head %}
    <th>Column {{ a_parameter }}</th>
    {% endblock head %}

    {% block body %}
    {% endblock body %}

{% endinclude %} (I know this isn't a thing!)

and have that render to something like:

<p>A different bit of the including page</p>
<table class="lots of custom stuff">
        <th>Column something</th>

Note an extra bonus requirement of being able to specify with arguments, though that’s not totally necessary: I suppose if the approach can support a block-style approach then this is doable that way.

Thanks in advance!

I’m sorry, I’m not quite sure I understand what you’re trying to achieve here.

What I’m getting from your description is that you actually want your template to extend another template, where that other template contains your “classes standard to our project”.

You can nest extends. You can have your base template containing everything to be used throughout your project. Then you can have a “table template” that extends your base with the features needed for tables. You can then build your table that extends the “table template” to populate your blocks.

(Side note: If you’re familiar with some other frameworks such as WordPress or Drupal, I can tell you that Django is different with how pages are composed. It does require some adjustment to the mindset you need when designing page layouts.)

Thanks for that: I think the thing that’s getting me about extend in Django is that it’s a template-wide thing: a template has to start with an extends declaration. I was looking for a component solution that can be “dropped in” anywhere in a template but which takes more than just with values as data. I’d like to pass it blocks of HTML.

I think I’m having trouble because I come from mostly React, where you’d have eg a MyTable component which can “wrap” a whole load of “child” content using the children prop.

So, I suppose what I’m asking is: is there a way to have an include-able component but pass a whole chunk of HTML to it as a named piece of context, rather than just smaller with foo="bar"-style data?

In short, yes. You can do {% include with html_fragment=chunk_of_html %} where chunk_of_html is your html passed in through your context.

However, that may not be the best way to handle it. You’re generally better off passing the data to be included to the template identified in the include statement, allowing it to render that included data. (You can find numerous examples of this in the Django admin templates.)

In “Django terms”, your “MyTable” component would be your template. Your “child” content would then be rendered as an {% include %} template. If you have multiple such children, you iterate through them, rendering each child as a separate include.

{% for child in children %}
  {% include "child_template.html" with child=child %}
{% endfor %}

Thanks, I’ll try and get something working along those lines!