url_for_params

This commit is contained in:
Waylon Walker 2024-04-05 22:39:40 -05:00
parent 7bff037b78
commit 133b37c490
No known key found for this signature in database
GPG key ID: 66E2BF2B4190EFE4
5 changed files with 57 additions and 9 deletions

View file

@ -1,8 +1,5 @@
# htmx patterns
[![PyPI - Version](https://img.shields.io/pypi/v/htmx-patterns.svg)](https://pypi.org/project/htmx-patterns)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/htmx-patterns.svg)](https://pypi.org/project/htmx-patterns)
-----
**Table of Contents**
@ -13,7 +10,11 @@
## Installation
```console
pip install htmx-patterns
pip install git+https://github.com/waylonwalker/htmx-patterns
# or clone and pip install
git clone https://github.com/waylonwalker/htmx-patterns
pip install .
```
## License

View file

@ -1,11 +1,13 @@
import os
import urllib.parse
from datetime import datetime, timezone
from functools import lru_cache
from functools import lru_cache, partial
from typing import Any, Optional
from urllib.parse import quote_plus
import jinja2
from dotenv import load_dotenv
from fastapi import Request
from fastapi.templating import Jinja2Templates
from pydantic import BaseModel, Field
from pydantic_settings import BaseSettings, SettingsConfigDict
@ -37,6 +39,41 @@ def https_url_for(context: dict, name: str, **path_params: Any) -> str:
return str(http_url).replace("http", "https", 1)
@pass_context
def url_for_query(context: dict, name: str, **params: dict) -> str:
request = context["request"]
url = str(request.url_for(name))
if params == {}:
return url
from urllib.parse import parse_qs, urlencode, urlparse, urlunparse
# Parse the URL
parsed_url = urlparse(url)
# Parse the query parameters
query_params = parse_qs(parsed_url.query)
# Update the query parameters with the new ones
query_params.update(params)
# Rebuild the query string
updated_query_string = urlencode(query_params, doseq=True)
# Rebuild the URL with the updated query string
updated_url = urlunparse(
(
parsed_url.scheme,
parsed_url.netloc,
parsed_url.path,
parsed_url.params,
updated_query_string,
parsed_url.fragment,
)
)
return updated_url
def get_templates(config: BaseSettings) -> Jinja2Templates:
templates = Jinja2Templates(directory="templates")
templates.env.filters["quote_plus"] = lambda u: quote_plus(str(u))
@ -44,6 +81,7 @@ def get_templates(config: BaseSettings) -> Jinja2Templates:
u, tz=timezone.utc
).strftime("%B %d, %Y")
templates.env.globals["https_url_for"] = https_url_for
templates.env.globals["url_for"] = url_for_query
templates.env.globals["config"] = config
console.print(f'Using environment: {os.environ.get("ENV")}')

View file

@ -11,8 +11,8 @@ from htmx_patterns.infinite.models import PersonFactory
config = get_config()
@infinite_router.get("/persons")
async def get_persons(request: Request, page: int = 1, n: int = 10):
@infinite_router.get("/")
async def infinite(request: Request, page: int = 1, n: int = 10):
# simulated last page
if page == 5:
return config.templates.TemplateResponse(

View file

@ -9,4 +9,13 @@
A collection of HTMX patterns
</p>
<ul id="patterns" class="flex flex-col gap-4">
<li>
<a href="{{ url_for('infinite') }}"
class="cursor-pointer bg-red-500 hover:bg-red-600 text-white font-bold py-2 px-4 rounded">
Infinite Scroll
</a>
</li>
</ul>
{% endblock %}

View file

@ -1,7 +1,7 @@
{% for person in persons %}
{% if loop.last %}
<li hx-get="/infinite/persons?page={{ next_page }}" hx-trigger="intersect once" hx-target="#persons" hx-swap='beforeend'
hx-indicator="#persons-loading"
<li hx-get="{{ url_for('infinite', page=next_page) }}" hx-trigger="intersect once" hx-target="#persons"
hx-swap='beforeend' hx-indicator="#persons-loading"
class="cursor-pointer bg-red-500 hover:bg-red-600 text-white font-bold py-2 px-4 rounded">
{{ person.name }} -