From 133b37c490c6759bdc3c95c431c85b8dbd5e38be Mon Sep 17 00:00:00 2001
From: "Waylon S. Walker"
Date: Fri, 5 Apr 2024 22:39:40 -0500
Subject: [PATCH] url_for_params
---
README.md | 9 +++---
htmx_patterns/config.py | 40 ++++++++++++++++++++++++-
htmx_patterns/infinite/router.py | 4 +--
templates/index.html | 9 ++++++
templates/infinite/persons_partial.html | 4 +--
5 files changed, 57 insertions(+), 9 deletions(-)
diff --git a/README.md b/README.md
index cc10cf7..d8a9a54 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,5 @@
# htmx patterns
-[](https://pypi.org/project/htmx-patterns)
-[](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
diff --git a/htmx_patterns/config.py b/htmx_patterns/config.py
index a3906e5..4df6aa8 100644
--- a/htmx_patterns/config.py
+++ b/htmx_patterns/config.py
@@ -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")}')
diff --git a/htmx_patterns/infinite/router.py b/htmx_patterns/infinite/router.py
index 72fe7bb..c9ee302 100644
--- a/htmx_patterns/infinite/router.py
+++ b/htmx_patterns/infinite/router.py
@@ -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(
diff --git a/templates/index.html b/templates/index.html
index 0b662ca..b683019 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -9,4 +9,13 @@
A collection of HTMX patterns
+
+
{% endblock %}
diff --git a/templates/infinite/persons_partial.html b/templates/infinite/persons_partial.html
index d8e99d0..c4a934f 100644
--- a/templates/infinite/persons_partial.html
+++ b/templates/infinite/persons_partial.html
@@ -1,7 +1,7 @@
{% for person in persons %}
{% if loop.last %}
-
{{ person.name }} -