Issue
When using HTMX framework with Python Flask, you have to be able to:
serve a request as a HTML fragment if it's done by HTMX (via AJAX)
server a request as a full page if it's done by the user (e.g. entered directly in the browser URL bar)
See Single-page-application with fixed header/footer with HTMX, with browsing URL history or Allow Manual Page Reloading for more details.
How to do this with the Flask template system?
from flask import Flask, render_template, request
app = Flask("")
@app.route('/pages/<path>')
def main(path):
htmx_request = request.headers.get('HX-Request') is not None
return render_template(path + '.html', fullpage=not htmx_request)
app.run()
What's the standard way to output a full page (based on a parent template pagelayout.html
):
{% extends "pagelayout.html" %}
{% block container %}
<button>Click me</button>
{% endblock %}
if fullpage
is True
, and just a HTML fragment:
<button>Click me</button>
if it is False
?
Solution
This solution based on that we can use a dynamic variable when extending a base template. So depending on the type or the request, we use the full base template or a minimal base template that returns only our fragment's content.
Lets call our base template for fragments base-fragments.html
:
{% block container %}
{% endblock %}
It's just returns the main block's content, nothing else. At the view function we have a new template variable baselayout
, that contains the name of the base template depending on the request's type (originating from HTMX or not):
@app.route('/pages/<path>')
def main(path):
htmx_request = request.headers.get('HX-Request') is not None
baselayout = 'base-fragments.html' if htmx_request else 'pagelayout.html'
return render_template(path + '.html', baselayout=baselayout)
And in the page template, we use this baselayout
variable at the extends
:
{% extends baselayout %}
{% block container %}
<button>Click me</button>
{% endblock %}
Answered By - Dauros
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.