Skip to main content

django-template-partials

Project description

django-template-partials

pypi

Reusable named inline partials for the Django Template Language.

Watch the talk

I introduced django-template-partials in my DjangoCon Europe 2023 talk in Edinburgh.

For a quick introduction, you can watch the video on YouTube. 🍿

DjangoCon Europe 2023 | Yak-shaving to Where the Puck is Going to Be.

Installation

Install with pip:

pip install django-template-partials

Then add to INSTALLED_APPS and you're good go.

INSTALLED_APPS = [
    "template_partials",
    ...,
]

See Advanced configuration (below) for more options.

Please see the CHANGELOG if you are upgrading from a previous version.

Basic Usage

Once installed, load the partials tags and define a re-usable partial at the top of your template:

{% load partials %}

{% partialdef test-partial %}
TEST-PARTIAL-CONTENT
{% endpartialdef %}

For extra readability, you can optionally add the name to your {% endblock %} tag. For example:

{% load partials %}

{% partialdef test-partial %}
TEST-PARTIAL-CONTENT
{% endpartialdef test-partial %}

Fragment Re-use

With the partial defined, you can reuse it multiple times later:

{% block main %}
BEGINNING
{% partial test-partial %}
MIDDLE
{% partial test-partial %}
END
{% endblock main %}

The partial content will be rendered in each time the named partial is used.

Via the template loader

django-template-partials is also integrated with the template loader, so you can pass a template plus a partial name to the loader to have just that part rendered:

# In view handler…
self.template_name = "example.html#test-partial"

The rest of your view logic remains the same.

This means that you can also use the partial with the include tag:

{% include "example.html#test-partial" %}

Outputting inline

You might want to wrap an existing part of your page, and continue rendering the content inside your partial, use the inline argument in that situation:

{% block main %}
{% partialdef inline-partial inline=True %}
CONTENT
{% endpartialdef %}
{% endblock main %}

Controlling the context

A template partial is rendered with the current context.

This means it works in, for example, a loop as expected:

{% for object in object_list %}
    {% partial test-partial %}
{% endfor %}

If you need to adjust the context, use the with tag as normal:

{% with name=value othername=othervalue %}
    {% partial test-partial %}
{% endwith %}

Capturing output

Rendering a partial — say a pagination widget — may be computationally expensive.

It's out-of-scope for django-template-partials to capture the generated HTML to the context, but other options exist, such as the Slipper's library fragment tag, that allows exactly this behaviour.

Adding partials to template builtins.

Maybe you don't want to load the partials tags in every template…

{% load partials %}

The Django Template Language's OPTIONS allow you to add to the builtins that are loaded for every template. You can add the partials tags there:

OPTIONS = {
    "builtins": ["template_partials.templatetags.partials"],
}

That's the basics. Enjoy! 🚀

Advanced configuration

By default, adding "template_partials" to your INSTALLED_APPS will configure any Django template backend to use the partials template loader.

If you need to control this behaviour, you can use an alternative SimpleAppConfig, which will not adjust your TEMPLATES setting:

INSTALLED_APPS = [
    "template_partials.apps.SimpleAppConfig",
    ...,
]

If you use SimpleAppConfig, you will need to configure the template loader yourself.

A wrap_loaders() function is available, and can be used to configure any specific template engine instance with the template partials loader.

You can use the backend's NAME to wrap_loaders() to add the partial loader just for that backend:

from template_partials.apps import wrap_loaders

TEMPLATES = [
    ...,
    {
        "BACKEND": "...",
        "NAME": "myname",
        "OPTIONS": {
           ...,
        },
    },
    ...,
]

wrap_loaders("myname")

If the NAME isn't provided, the penultimate element of the BACKEND value is used - for example, "django.template.backends.django.DjangoTemplates" would be equivalent to a NAME of "django".

Under the hood, wrap_loaders() is equivalent to explicitly defining the loaders by-hand. Assuming defaults…

from django.conf import settings

default_loaders = [
    "django.template.loaders.filesystem.Loader",
    "django.template.loaders.app_directories.Loader",
]
cached_loaders = [("django.template.loaders.cached.Loader", default_loaders)]
partial_loaders = [("template_partials.loader.Loader", cached_loaders)]

settings.TEMPLATES[...]['OPTIONS']['loaders'] = partial_loaders

… where TEMPLATES[...] is the entry in TEMPLATES with the NAME matching that passed to wrap_loaders().

Running the tests

Fork, then clone the repo:

git clone git@github.com:your-username/django-template-partials.git

Set up a venv:

python -m venv .venv
source .venv/bin/activate
python -m pip install -e .[tests]

Then you can run the tests with the just command runner:

just test

Or with coverage:

just coverage

If you don't have just installed, you can look in the justfile for a commands that are run.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_template_partials-24.4.tar.gz (14.5 kB view details)

Uploaded Source

Built Distribution

django_template_partials-24.4-py2.py3-none-any.whl (8.4 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file django_template_partials-24.4.tar.gz.

File metadata

File hashes

Hashes for django_template_partials-24.4.tar.gz
Algorithm Hash digest
SHA256 25b67301470fc274ecc419e5e5fd4686a5020b1c038fd241a70eb087809034b6
MD5 c52c08f4c4e165c30b5c76722729354f
BLAKE2b-256 1cff2a7ddae12ca8e5fea1a41af05924c04f1bb4aec7157b04a88b829dd93d4a

See more details on using hashes here.

File details

Details for the file django_template_partials-24.4-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for django_template_partials-24.4-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 ee59d3839385d7f648907c3fa8d5923fcd66cd8090f141fe2a1c338b917984e2
MD5 7c9e04c2fa99a208c58be98aaa61a7c3
BLAKE2b-256 3172d8eea70683b25230e0d2647b5cf6f2db4a7e7d35cb6170506d9618196374

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page