Skip to content

Commit

Permalink
Update view and templates to use template-partials.
Browse files Browse the repository at this point in the history
  • Loading branch information
carltongibson committed Aug 6, 2024
1 parent fe1878d commit 5220acd
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 83 deletions.
3 changes: 0 additions & 3 deletions example/example/templates/_partial.html

This file was deleted.

153 changes: 79 additions & 74 deletions example/example/templates/partial-rendering.html
Original file line number Diff line number Diff line change
@@ -1,90 +1,95 @@
{% extends base_template %}
{% load partials %}

{% block main %}
<section>
<p>
This example shows you how you can do partial rendering for htmx requests.
The view uses an alternative base template for requests made with htmx.
This base template only renders the <code>&lt;main&gt;</code> element, saving time and bandwidth.
This example shows you how you can do partial rendering for htmx requests using django-template-partials.
The view renders only the content of the table section partial for requests made with htmx, saving time and bandwidth.
Paginate through the below list of randomly generated people to see this in action, and study the view and template.
</p>
<p><a href="https://django-htmx.readthedocs.io/en/latest/tips.html#partial-rendering">See more in the docs</a>.</p>
</section>

<section>
<table>
<thead>
<tr>
<th>id</th>
<th>name</th>
</tr>
</thead>
<tbody>
{% for person in page.object_list %}
<tr>
<td>{{ person.id }}</td>
<td>{{ person.name }}</td>
</tr>
{% empty %}
{% partialdef table-section inline %}
<article id="table">
<section>
<table>
<thead>
<tr>
<td colspan="2">
No people on this page.
</td>
<th>id</th>
<th>name</th>
</tr>
{% endfor %}
</tbody>
</table>
</section>
</thead>
<tbody>
{% for person in page.object_list %}
<tr>
<td>{{ person.id }}</td>
<td>{{ person.name }}</td>
</tr>
{% empty %}
<tr>
<td colspan="2">
No people on this page.
</td>
</tr>
{% endfor %}
</tbody>
</table>
</section>

<section>
<!--
The htmx attributes set on the nav here are inherited by the child links.
hx-target tells where htmx to swap the fetched content in, and hx-swap
tells it how to swap it - by replacing the 'outerHTML' attribute of the
target, i.e. replacing the target's actual DOM node. hx-push-url tells
htmx to push the fetched URL into the browser history, so we can use
the backwards/forwards buttons to navigate these subpages.
-->
<nav hx-target="#main" hx-swap="outerHTML" hx-push-url="true">
<ul>
{% if page.number != 1 %}
<li>
<!--
For each link we use hx-get to tell htmx to fetch that URL and
swap it in. We also repeat the URL in the href attribute so the
page works without JavaScript, and to ensure the link is
displayed as clickable.
-->
<a hx-get="?page=1" href="?page=1">
&laquo; First
</a>
</li>
{% endif %}
{% if page.has_previous %}
<section>
<!--
The htmx attributes set on the nav here are inherited by the child links.
hx-target tells where htmx to swap the fetched content in, and hx-swap
tells it how to swap it - by replacing the 'outerHTML' attribute of the
target, i.e. replacing the target's actual DOM node. hx-push-url tells
htmx to push the fetched URL into the browser history, so we can use
the backwards/forwards buttons to navigate these subpages.
-->
<nav hx-target="#table" hx-swap="outerHTML" hx-push-url="true">
<ul>
{% if page.number != 1 %}
<li>
<!--
For each link we use hx-get to tell htmx to fetch that URL and
swap it in. We also repeat the URL in the href attribute so the
page works without JavaScript, and to ensure the link is
displayed as clickable.
-->
<a hx-get="?page=1" href="?page=1">
&laquo; First
</a>
</li>
{% endif %}
{% if page.has_previous %}
<li>
<a hx-get="?page={{ page.previous_page_number }}" href="?page={{ page.previous_page_number }}">
{{ page.previous_page_number }}
</a>
</li>
{% endif %}
<li>
<a hx-get="?page={{ page.previous_page_number }}" href="?page={{ page.previous_page_number }}">
{{ page.previous_page_number }}
</a>
{{ page.number }}
</li>
{% endif %}
<li>
{{ page.number }}
</li>
{% if page.has_next %}
<li>
<a hx-get="?page={{ page.next_page_number }}" href="?page={{ page.next_page_number }}">
{{ page.next_page_number }}
</a>
</li>
{% endif %}
{% if page.number != page.paginator.num_pages %}
<li>
<a hx-get="?page={{ page.paginator.num_pages }}" href="?page={{ page.paginator.num_pages }}">
&raquo; Last
</a>
</li>
{% endif %}
</ul>
</nav>
</section>
{% if page.has_next %}
<li>
<a hx-get="?page={{ page.next_page_number }}" href="?page={{ page.next_page_number }}">
{{ page.next_page_number }}
</a>
</li>
{% endif %}
{% if page.number != page.paginator.num_pages %}
<li>
<a hx-get="?page={{ page.paginator.num_pages }}" href="?page={{ page.paginator.num_pages }}">
&raquo; Last
</a>
</li>
{% endif %}
</ul>
</nav>
</section>
</article>
{% endpartialdef %}

{% endblock %}
11 changes: 5 additions & 6 deletions example/example/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,19 +119,18 @@ def partial_rendering(request: HtmxHttpRequest) -> HttpResponse:
page_num = request.GET.get("page", "1")
page = Paginator(object_list=people, per_page=10).get_page(page_num)

# The htmx magic - use a different, minimal base template for htmx
# The htmx magic - render just the `#table-section` partial for htmx
# requests, allowing us to skip rendering the unchanging parts of the
# template.
template_name = "partial-rendering.html"
if request.htmx:
base_template = "_partial.html"
else:
base_template = "_base.html"
template_name += "#table-section"

return render(
request,
"partial-rendering.html",
template_name,
{
"base_template": base_template,
"base_template": "_base.html",
"page": page,
},
)

0 comments on commit 5220acd

Please sign in to comment.