Add queryloop smart tag: query-driven post/page card listings
Add queryloop smart tag: query-driven post/page card listings
#35 in Riparion/riparion-cms — merged 2026-06-02
Summary
A new [[component:queryloop query="…"]] smart-tag embed that parses an author-written pseudo-SQL query into a typed boolean AST and renders the matching posts or pages as paginated summary cards.
Example:
[[component:queryloop query="select posts where category=foo and (tag=a or tag=b) order_by_desc=published_date take=6"]]
Grammar (full boolean expression; precedence not > and > or):
select posts|pages [where <bool expr over category=/tag=>]
[order_by[_desc]=published_date|created_date|title] [take=N]
What's included
- Parser/AST (
src/embeds/queryloop.rs): tokenizer + recursive-descent parser withand/or/not, parentheses, and precedence. Non-gated (cfg(any(server, web))likemdx.rs) so the wasm editor validates inline;QueryLoopcomponent holds a per-instancepagesignal +PaginationBar(multiple loops in one body paginate independently). - DB builders (
queryloop_posts_db/queryloop_pages_db): compose SQL only from whitelisted fragments and bind every literal as$N(thefacet_clausediscipline — no author string ever reaches SQL text); return(items, total)via aCOUNTcompanion for the pager. - Server fn
#[post("/api/queryloop")]: re-parses as the authoritative security boundary, dispatches, attaches responsive srcsets. - Wire types
QueryLoopItems/QueryLoopResult+PageCard/From<Page>; newPageCardView(links pages bypath) and widget re-exports. - Registered in
EmbedBlock+ theSMART_TAGSslash menu. - CSS fix: the hand-rolled
.prose *rules now honornot-prose, so embed cards (and any embed with links/headings/images) no longer inherit article typography — fixes the accent-colored card title/author links reported in review.
Decisions
[[component:…]]grammar (no coremdx.rschange), full boolean AST, paged prev/next — all per request.- v1 scope cuts (documented in code): page cards skip image
srcsetrenditions;not category=xexcludes posts with no category.
Tests / checks
- 8 parser unit tests + 3 DB-builder tests (
server::tests::queryloop). Extendedtest_poolwith theuserscard columns +pagestable. - Passes
cargo fmt --check, clippy-D warningsonserver,sqlite+server,postgres(--all-targets) and the wasm32 client, andcargo test --features server,sqlite. - Manual E2E steps captured in
TODO_VERIFICATION.md(gitignored).
🤖 Generated with Claude Code
Last updated 2026-06-03
Links to this note
Credits
Merged pull requests, newest first.