url_for_params
This commit is contained in:
parent
7bff037b78
commit
133b37c490
5 changed files with 57 additions and 9 deletions
|
|
@ -1,8 +1,5 @@
|
||||||
# htmx patterns
|
# htmx patterns
|
||||||
|
|
||||||
[](https://pypi.org/project/htmx-patterns)
|
|
||||||
[](https://pypi.org/project/htmx-patterns)
|
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
|
||||||
**Table of Contents**
|
**Table of Contents**
|
||||||
|
|
@ -13,7 +10,11 @@
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```console
|
```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
|
## License
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
import os
|
import os
|
||||||
|
import urllib.parse
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from functools import lru_cache
|
from functools import lru_cache, partial
|
||||||
from typing import Any, Optional
|
from typing import Any, Optional
|
||||||
from urllib.parse import quote_plus
|
from urllib.parse import quote_plus
|
||||||
|
|
||||||
import jinja2
|
import jinja2
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
from fastapi import Request
|
||||||
from fastapi.templating import Jinja2Templates
|
from fastapi.templating import Jinja2Templates
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
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)
|
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:
|
def get_templates(config: BaseSettings) -> Jinja2Templates:
|
||||||
templates = Jinja2Templates(directory="templates")
|
templates = Jinja2Templates(directory="templates")
|
||||||
templates.env.filters["quote_plus"] = lambda u: quote_plus(str(u))
|
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
|
u, tz=timezone.utc
|
||||||
).strftime("%B %d, %Y")
|
).strftime("%B %d, %Y")
|
||||||
templates.env.globals["https_url_for"] = https_url_for
|
templates.env.globals["https_url_for"] = https_url_for
|
||||||
|
templates.env.globals["url_for"] = url_for_query
|
||||||
templates.env.globals["config"] = config
|
templates.env.globals["config"] = config
|
||||||
console.print(f'Using environment: {os.environ.get("ENV")}')
|
console.print(f'Using environment: {os.environ.get("ENV")}')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ from htmx_patterns.infinite.models import PersonFactory
|
||||||
config = get_config()
|
config = get_config()
|
||||||
|
|
||||||
|
|
||||||
@infinite_router.get("/persons")
|
@infinite_router.get("/")
|
||||||
async def get_persons(request: Request, page: int = 1, n: int = 10):
|
async def infinite(request: Request, page: int = 1, n: int = 10):
|
||||||
# simulated last page
|
# simulated last page
|
||||||
if page == 5:
|
if page == 5:
|
||||||
return config.templates.TemplateResponse(
|
return config.templates.TemplateResponse(
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,13 @@
|
||||||
A collection of HTMX patterns
|
A collection of HTMX patterns
|
||||||
</p>
|
</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 %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{% for person in persons %}
|
{% for person in persons %}
|
||||||
{% if loop.last %}
|
{% if loop.last %}
|
||||||
<li hx-get="/infinite/persons?page={{ next_page }}" hx-trigger="intersect once" hx-target="#persons" hx-swap='beforeend'
|
<li hx-get="{{ url_for('infinite', page=next_page) }}" hx-trigger="intersect once" hx-target="#persons"
|
||||||
hx-indicator="#persons-loading"
|
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">
|
class="cursor-pointer bg-red-500 hover:bg-red-600 text-white font-bold py-2 px-4 rounded">
|
||||||
|
|
||||||
{{ person.name }} -
|
{{ person.name }} -
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue