Properly Factor Your Jinja HTML Code with Jinja Partials

If you work with Python code, then you’ve surely seen some bad code. Martin Fowler popularized the idea of code smells.

“Code smells are certain structures in the code that indicate violation of fundamental design principles and negatively impact design quality.” [wk]

This may have been your bad code. More likely, if you’re taking the time to read about code styles, it was someone else’s.

Either way, one of the biggest offenders is the long method.

You know, that single Python function that is

627

lines

long.

Really? Yes, apparently. We see this and immediately know it’s bad. Usually this has some some foul code duplication mixed in for good measure.

If you were responsible for this code, you’d fix it straight away.

But we do this every day on the web

While outrageous in code, we wouldn’t bat an eye if we had an HTML template (think Jinja2 from Flask/FastAPI, Django template from Django, or Chameleon from Pyramid) that was over 600 lines of HTML.

There usually is no mechanism of a function call within HTML templates for Python languages.

Or is there?

When I started working with HTMX (incredible framework!), this problem came to a head in my Python apps. So I created the Jinja Partials package. There is also a Pyramid/Chameleon version.

Jinja Partials adds the concept of a function call with a named set of template code and a clear variables / parameters passed to that template. The repo has some examples.

I just used this concept to surface more options for subscribing to Talk Python.

See the choices of podcast players in the list of episodes page:

And on the episode details page:

As well as the new subscribe page:

That list of podcast players, style, and basic analytics (click counting) is all handled with just this HTML fragement:

{{ render_partial('episodes/partials/subscribe-in-players.pt', 
                 is_listing=False, 
                 cdn_prefix=view.cdn_prefix)
 }}

If this idea of a function inside HTML appeals to you, then check out jinja-partials or chameleon_partials.

Finally, if you’re one of the few people saying “Jinja already has include!!!” Yes, it does. It’s not the same. See the whole discussion here.

TL;DR; about include: Jinja’s include is analogous to C++ precompiler macros without passing parameters. Jinja Partials is like functions with parameters and local variable scope. They can both solve the same problem some of the time, but they are definitely not the same.

Hope you find this idea of cleaning up your HTML templates with functions appealing!