input
input(name, label, type, allowed_chars, validate, placeholder, value, required, hint, resize)
type="text" - basic
{{ apep.macros.input("username", "Username") }}type="email" - required
{{ apep.macros.input("email", "Email Address", type="email", required=True, placeholder="you@example.com") }}type="password" + hint
{{ apep.macros.input("password", "Password", type="password", required=True, hint="At least 8 characters.") }}prefilled + allowed_chars
{{ apep.macros.input("code", "Access Code", value="ABC-", allowed_chars=["A-Z", "0-9", "-"]) }}resize="vertical" (textarea)
{{ apep.macros.input("message", "Message", resize="vertical", placeholder="Type here...") }}resize="both" + hint
{{ apep.macros.input("notes", "Notes", resize="both", hint="Drag the corner to resize.") }}lang_switch
lang_switch(current_lang, langs)
default (DE + EN), active=de
{{ apep.macros.lang_switch() }}default, active=en
{{ apep.macros.lang_switch(current_lang="en") }}4 custom langs, active=fr
{{ apep.macros.lang_switch(current_lang="fr", langs=[ {"code": "en", "label": "EN", "flag": "π¬π§"}, {"code": "de", "label": "DE", "flag": "π©πͺ"}, {"code": "fr", "label": "FR", "flag": "π«π·"}, {"code": "es", "label": "ES", "flag": "πͺπΈ"} ]) }}no flags
{{ apep.macros.lang_switch(current_lang="en", langs=[ {"code": "en", "label": "English"}, {"code": "de", "label": "Deutsch"} ]) }}progress_bar
progress_bar(value, max, id, label, show_value, variant) - JS demo via ApepProgress.set(id, value)
variant="default" - 60%
{{ apep.macros.progress_bar(60) }}variant="success" + label + show_value
{{ apep.macros.progress_bar(80, label="Upload", show_value=True, variant="success") }}variant="warning" - 45 / 200
{{ apep.macros.progress_bar(45, max=200, label="Storage", show_value=True, variant="warning") }}variant="danger" - nearly full
{{ apep.macros.progress_bar(95, label="Quota", show_value=True, variant="danger") }}0% start
{{ apep.macros.progress_bar(0, label="Initializing...") }}JS-controlled via ApepProgress.set("js-bar", value)
{{ apep.macros.progress_bar(20, id="js-bar", label="JS-controlled bar", show_value=True, variant="success") }}radio
radio(name, options, selected)
none selected
{{ apep.macros.radio("plan", [ {"label": "Free"}, {"label": "Pro"}, {"label": "Enterprise"} ]) }}selected via option.checked
{{ apep.macros.radio("size", [ {"label": "Small"}, {"label": "Medium", "checked": True}, {"label": "Large"} ]) }}selected param overrides checked
{{ apep.macros.radio("color", [ {"label": "Red", "value": "red"}, {"label": "Green", "value": "green", "checked": True}, {"label": "Blue", "value": "blue"} ], selected="blue") }}range_slider
range_slider(name, label, min, max, value, step, unit, hint)
basic 0-100
{{ apep.macros.range_slider("volume", "Volume") }}unit="%" + prefilled value=75
{{ apep.macros.range_slider("opacity", "Opacity", min=0, max=100, value=75, unit="%") }}step=50 + unit="β¬" + hint
{{ apep.macros.range_slider("budget", "Monthly Budget", min=0, max=1000, value=250, step=50, unit="β¬", hint="Adjust in 50 β¬ increments.") }}narrow range 1-10, unit="β "
{{ apep.macros.range_slider("rating", "Rating", min=1, max=10, value=7, unit="β ") }}unit="px" - font size 8-72
{{ apep.macros.range_slider("font_size", "Font Size", min=8, max=72, value=16, unit="px") }}review_card
review_card(text, author, role, rating, avatar, logo, date, expandable, expand_text, collapse_text)
text only
{{ apep.macros.review_card("Fantastic product, highly recommended!") }}rating + author + role
{{ apep.macros.review_card( "This macro system saved our team weeks of work.", author="Jane Doe", role="Lead Developer", rating=5 ) }}rating + date
{{ apep.macros.review_card( "Solid and predictable. Exactly what a component system should be.", author="Max MΓΌller", rating=4, date="March 2025" ) }}short - 1 star - author only
{{ apep.macros.review_card( "Not for me.", author="Anonymous", rating=1 ) }}all fields - no expandable
{{ apep.macros.review_card( "Everything works exactly as documented. The team behind this clearly cares about DX. Just a lil to long...", author="Petra V.", role="Engineering Manager", rating=5, date="April 2025" ) }}expandable - long text
{{ apep.macros.review_card( "I have been using APEP for six months now and can honestly say it has fundamentally changed how we build templates. The macro system is intuitive, composable, and the server-side rendering means zero client-side bloat. The breadcrumb, nav, and form components have saved us enormous time. We migrated from a custom framework in under a week. I could go on, but the short version is: if you build Jinja2 apps, use this.", author="Sofia Ricci", role="Fullstack Engineer", rating=5, expand_text="Read full review", collapse_text="Collapse" ) }}expandable - medium text
{{ apep.macros.review_card( "Genuinely surprised by how polished this is for an open-source project. The date picker alone saved us two days of work. Minor gripe: some edge-case docs are thin. Overall very strong.", author="Lars B.", role="Backend Dev", rating=4, date="May 2025", expand_text="More", collapse_text="Less" ) }}3 stars - balanced review
{{ apep.macros.review_card( "Good bones but the documentation needs work in places. Found a few inconsistencies between what the docs say and what the macros actually do. Team is responsive on GitHub though.", author="Kim P.", rating=3, date="Feb 2025" ) }}review_gallery
review_gallery(reviews, expand_text, collapse_text)
6 reviews - mix of short and medium - carousel with arrows + dots
{{ apep.macros.review_gallery([ {"text": "Excellent quality and great support.", "author": "Anna K.", "rating": 5}, {"text": "Works right out of the box. Recommended.", "author": "Ben S.", "rating": 4, "date": "Jan 2025"}, {"text": "Great docs, fast support from the team.", "author": "Carla M.", "role": "CTO", "rating": 5}, {"text": "Saved us weeks. Macro system is excellent.", "author": "David R.", "role": "Senior Dev", "rating": 5, "date": "Mar 2025"}, {"text": "Not perfect but very close. Would recommend with minor reservations about edge-case handling.", "author": "Elena S.", "rating": 3}, {"text": "We replaced three custom components in one afternoon. Deployment was smooth.", "author": "Frank T.", "role": "DevOps Lead", "rating": 4, "date": "Apr 2025"} ]) }}5 reviews - mix of expandable long and short - custom expand/collapse labels
{{ apep.macros.review_gallery([ { "text": "This is a longer review that goes into significant detail about how the product performs under real-world conditions, including edge cases and performance benchmarks not mentioned in the official docs. Truly impressive engineering. We ran it on a project with 40k daily users and had zero issues.", "author": "Tom H.", "rating": 4, }, { "text": "Short one: it just works.", "author": "Mia W.", "rating": 5, "date": "June 2025" }, { "text": "The component library is incredibly well thought out. We migrated from a custom CSS framework in under a week and our team was productive almost immediately. The only minor critique is that edge case documentation could be expanded slightly. The form validation, in particular, has a few undocumented behaviours that took us a while to figure out.", "author": "Linda Z.", "role": "Frontend Architect", "rating": 5, }, { "text": "Decent. Does what it says.", "author": "Nils R.", "rating": 3 }, { "text": "After evaluating four different component systems for our Jinja2 stack, APEP was the clear winner. The server-side rendering approach means our pages are fast even on slow connections, and the macro API is consistent enough that new team members pick it up in hours rather than days. We have been running it in production for three months with no regressions.", "author": "Olivia M.", "role": "Engineering Director", "rating": 5, "date": "May 2025", } ], expand_text="Show more", collapse_text="Show less") }}sidescroller
sidescroller(items)
9 images with labels - mix of short and long label text - scroll left/right
{{ apep.macros.sidescroller([ {"src": "/apep-static/images/examples/unsplash1.svg", "alt": "Scene 1", "label": "Forest"}, {"src": "/apep-static/images/examples/unsplash2.svg", "alt": "Scene 2", "label": "Mountain Range"}, {"src": "/apep-static/images/examples/unsplash3.svg", "alt": "Scene 3", "label": "Ocean"}, {"src": "/apep-static/images/examples/unsplash4.svg", "alt": "Scene 4", "label": "Desert at Dusk"}, {"src": "/apep-static/images/examples/unsplash5.svg", "alt": "Scene 5", "label": "Jungle"}, {"src": "/apep-static/images/examples/unsplash6.svg", "alt": "Scene 6", "label": "Tundra"}, {"src": "/apep-static/images/examples/unsplash7.svg", "alt": "Scene 7", "label": "Volcanic Landscape"}, {"src": "/apep-static/images/examples/unsplash8.svg", "alt": "Scene 8", "label": "Coastal Cliffs"}, {"src": "/apep-static/images/examples/unsplash9.svg", "alt": "Scene 9", "label": "Night Sky"} ]) }}9 items - overlay=True - mix of long and short captions - click to open fullscreen
{{ apep.macros.sidescroller([ {"src": "/apep-static/images/examples/unsplash1.svg", "alt": "Scene 1", "overlay": True, "caption": "Waterfall at dusk - a long hike but absolutely worth every step of the trail"}, {"src": "/apep-static/images/examples/unsplash2.svg", "alt": "Scene 2", "overlay": True, "caption": "Summit view"}, {"src": "/apep-static/images/examples/unsplash3.svg", "alt": "Scene 3", "overlay": True}, {"src": "/apep-static/images/examples/unsplash4.svg", "alt": "Scene 4", "overlay": True, "caption": "Forest at dawn, shot on a cold October morning with a 24mm prime lens"}, {"src": "/apep-static/images/examples/unsplash5.svg", "alt": "Scene 5", "overlay": True, "caption": "Desert"}, {"src": "/apep-static/images/examples/unsplash6.svg", "alt": "Scene 6", "overlay": True, "caption": "Frozen lake"}, {"src": "/apep-static/images/examples/unsplash7.svg", "alt": "Scene 7", "overlay": True}, {"src": "/apep-static/images/examples/unsplash8.svg", "alt": "Scene 8", "overlay": True, "caption": "Rocky coastline at low tide"}, {"src": "/apep-static/images/examples/unsplash9.svg", "alt": "Scene 9", "overlay": True, "caption": "Milky Way above the ridge - 25 second exposure, ISO 3200"} ]) }}6 linked items - click opens url - mix of label lengths
{{ apep.macros.sidescroller([ {"src": "/apep-static/images/examples/unsplash2.svg", "alt": "Link 1", "url": "https://example.com/1", "label": "Link A"}, {"src": "/apep-static/images/examples/unsplash3.svg", "alt": "Link 2", "url": "https://example.com/2", "label": "Product Overview Page"}, {"src": "/apep-static/images/examples/unsplash4.svg", "alt": "Link 3", "url": "https://example.com/3", "label": "Link C"}, {"src": "/apep-static/images/examples/unsplash5.svg", "alt": "Link 4", "url": "https://example.com/4", "label": "Documentation & Guides"}, {"src": "/apep-static/images/examples/unsplash6.svg", "alt": "Link 5", "url": "https://example.com/5", "label": "D"}, {"src": "/apep-static/images/examples/unsplash7.svg", "alt": "Link 6", "url": "https://example.com/6", "label": "Community Forum"} ]) }}split_group
split_group(items, gap)
2 columns - gap="md", no dividers
{% set _col1 %}Left column content.
{% endset %} {% set _col2 %}Right column content.
{% endset %} {{ apep.macros.split_group([ {"content": _col1}, {"content": _col2} ]) }}3 columns - pos_divider right / right / none
{% set _a %}Alpha
First section.
Beta
Second section.
Gamma
Third section.
gap="sm"
{% set _x %}Narrow gap left.
{% endset %} {% set _y %}Narrow gap right.
{% endset %} {{ apep.macros.split_group([{"content": _x}, {"content": _y}], gap="sm") }}gap="lg"
{% set _p %}Wide gap left.
{% endset %} {% set _q %}Wide gap right.
{% endset %} {{ apep.macros.split_group([{"content": _p}, {"content": _q}], gap="lg") }}stepper
stepper(steps, current)
current=1 (first active)
{{ apep.macros.stepper([ {"label": "Account"}, {"label": "Profile"}, {"label": "Review"}, {"label": "Done"} ], current=1) }}current=3 (two done, one active)
{{ apep.macros.stepper([ {"label": "Account"}, {"label": "Profile"}, {"label": "Review"}, {"label": "Done"} ], current=3) }}all done (current beyond last step)
{{ apep.macros.stepper([ {"label": "Account"}, {"label": "Profile"}, {"label": "Review"}, {"label": "Done"} ], current=5) }}with detail tooltips - hover over step markers
{{ apep.macros.stepper([ {"label": "Account", "detail": "Enter your email and password."}, {"label": "Billing", "detail": "Add a payment method."}, {"label": "Confirm", "detail": "Review your order summary."}, {"label": "Complete", "detail": "You're done!"} ], current=2) }}text_block
text_block(text, min_width, max_width, min_height, max_height, scroll, variant)
variant="default"
{{ apep.macros.text_block("This is a default text block with no scroll.
") }}variant="plain"
{{ apep.macros.text_block("Plain variant - no decorative border/background.
", variant="plain") }}scroll="vertical" + max_height=120px
{{ apep.macros.text_block( "Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
Line 7
", max_height="120px", scroll="vertical" ) }}scroll="horizontal" (long single line)
{{ apep.macros.text_block( "This is a very very very very very very very long horizontal text that overflows intentionally.
", max_width="300px", scroll="horizontal" ) }}min/max_width + rich HTML
{{ apep.macros.text_block( "Paragraphs, bold, italic.
theme_switch
theme_switch(variant) - floating variant omitted, fixed positioning does not work in showcase context
variant="icon"
{{ apep.macros.theme_switch(variant="icon") }}variant="slider"
{{ apep.macros.theme_switch(variant="slider") }}timeline
timeline(items, direction="right", same_side=False)
default (direction="right") - 8 items - scroll left/right
direction="right" - same_side=True - 8 items
direction="down" - alternating - 8 items - scroll up/down
direction="down" - same_side=True - 8 items
direction="right" - detail tooltips - hover markers
toast_container
toast_container(position) - ApepToast.show(message, variant, duration)
all variants - toast always appears at the container position (here: bottom-right)
JS API - ApepToast.show()
// Basic - info toast, auto-closes after 4 seconds (default)
ApepToast.show("Saved successfully!")
// With variant - "info" | "success" | "warning" | "danger"
ApepToast.show("File uploaded.", "success")
ApepToast.show("Low disk space.", "warning", 6000)
ApepToast.show("Something went wrong.", "danger")
// Permanent - duration=0, user must click Γ to dismiss
ApepToast.show("Action required.", "warning", 0)
Macro: toast_container(position) - include once per page, ideally before </body>. Available positions: top-right, top-left, top-center, bottom-right, bottom-left, bottom-center.
toggle
toggle(name, label, checked, disabled, hint)
unchecked (default)
{{ apep.macros.toggle("notifications", "Enable notifications") }}checked=True
{{ apep.macros.toggle("dark_mode", "Dark mode", checked=True) }}disabled + unchecked
{{ apep.macros.toggle("beta", "Beta features", disabled=True) }}disabled + checked
{{ apep.macros.toggle("admin", "Admin access", checked=True, disabled=True) }}with hint
{{ apep.macros.toggle("marketing", "Marketing emails", hint="You can unsubscribe at any time.") }}