From 5e06b970956af4854e970e74990cb971ba31c96b Mon Sep 17 00:00:00 2001 From: farhan Date: Tue, 3 Jun 2025 10:32:34 +0500 Subject: 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 Co-authored-by: Natalia <124304+nessita@users.noreply.github.com> Co-authored-by: Nick Pope --- docs/ref/templates/builtins.txt | 74 +++++++++++++++++++++ docs/ref/templates/language.txt | 144 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 218 insertions(+) (limited to 'docs/ref') 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 %} + + {% 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 +`. + +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 %} +
+

{{ title }}

+

{{ content }}

+
+ {% 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 `, +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 %} +
+

{{ user.name }}

+

{{ user.bio }}

+
+ {% 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 %} +

Authors

+ {% for user in authors %} + {% partial user-info %} + {% endfor %} + +

Editors

+ {% 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 %} +
+

{{ user.name }}

+

{{ user.bio }}

+
+ {% endpartialdef %} + + {# Other page content here. #} + + {# Reuse later elsewhere in the template. #} + + +.. _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 %} +

Featured Author of the Month

+ {% partial user-info %} + {% endwith %} + .. _next section: #automatic-html-escaping .. _automatic-html-escaping: -- cgit v1.3