simple-web-app

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit bcbb343afad2fc8f0bde426d5bf8eecdba61a0f0
parent 0614e572fea002f7d957bf83a1c52fc1208de478
Author: Silas Brack <silasbrack@gmail.com>
Date:   Thu,  2 Oct 2025 17:53:31 +0200

feat: enable hx-preload

Diffstat:
MREADME.md | 1+
Msrc/simple_web_app/app.py | 9+++++++++
Msrc/simple_web_app/templates/application.html | 2+-
Msrc/simple_web_app/templates/index.html | 6+++---
Msrc/simple_web_app/templates/load_more.html | 2+-
Msrc/simple_web_app/templates/news_card.html | 2+-
6 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/README.md b/README.md @@ -12,4 +12,5 @@ Configuration should thus always be performed via environment variables. - ~~Use OOB for loading more articles~~ - Look into Jinja macros for components - ~~Fix tabs~~ +- Fix paths and full page loads diff --git a/src/simple_web_app/app.py b/src/simple_web_app/app.py @@ -13,6 +13,7 @@ import aiosqlite from starlette.applications import Starlette from starlette.config import Config from starlette.middleware import Middleware +from starlette.middleware.base import BaseHTTPMiddleware # from starlette.middleware.sessions import SessionMiddleware from starlette.requests import Request from starlette.routing import Mount, Route @@ -138,6 +139,13 @@ async def open_settings(request: Request): return render(request, "settings.html", context={"tab": "general"}) +class CacheControlMiddleware(BaseHTTPMiddleware): + async def dispatch(self, request, call_next): + response = await call_next(request) + if request.headers.get("HX-Preloaded") == "true": + response.headers['cache-control'] = 'private, max-age=60' + return response + @contextlib.asynccontextmanager async def lifespan(app: Starlette): conn = sqlite3.connect(DATABASE_PATH) @@ -162,6 +170,7 @@ routes = [ Mount("/static", StaticFiles(directory=STATIC_DIR), name="static"), ] middleware = [ + Middleware(CacheControlMiddleware), # Middleware(SessionMiddleware, secret_key=SECRET_KEY), ] app = Starlette( diff --git a/src/simple_web_app/templates/application.html b/src/simple_web_app/templates/application.html @@ -5,7 +5,7 @@ <title>My Chat</title> <meta name="viewport" content="width=device-width, initial-scale=1" /> <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.7/dist/htmx.min.js"></script> - <!--<script src="https://cdn.jsdelivr.net/npm/htmx-ext-preload@2.1.0"></script>--> + <script src="https://cdn.jsdelivr.net/npm/htmx-ext-preload@2.1.0"></script> <script src="https://unpkg.com/hyperscript.org@0.9.14"></script> <link rel="stylesheet" href="{{ url_for('static', path='style.css') }}"/> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.amber.min.css"/> diff --git a/src/simple_web_app/templates/index.html b/src/simple_web_app/templates/index.html @@ -8,9 +8,9 @@ <li><strong style="cursor: pointer;" data-tooltip="Choose another date" data-placement="bottom">Tuesday, September 30</strong></li> </ul> <ul> - <li><a style="cursor: pointer;" data-tooltip="Search" hx-trigger="click, keyup[ctrlKey&&shiftKey&&key=='O']" hx-get="/search" hx-target="#modal-placeholder" hx-swap="innerHTML" class="secondary"><svg height="20pt" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M480 272C480 317.9 465.1 360.3 440 394.7L566.6 521.4C579.1 533.9 579.1 554.2 566.6 566.7C554.1 579.2 533.8 579.2 521.3 566.7L394.7 440C360.3 465.1 317.9 480 272 480C157.1 480 64 386.9 64 272C64 157.1 157.1 64 272 64C386.9 64 480 157.1 480 272zM272 416C351.5 416 416 351.5 416 272C416 192.5 351.5 128 272 128C192.5 128 128 192.5 128 272C128 351.5 192.5 416 272 416z"/></svg></a></li> + <li><a style="cursor: pointer;" data-tooltip="Search" hx-trigger="click, keyup[ctrlKey&&shiftKey&&key=='O']" hx-get="/search" hx-target="#modal-placeholder" hx-swap="innerHTML" preload class="secondary"><svg height="20pt" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M480 272C480 317.9 465.1 360.3 440 394.7L566.6 521.4C579.1 533.9 579.1 554.2 566.6 566.7C554.1 579.2 533.8 579.2 521.3 566.7L394.7 440C360.3 465.1 317.9 480 272 480C157.1 480 64 386.9 64 272C64 157.1 157.1 64 272 64C386.9 64 480 157.1 480 272zM272 416C351.5 416 416 351.5 416 272C416 192.5 351.5 128 272 128C192.5 128 128 192.5 128 272C128 351.5 192.5 416 272 416z"/></svg></a></li> <li><a data-tooltip="Change font size" class="secondary"><svg height="20pt" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M349.1 114.7C343.9 103.3 332.5 96 320 96C307.5 96 296.1 103.3 290.9 114.7L123.5 480L112 480C94.3 480 80 494.3 80 512C80 529.7 94.3 544 112 544L200 544C217.7 544 232 529.7 232 512C232 494.3 217.7 480 200 480L193.9 480L215.9 432L424.2 432L446.2 480L440.1 480C422.4 480 408.1 494.3 408.1 512C408.1 529.7 422.4 544 440.1 544L528.1 544C545.8 544 560.1 529.7 560.1 512C560.1 494.3 545.8 480 528.1 480L516.6 480L349.2 114.7zM394.8 368L245.2 368L320 204.8L394.8 368z"/></svg></a></li> - <li><a style="cursor: pointer;" data-tooltip="Settings" hx-get="/settings" hx-target="#modal-placeholder" hx-swap="innerHTML" class="secondary"><svg height="20pt" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M259.1 73.5C262.1 58.7 275.2 48 290.4 48L350.2 48C365.4 48 378.5 58.7 381.5 73.5L396 143.5C410.1 149.5 423.3 157.2 435.3 166.3L503.1 143.8C517.5 139 533.3 145 540.9 158.2L570.8 210C578.4 223.2 575.7 239.8 564.3 249.9L511 297.3C511.9 304.7 512.3 312.3 512.3 320C512.3 327.7 511.8 335.3 511 342.7L564.4 390.2C575.8 400.3 578.4 417 570.9 430.1L541 481.9C533.4 495 517.6 501.1 503.2 496.3L435.4 473.8C423.3 482.9 410.1 490.5 396.1 496.6L381.7 566.5C378.6 581.4 365.5 592 350.4 592L290.6 592C275.4 592 262.3 581.3 259.3 566.5L244.9 496.6C230.8 490.6 217.7 482.9 205.6 473.8L137.5 496.3C123.1 501.1 107.3 495.1 99.7 481.9L69.8 430.1C62.2 416.9 64.9 400.3 76.3 390.2L129.7 342.7C128.8 335.3 128.4 327.7 128.4 320C128.4 312.3 128.9 304.7 129.7 297.3L76.3 249.8C64.9 239.7 62.3 223 69.8 209.9L99.7 158.1C107.3 144.9 123.1 138.9 137.5 143.7L205.3 166.2C217.4 157.1 230.6 149.5 244.6 143.4L259.1 73.5zM320.3 400C364.5 399.8 400.2 363.9 400 319.7C399.8 275.5 363.9 239.8 319.7 240C275.5 240.2 239.8 276.1 240 320.3C240.2 364.5 276.1 400.2 320.3 400z"/></svg></a></li> + <li><a style="cursor: pointer;" data-tooltip="Settings" hx-get="/settings" hx-target="#modal-placeholder" hx-swap="innerHTML" preload class="secondary"><svg height="20pt" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M259.1 73.5C262.1 58.7 275.2 48 290.4 48L350.2 48C365.4 48 378.5 58.7 381.5 73.5L396 143.5C410.1 149.5 423.3 157.2 435.3 166.3L503.1 143.8C517.5 139 533.3 145 540.9 158.2L570.8 210C578.4 223.2 575.7 239.8 564.3 249.9L511 297.3C511.9 304.7 512.3 312.3 512.3 320C512.3 327.7 511.8 335.3 511 342.7L564.4 390.2C575.8 400.3 578.4 417 570.9 430.1L541 481.9C533.4 495 517.6 501.1 503.2 496.3L435.4 473.8C423.3 482.9 410.1 490.5 396.1 496.6L381.7 566.5C378.6 581.4 365.5 592 350.4 592L290.6 592C275.4 592 262.3 581.3 259.3 566.5L244.9 496.6C230.8 490.6 217.7 482.9 205.6 473.8L137.5 496.3C123.1 501.1 107.3 495.1 99.7 481.9L69.8 430.1C62.2 416.9 64.9 400.3 76.3 390.2L129.7 342.7C128.8 335.3 128.4 327.7 128.4 320C128.4 312.3 128.9 304.7 129.7 297.3L76.3 249.8C64.9 239.7 62.3 223 69.8 209.9L99.7 158.1C107.3 144.9 123.1 138.9 137.5 143.7L205.3 166.2C217.4 157.1 230.6 149.5 244.6 143.4L259.1 73.5zM320.3 400C364.5 399.8 400.2 363.9 400 319.7C399.8 275.5 363.9 239.8 319.7 240C275.5 240.2 239.8 276.1 240 320.3C240.2 364.5 276.1 400.2 320.3 400z"/></svg></a></li> </ul> </nav> @@ -18,7 +18,7 @@ <table> <tr> {% for category in categories %} - <th><div hx-get="/?category-id={{ category.id }}" hx-target="#news-cards" style="cursor: pointer;">{{ category.name }}</div></th> + <th><div hx-get="/?category-id={{ category.id }}" hx-target="#news-cards" preload style="cursor: pointer;">{{ category.name }}</div></th> {% endfor %} </tr> </table> diff --git a/src/simple_web_app/templates/load_more.html b/src/simple_web_app/templates/load_more.html @@ -1 +1 @@ -<button id="load-more-btn" {% if oob %}hx-swap-oob="true"{% endif %} hx-target="#news-cards" hx-swap="beforeend" hx-get="/?category-id={{ category_id }}&page={{ page + 1 }}&current_time={{ current_time }}" class="secondary">Load more</button> +<button id="load-more-btn" {% if oob %}hx-swap-oob="true"{% endif %} hx-target="#news-cards" hx-swap="beforeend" hx-get="/?category-id={{ category_id }}&page={{ page + 1 }}&current_time={{ current_time }}" preload class="secondary">Load more</button> diff --git a/src/simple_web_app/templates/news_card.html b/src/simple_web_app/templates/news_card.html @@ -2,7 +2,7 @@ <header> <nav><ul> {% for category in new.categories %} - <li><div style="cursor: pointer;" hx-get="/?category-id={{ category.id }}" hx-target="#news-cards"><small>{{ category.name }}</small></div></small></li> + <li><div style="cursor: pointer;" hx-get="/?category-id={{ category.id }}" hx-target="#news-cards" preload><small>{{ category.name }}</small></div></small></li> {% endfor %} </ul></nav> </header>