diff options
| author | farhan <farhanalirazaazeemi@gmail.com> | 2025-06-03 10:32:34 +0500 |
|---|---|---|
| committer | nessita <124304+nessita@users.noreply.github.com> | 2025-08-14 21:53:14 -0300 |
| commit | 5e06b970956af4854e970e74990cb971ba31c96b (patch) | |
| tree | 59fb79f5e255298625af1ad072ad4026e64f582d /docs | |
| parent | fda3c1712a1eb7b20dfc91e6c9abae32bd64d081 (diff) | |
Fixed #36410 -- Added support for Template Partials to the Django Template Language.
Introduced `{% partialdef %}` and `{% partial %}` template tags to
define and render reusable named fragments within a template file.
Partials can also be accessed using the `template_name#partial_name`
syntax via `get_template()`, `render()`, `{% include %}`, and other
template-loading tools.
Adjusted `get_template()` behavior to support partial resolution, with
appropriate error handling for invalid names and edge cases. Introduced
`PartialTemplate` to encapsulate partial rendering behavior.
Includes tests and internal refactors to support partial context
binding, exception reporting, and tag validation.
Co-authored-by: Carlton Gibson <carlton@noumenal.es>
Co-authored-by: Natalia <124304+nessita@users.noreply.github.com>
Co-authored-by: Nick Pope <nick@nickpope.me.uk>
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/ref/templates/builtins.txt | 74 | ||||
| -rw-r--r-- | docs/ref/templates/language.txt | 144 | ||||
| -rw-r--r-- | docs/releases/6.0.txt | 15 | ||||
| -rw-r--r-- | docs/topics/templates.txt | 27 |
4 files changed, 260 insertions, 0 deletions
diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt index 1eb391d8c0..464c4d83ac 100644 --- a/docs/ref/templates/builtins.txt +++ b/docs/ref/templates/builtins.txt @@ -957,6 +957,80 @@ output (as a string) inside a variable. This is useful if you want to use {% now "Y" as current_year %} {% blocktranslate %}Copyright {{ current_year }}{% endblocktranslate %} +.. templatetag:: partial + +``partial`` +----------- + +.. versionadded:: 6.0 + +Renders a template fragment that was defined with :ttag:`partialdef`, inserting +the matching partial at this location. + +Usage: + +.. code-block:: html+django + + {% partial partial_name %} + +The ``partial_name`` argument is the name of the template fragment to render. + +In the following example, a partial named ``button`` is defined and then +rendered three times: + +.. code-block:: html+django + + {% partialdef button %} + <button>Submit</button> + {% endpartialdef %} + + {% partial button %} + {% partial button %} + {% partial button %} + +.. templatetag:: partialdef + +``partialdef`` +-------------- + +.. versionadded:: 6.0 + +Defines a reusable template fragment that can be rendered multiple times within +the same template or accessed directly via :ref:`template loading or inclusion +<template-partials-direct-access>`. + +Usage: + +.. code-block:: html+django + + {% partialdef partial_name %} + {# Reusable content. #} + {% endpartialdef %} + +The ``partial_name`` argument is required and must be a valid template +identifier. + +In the following example, a new fragment named ``card`` is defined: + +.. code-block:: html+django + + {% partialdef card %} + <div class="card"> + <h3>{{ title }}</h3> + <p>{{ content }}</p> + </div> + {% endpartialdef %} + +This partial can then be rendered using the :ttag:`partial` tag: + +.. code-block:: html+django + + {% partial card %} + {% partial card %} + +To :ref:`render a fragment immediately in place <template-partials-inline>`, +use the ``inline`` option. The partial is still stored and can be reused later. + .. templatetag:: querystring ``querystring`` diff --git a/docs/ref/templates/language.txt b/docs/ref/templates/language.txt index 16a3682086..e8812666fa 100644 --- a/docs/ref/templates/language.txt +++ b/docs/ref/templates/language.txt @@ -475,6 +475,150 @@ it also defines the content that fills the hole in the *parent*. If there were two similarly-named :ttag:`block` tags in a template, that template's parent wouldn't know which one of the blocks' content to use. +.. _template-partials: + +Template partials +================= + +.. versionadded:: 6.0 + +Template partials define reusable template fragments within a template file. +They are self-contained components that can be rendered multiple times within +the same template, helping to avoid repetition and maintain consistent output. + +Basic syntax +------------ + +A partial can be defined using the :ttag:`partialdef` tag: + +.. code-block:: html+django + :caption: ``authors.html`` + + {% partialdef user-info %} + <div id="user-info-{{ user.username }}"> + <h3>{{ user.name }}</h3> + <p>{{ user.bio }}</p> + </div> + {% endpartialdef %} + +For extra readability, the name can be included in the ``{% endpartialdef %}`` +closing tag: + +.. code-block:: html+django + + {% partialdef user-info %} + {# ... #} + {% endpartialdef user-info %} + +The template fragment can be rendered using the :ttag:`partial` tag: + +.. code-block:: html+django + + {% partial user-info %} + +Fragment reuse +-------------- + +A template fragment can be reused multiple times: + +.. code-block:: html+django + :caption: ``authors.html`` + + {% block content %} + <h2>Authors</h2> + {% for user in authors %} + {% partial user-info %} + {% endfor %} + + <h2>Editors</h2> + {% for user in editors %} + {% partial user-info %} + {% endfor %} + {% endblock %} + +The partial content is rendered each time the named partial is used, with the +current template context. + +.. _template-partials-inline: + +Inline partials +--------------- + +A template fragment can be defined and rendered in-place using the ``inline`` +argument. This defines the partial for later reuse while also rendering it +immediately at its definition: + +.. code-block:: html+django + + {# Define and render immediately. #} + {% partialdef user-info inline %} + <div id="user-info-{{ user.username }}"> + <h3>{{ user.name }}</h3> + <p>{{ user.bio }}</p> + </div> + {% endpartialdef %} + + {# Other page content here. #} + + {# Reuse later elsewhere in the template. #} + <section class="featured-authors"> + <h2>Featured Authors</h2> + {% for user in featured %} + {% partial user-info %} + {% endfor %} + </section> + +.. _template-partials-direct-access: + +Accessing partials directly +--------------------------- + +Template fragments defined with :ttag:`partialdef` can be accessed directly via +template loading or inclusion using the ``template.html#partial_name`` syntax. + +For example, using the :func:`~django.shortcuts.render` shortcut, the following +code renders only the partial named ``user-info`` defined in the +``authors.html`` template:: + + from django.contrib.auth.models import User + from django.shortcuts import get_object_or_404, render + + + def user_info_partial(request, user_id): + user = get_object_or_404(User, id=user_id) + return render(request, "authors.html#user-info", {"user": user}) + +This approach is particularly useful for AJAX-style requests that update only +specific portions of a page with the rendered template fragment. + +Template partials can also be included using the :ttag:`include` template tag +with the same ``#`` directive: + +.. code-block:: html+django + + {% include "authors.html#user-info" %} + +Context handling +---------------- + +Template partials are rendered with the current template context. They work as +expected in loops and with context variables: + +.. code-block:: html+django + + {% for user in users %} + {% partial user-info %} + {% endfor %} + +Context variables can be adjusted using the :ttag:`with` tag: + +.. code-block:: html+django + + {% with user=featured_author %} + <h2>Featured Author of the Month</h2> + {% partial user-info %} + {% endwith %} + .. _next section: #automatic-html-escaping .. _automatic-html-escaping: diff --git a/docs/releases/6.0.txt b/docs/releases/6.0.txt index 0c1a2c87eb..3e250706ec 100644 --- a/docs/releases/6.0.txt +++ b/docs/releases/6.0.txt @@ -91,6 +91,21 @@ Notably, the return type of the :class:`EmailMessage.message() previous ``SafeMIMEText`` and ``SafeMIMEMultipart`` return types, but is not an instance of those now-deprecated classes. +Template Partials +----------------- + +The :ref:`Django Template Language <template-language-intro>` now supports +:ref:`template partials <template-partials>` , making it easier to encapsulate +and reuse small named fragments within a template file. The new tags +:ttag:`{% partialdef %} <partialdef>` and :ttag:`{% partial %} <partial>` +define a partial and render it, respectively. + +Partials can also be referenced using the ``template_name#partial_name`` syntax +with :func:`~django.template.Engine.get_template`, +:func:`~django.shortcuts.render`, :ttag:`{% include %}<include>`, and other +template-loading tools, enabling more modular and maintainable templates +without needing to split components into separate files. + Minor features -------------- diff --git a/docs/topics/templates.txt b/docs/topics/templates.txt index df55cccb06..1b5559db5a 100644 --- a/docs/topics/templates.txt +++ b/docs/topics/templates.txt @@ -306,6 +306,33 @@ The ``django.template.loader`` module defines two functions to load templates. If you want to restrict the search to a particular template engine, pass the engine's :setting:`NAME <TEMPLATES-NAME>` in the ``using`` argument. + **Partial loading:** + + When using the :class:`~django.template.backends.django.DjangoTemplates` + backend, a specific fragment from a template can be loaded by name. This + fragment should have been previously defined using the :ttag:`partialdef` + template tag:: + + from django.template.loader import get_template + + # Load an entire template. + template = get_template("template.html") + + # Load a specific fragment from a template. + partial = get_template("template.html#partial_name") + + When loading a partial, the returned object behaves like a regular + ``Template`` but contains only the partial's content. + + See :ref:`template-partials` for more information about defining and using + template fragments. + + .. versionchanged:: 6.0 + + Support for loading template partials when using the + :class:`~django.template.backends.django.DjangoTemplates` backend was + added. + .. function:: select_template(template_name_list, using=None) ``select_template()`` is just like ``get_template()``, except it takes a |
