from contextlib import contextmanager from urllib.parse import unquote from html5tagger import Builder, E # type: ignore from sanic import Request from webapp.display.search.search import Searcher from ..base import BaseRenderer from ..layouts.main import MainLayout class SearchRenderer(BaseRenderer): def render( self, request: Request, language: str, searcher: Searcher, full: bool ) -> Builder: builder = self.get_builder( full=request.headers.get("HX-Request") is None, language=language, ) self._body(request, builder, language, searcher, full) return builder def _body( self, request: Request, builder: Builder, language: str, searcher: Searcher, full: bool, ): with self._base(request, builder, full): builder.h1("Search") self._results(request, builder, searcher, language) @contextmanager def _base(self, request: Request, builder: Builder, full: bool): layout = MainLayout(builder) with layout(request, full): yield def _results( self, request: Request, builder: Builder, searcher: Searcher, language: str, ): query = unquote(request.args.get("q", "")) results = searcher.search(query, language) if not query or not results: builder.p("No results found") return with builder.div(class_="container"): with builder.ul(): for _, doc in results: builder.li( E.a( doc.title, href=f"/{doc.page.relative_path}", hx_get=f"/{doc.page.relative_path}", hx_target="#content", hx_swap="innerHTML", hx_push_url="true", ), f" - {doc.page.relative_path}", )