Helpers
AjaxCMS uses helpers to simplify inserting dynamic content and complex code. Helpers use a double-brace syntax: {{helper | param1 | param2 | ...}}. Parameters are separated by the pipe | character and processed in sequential order. Trailing parameters can be omitted if not needed.
Before a page is displayed, helpers are replaced with the appropriate HTML content.
Helper Syntax Rules
Displaying Helper Code in Documentation
Helper syntax inside code blocks (using backticks ` or triple backticks ```) is automatically protected from processing. This allows you to show helper examples in documentation without them being executed.
Example:
Use `{{a | home}}` to create a link to the home page.
The helper syntax above will display as-is in code blocks, not be processed.
Legacy method: Helpers with five or more sequential spaces are also skipped for backward compatibility, but this is no longer necessary with automatic code block protection.
HTML Attributes
All helpers (except {{insert}}) support attribute parameters using the => syntax. These inject HTML attributes into the generated element.
Format: attr=>value becomes attr="value" in the output HTML
Example:
{{a | documentation | class=>btn btn-primary | id=>nav-link}}
Becomes:
<a class="btn btn-primary" id="nav-link"
onclick="loadPage('./pages/menus/01-Documentation/02-Helpers.md')">
documentation
</a>
This works for any HTML attribute: class, id, style, data-*, aria-*, etc.
Markdown Support
Pages with .md extensions are processed through the marked Markdown parser (GitHub-flavored). See the GitHub Markdown Guide for syntax reference.
Available Helpers
Anchor (Link)
Syntax: {{a | page | link_text | alt_text}}
Creates an internal link that loads a page via AJAX without refreshing the browser. Uses partial matching to find pages, so you only need to specify enough of the filename to uniquely identify it.
Parameters:
page(required) - Page filename or partial match (e.g., "test" matches "./pages/menus/test.html")link_text(optional) - Display text for the link (defaults to page name)alt_text(optional) - Alt/title attribute text
Examples:
{{a | 01-Getting_Started.md}}
{{a | 01-Getting_Started.md | Get Started}}
{{a | 01-Getting_Started.md | Get Started | Getting Started Guide}}
With attributes:
{{a | home | Home Page | class=>nav-link active}}
Why use this instead of <a>?
Regular HTML anchor tags (<a href="...">) cause full page reloads. The {{a}} helper creates links that load content via AJAX with smooth page transitions.
Image
Syntax: {{i | image | alt_text}}
Inserts an image from the images/ directory. Uses partial matching, so you only need enough of the filename to uniquely identify it.
Parameters:
image(required) - Image filename, partial match, or wildcard pattern (e.g., "logo", "vacation/", "photos/2024-")alt_text(optional) - Alt attribute for accessibility
Examples:
{{i | logo}}
{{i | logo | Company Logo}}
{{i | vacation/colorado.jpg | Mountain View}}
With CSS classes:
{{i | logo | Company Logo | class=>img-fluid rounded}}
Built-in CSS classes (defined in index.html):
- Size:
icon(70px),thumb(20px),small(300px),medium(600px),large(900px) - Position:
left,right
Example with built-in classes:
{{i | photo | class=>medium left}}
Wildcard Support:
The image helper supports wildcards (*) to match multiple images. When a wildcard pattern is used, it automatically creates a responsive Bootstrap grid gallery.
Syntax: {{i | pattern | alt_text_or_per_row | per_row}}
Parameters:
pattern(required) - Image pattern with wildcard (e.g.,vacation/*)alt_text_or_per_row(optional) - Either alt text (string) OR images per row (number). Default: 3 per rowper_row(optional) - Number of images per row (1-12). Only used if second param is alt text
Wildcard examples:
{{i | vacation/*}} ← Gallery with 3 images per row (default)
{{i | vacation/* | 4}} ← Gallery with 4 images per row
{{i | vacation/* | Vacation Photos}} ← Gallery with custom alt text, 3 per row
{{i | vacation/* | Vacation Photos | 5}} ← Gallery with alt text and 5 per row
How wildcards work:
*matches any characters in the pathvacation/*matches all images in thevacation/directoryvacation/test*matches images starting with "test" invacation/directory- Creates a responsive Bootstrap grid gallery using
rowandcol-md-*classes - Default: 3 images per row (adjust with numeric parameter)
- Images use
img-fluidclass for responsive sizing - If no images match the pattern, an error message is displayed
Carousel (Slideshow)
Syntax: {{carousel:interval | image1:alt1:caption1 | image2:alt2:caption2 | ...}}
Creates a Bootstrap 5 carousel slideshow with multiple images. Supports unlimited slides.
Parameters:
interval(optional) - Milliseconds between slides (e.g.,5000= 5 seconds). If omitted, uses Bootstrap default (5000ms)- Each slide:
image:alt:captionseparated by|image(required) - Image filename, partial match, or wildcard patternalt(optional) - Alt text for accessibilitycaption(optional) - Text overlay (can include HTML like<h3>Title</h3>)
Examples:
Basic carousel (3 slides, 5-second interval):
{{carousel:5000 | slide1.jpg | slide2.jpg | slide3.jpg}}
With alt text:
{{carousel:3000 | beach.jpg:Sunset at the beach | mountain.jpg:Mountain peak}}
With captions (HTML allowed):
{{carousel:4000 | product1.jpg:Product Image:<h3>New Arrival</h3><p>Check out our latest product</p> | product2.jpg:Product Image:<h3>Best Seller</h3><p>Our most popular item</p>}}
With CSS classes:
{{carousel:5000 | img1 | img2 | img3 | class=>carousel-fade}}
Wildcard Support:
Individual slide parameters can use wildcards (*) to match multiple images. Each matched image becomes a separate slide.
Wildcard examples:
{{carousel:5000 | vacation/*}} ← All images in vacation/ folder
{{carousel:3000 | vacation/*:Vacation Photo}} ← All with same alt text
{{carousel:4000 | photos/2024-*::Trip to Europe}} ← All with same caption
{{carousel:5000 | vacation/* | photos/city* | nature.jpg}} ← Mix wildcards and specific images
How wildcards work:
- Each wildcard pattern expands into multiple slides
- If you specify
altorcaption, they apply to all images matched by that pattern - Wildcards can be combined with regular image specifications in the same carousel
- Example:
vacation/*:My Vacationcreates one slide per image invacation/, all with alt text "My Vacation"
Insert
Syntax: {{insert | page_name | allow_scripts}}
Embeds the content of another page at the helper location. The inserted page includes any layout.html that applies to it. Inserts can be nested (inserted pages can contain other inserts).
Parameters:
page_name(required) - Page filename or partial matchallow_scripts(optional) - Boolean, defaults totrue. Set tofalseto strip<script>tags
Examples:
{{insert | sidebar}}
{{insert | header}}
{{insert | footer | false}}
Use cases:
- Embed common content (headers, footers, sidebars) into layouts
- Insert formatted content into pages without layouts
- Create reusable content blocks
Note: The {{insert}} helper does NOT support attribute parameters. To add attributes, wrap it manually:
<div id="sidebar" class="col-md-4">
{{insert | sidebar_content}}
</div>
File List
Syntax: {{filelist | directory_path}}
Generates a hierarchical menu from a directory and all its subdirectories. Uses standard HTML list format (<ul>, <li>).
Parameters:
directory_path(required) - Path relative to site root (e.g.,./pages/docs)
Example:
{{filelist | ./pages/tutorials}}
Use cases:
- Create vertical navigation menus
- Display file/folder structures
- Generate dynamic content indexes
Blog
Syntax: {{blog | directory | start | stop}}
Displays blog entries as expandable summaries. Entries load full content via AJAX when clicked. Blog files must follow a specific naming convention.
Parameters:
directory(required) - Path to blog posts directorystart(optional) - First post index to display (for pagination)stop(optional) - Last post index to display (for pagination)
Blog file naming convention:
YYYY-MM-DD-Title.md
YYYY-MM-DD-Title.html
YYYY-MM-DD-n-Title.md (n = optional number for multiple posts per day)
Examples:
2024-01-15-Hello_World.md
2024-01-15-1-Morning_Post.md
2024-01-15-2-Evening_Post.md
Usage:
{{blog | ./pages/blog}}
{{blog | ./pages/blog | 0 | 5}} ← Show first 5 posts
{{blog | ./pages/blog | 5 | 10}} ← Show posts 5-10 (pagination)
How it works:
- Displays post title, date, and excerpt
- Clicking a post loads full content in place
- Automatically sorts by date (newest first)
Blog List
Syntax: {{bloglist | directory | start | stop}}
Displays a simple list of blog post titles with links. Similar to {{blog}} but shows only titles without excerpts or expansion.
Parameters:
directory(required) - Path to blog posts directorystart(optional) - First post index to displaystop(optional) - Last post index to display
Blog file naming: Same as {{blog}} - must use YYYY-MM-DD-Title format
Examples:
{{bloglist | ./pages/blog}}
{{bloglist | ./pages/blog | 0 | 10}} ← Show first 10 post titles
Use case: Create a compact blog archive or sidebar widget
Form
Syntax: {{form | filename | field1 | field2 | field3 | ...}}
Creates a simple form that saves submissions to a CSV file. Useful for contact forms, newsletter signups, surveys, and other data collection.
Parameters:
filename(required) - Name for the CSV file (without extension). Only alphanumeric characters, dashes, and underscores allowedfield1, field2, ...(required) - Field names to display as form labels. At least one field is required
Examples:
{{form | contact | Name | Email | Message}}
{{form | newsletter | Name | Email}}
{{form | survey | Name | Favorite Color | Comments}}
With CSS classes:
{{form | contact | Name | Email | class=>my-custom-form}}
How it works:
- Form submissions are saved to
files/filename.csvin your site directory - Each submission includes a timestamp and the submitter's IP address
- CSV file is created automatically on first submission
- Subsequent submissions are appended as new rows
- Success/error messages are displayed to the user after submission
Viewing submissions:
Visit the CSV file URL directly to see submissions as a formatted HTML table:
http://yoursite.com/files/contact.csv
Features:
- Styled HTML table with all submissions
- Submission count
- "Download CSV" button for raw file download
- Add
?download=1to URL for direct CSV download
Security:
- All displayed values are HTML-escaped to prevent XSS attacks
- CSV injection protection: values starting with
=,+,-,@are prefixed with single quote - The
files/directory is hidden from directory listings - files are only accessible by direct URL - Filenames are sanitized to prevent path traversal attacks
Helper Reference Quick Guide
| Helper | Purpose | Example |
|---|---|---|
{{a}} |
Internal link | {{a | page | text}} |
{{i}} |
Image | {{i | image | alt}} |
{{carousel}} |
Slideshow | {{carousel:5000 | img1 | img2}} |
{{insert}} |
Embed page | {{insert | page}} |
{{filelist}} |
Directory tree | {{filelist | ./pages/docs}} |
{{blog}} |
Blog with excerpts | {{blog | ./pages/blog | 0 | 5}} |
{{bloglist}} |
Blog titles only | {{bloglist | ./pages/blog}} |
{{form}} |
Form to CSV | {{form | contact | Name | Email}} |
Next Steps
- {{a | 03-Layouts.md | Learn about layouts}} to create multi-column page templates
- {{a | 01-Getting_Started.md | Return to Getting Started}} guide
- View example helper usage in the {{a | ../02-Examples | Examples section}}