Coverage for src/lexigram/admin/lib/template/render.py: 20%
20 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 23:39 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 23:39 +0800
1"""Template utilities for lexigram-admin.
3Provides simple template rendering functions for standalone pages
4like login, error, etc. Uses StandaloneLayout for consistent styling.
5"""
7from typing import Any
9from markupsafe import escape
11from lexigram.admin.ui.layouts import (
12 StandaloneLayout,
13 StandaloneLayoutConfig,
14 StandaloneLayoutContext,
15)
18def render_template(
19 template_name: str,
20 context: dict[str, Any] | None = None,
21 **kwargs: Any,
22) -> str:
23 """Render a named template.
25 This is a simple fallback template renderer. For full template support,
26 use the Jinja2 integration in ui/templates_jinja.py.
28 Args:
29 template_name: Template name (used as title)
30 context: Template context
31 **kwargs: Additional context values
33 Returns:
34 HTML string
35 """
36 ctx = context or {}
37 ctx.update(kwargs)
39 title = ctx.get("title", template_name)
40 content = ctx.get("content", "")
42 # Include debug info when error template is requested
43 if template_name == "debug_error.html":
44 exc_type = ctx.get("exc_type", "")
45 exc_message = ctx.get("exc_message", "")
46 traceback = ctx.get("traceback", "")
47 traceback_plain = ctx.get("traceback_plain", "")
48 debug_html = f"""
49 <div class="error-details" style="margin-top: 1rem; padding: 1rem; background: #fef2f2; border: 1px solid #fecaca; border-radius: 4px;">
50 <h2 style="color: #b91c1c;">{escape(str(exc_type))}</h2>
51 <pre style="white-space: pre-wrap; word-break: break-word; font-family: monospace; font-size: 0.85rem; margin-top: 0.5rem;">{escape(str(exc_message))}</pre>
52 <details style="margin-top: 0.5rem;">
53 <summary style="cursor: pointer; font-weight: 500;">Traceback</summary>
54 <pre style="white-space: pre-wrap; word-break: break-word; font-family: monospace; font-size: 0.75rem; max-height: 400px; overflow: auto; margin-top: 0.25rem; background: #1f2937; color: #e5e7eb; padding: 0.75rem; border-radius: 4px;">{escape(str(traceback_plain))}</pre>
55 </details>
56 </div>
57 """
58 content = debug_html
60 config = StandaloneLayoutConfig(
61 show_footer=False,
62 show_logo=False,
63 centered=False,
64 )
65 layout_context = StandaloneLayoutContext(
66 page_title=title,
67 )
69 page_content = f"""
70 <main class="container" style="padding: 2rem;">
71 <h1>{escape(title)}</h1>
72 {content}
73 </main>
74 """
76 layout = StandaloneLayout(config=config, context=layout_context)
77 return layout.render(page_content)