Skip to content

Twig Render Reference

The render adapter generates complete HTML output for images, galleries, pagination, and other UI components. For URL-only access, see cms.media.

Render a complete <img> tag with ImageWorks URL, dimensions, alt text, and lazy loading.

{# Basic image #}
{{ cms.render.image('hero') }}
{# With ImageWorks transformations #}
{{ cms.render.image('hero', {w: 800, h: 600, fit: 'crop'}) }}
{# Custom collection and property #}
{{ cms.render.image('widget', {}, {collection: 'products', property: 'photo'}) }}
{# Pass object directly (recommended) #}
{{ cms.render.image(product, {w: 600}, {collection: 'products', property: 'image'}) }}
{# Eager loading (default is lazy) #}
{{ cms.render.image('hero', {}, {loading: 'eager'}) }}
ParameterTypeDefaultDescription
idOrObjectstring|array|nullrequiredObject ID or full object data
imageworksarray[]ImageWorks transformation parameters
optionsarray[]Options: collection, property, loading

Get the alt text for an image. Falls back through alt text, EXIF data, then filename.

{{ cms.render.alt('hero') }}
{{ cms.render.alt(product, {collection: 'products', property: 'image'}) }}

Render a complete gallery grid with LightGallery lightbox support.

{# Default gallery (300x200 thumbnails) #}
{{ cms.render.gallery('vacation') }}
{# Custom thumbnail size #}
{{ cms.render.gallery('vacation', {w: 150, h: 150}) }}
{# Thumbnail and full-size settings #}
{{ cms.render.gallery('vacation', {w: 150}, {w: 1200}) }}
{# With options #}
{{ cms.render.gallery('vacation', {w: 200}, {}, {
maxVisible: 8,
viewAllText: 'Show all photos',
loop: true,
download: false,
captions: true,
gridCaptions: true,
sort: 'name',
class: 'my-gallery'
}) }}

Gallery Options:

OptionTypeDefaultDescription
collectionstring'gallery'Collection identifier
propertystring'gallery'Property name
maxVisibleint0Max visible thumbnails (0 = all)
viewAllTextstring'View All'Text for the “view all” button
captionsbool|stringfalseLightbox captions: true for default, or a template string
gridCaptionsbool|stringfalseGrid captions below thumbnails
sortstring|array''Sort property (prefix with - for descending) or array of sort rules
classstring''CSS class on the gallery container
loopbooltrueLoop gallery in lightbox
downloadbooltrueShow download button in lightbox
counterbooltrueShow image counter
pluginsarray['zoom','thumbnail','fullscreen']LightGallery plugins

For caption templates and sorting details, see totalcms.md.

Generate a hidden template element with gallery data for programmatic lightbox initialization. Use this when you want custom trigger elements instead of the default grid.

{{ cms.render.galleryLauncher('vacation') }}
<button data-gallery="gallery-vacation">View Photos</button>
{# With settings #}
{{ cms.render.galleryLauncher('vacation', {w: 300}, {w: 1920}, {
captions: true,
trigger: '.gallery-thumb',
loop: true,
download: false
}) }}

Additional Launcher Options:

OptionTypeDefaultDescription
triggerstring''CSS selector for trigger elements
galleryIdstringautoCustom gallery ID (default: {collection}-{id})
sortstring''Sort images by field (e.g., name, -name for descending)
includestring''Include filter — only images matching ALL criteria (e.g., tags:landscape,featured:true)
excludestring''Exclude filter — remove images matching ANY criteria (e.g., tags:archived)
searchstring''Full-text search across all image fields
{# Filter to only landscape-tagged images #}
{{ cms.render.galleryLauncher('vacation', {w: 300}, {w: 1920}, {
include: 'tags:landscape'
}) }}
{# Exclude archived images, sorted by name #}
{{ cms.render.galleryLauncher('vacation', {w: 300}, {w: 1920}, {
exclude: 'tags:archived',
sort: 'name'
}) }}
{# Search for images matching "sunset" #}
{{ cms.render.galleryLauncher('vacation', {w: 300}, {w: 1920}, {
search: 'sunset'
}) }}

Filtering uses the same syntax as Index Filtering, including wildcard patterns for flexible string matching.

For complete launcher usage with trigger methods and opening at specific images, see totalcms.md.

Render a single gallery image as an <img> tag with LightGallery integration attributes (data-gallery, data-gallery-image).

{# By filename #}
{{ cms.render.galleryImage('vacation', 'sunset.jpg', {w: 300, h: 200}) }}
{# Dynamic selectors #}
{{ cms.render.galleryImage('vacation', 'first', {w: 400}) }}
{{ cms.render.galleryImage('vacation', 'last') }}
{{ cms.render.galleryImage('vacation', 'random') }}
{{ cms.render.galleryImage('vacation', 'featured') }}

Get the alt text for a specific gallery image.

{{ cms.render.galleryAlt('vacation', 'sunset.jpg') }}
{{ cms.render.galleryAlt('vacation', 'sunset.jpg', {collection: 'photos'}) }}

Get the caption for a gallery image, with optional template rendering.

{# Default caption (alt text fallback chain) #}
{{ cms.render.galleryCaption('vacation', 'sunset.jpg') }}
{# With template #}
{{ cms.render.galleryCaption('vacation', 'sunset.jpg', {}, '<h4>{alt}</h4><p>{exif.camera}</p>') }}

Render simple Previous/Next pagination links.

{{ cms.render.paginationSimple(totalItems, currentPage, itemsPerPage) }}
{# With custom labels and page key #}
{{ cms.render.paginationSimple(items|length, page, 10, 'page', 'Prev', 'Next') }}
{# Preserve query string parameters #}
{{ cms.render.paginationSimple(total, page, 10, 'p', 'Previous', 'Next', {sort: 'date', q: query}) }}
ParameterTypeDefaultDescription
totalObjectsintrequiredTotal number of items
currentPageintrequiredCurrent page number
pageLimitintrequiredItems per page
pageKeystring'p'Query parameter name for page number
prevContentstring'Previous'Previous button text/HTML
nextContentstring'Next'Next button text/HTML
getDataarray[]Additional query parameters to preserve

Render full pagination with numbered page links, plus Previous/Next.

{{ cms.render.paginationFull(totalItems, currentPage, itemsPerPage) }}
{{ cms.render.paginationFull(items|length, page, 10, 'p', '← Previous', 'Next →', {sort: 'date'}) }}

Parameters are identical to paginationSimple().

Generate an HTMX-powered “load more” trigger for paginated collection loading.

{{ cms.render.loadMore('blog', {template: 'blog/card.twig', limit: 10}) }}
{# Render first page server-side + HTMX for the rest #}
{{ cms.render.loadMore('blog', {template: 'blog/card.twig', limit: 10, load: true}) }}
{# With empty state for filtered results #}
{{ cms.render.loadMore('blog', {
template: 'blog/card.twig',
include: 'published:true',
empty: '<p>No posts found.</p>'
}) }}

See Load More Documentation for full options and examples.

Generate an HTMX-powered “load more” trigger for paginated DataView loading.

{{ cms.render.loadMoreDataView('recent-posts', {template: 'blog/card.twig', limit: 10}) }}

Generate a standalone HTMX button that appends items into an external container. Unlike loadMore(), the button can be placed anywhere on the page.

<div id="blog-feed"></div>
{{ cms.render.loadMoreButton('blog', {
target: '#blog-feed',
template: 'blog/card.twig',
limit: 10,
load: true
}) }}

See Load More Documentation for full options and examples.

Generate a standalone HTMX button for paginated DataView loading into an external container.

<div id="feed"></div>
{{ cms.render.loadMoreDataViewButton('recent-posts', {
target: '#feed',
template: 'cards/item.twig',
limit: 20
}) }}

Render an interactive file browser for depot properties. Displays files in a nested folder tree with filtering, previews, and download links.

{# Basic depot browser #}
{{ cms.render.depotBrowser('my-object') }}
{# With options #}
{{ cms.render.depotBrowser('my-object', {
collection: 'documents',
property: 'files',
filter: true,
preview: true,
tags: true,
comments: true,
class: 'my-depot'
}) }}
{# Filter by tags #}
{{ cms.render.depotBrowser('my-object', {filterTags: ['important', 'public']}) }}
{# Flat file list (no folders) #}
{{ cms.render.depotBrowser('my-object', {folders: false}) }}

Depot Browser Options:

OptionTypeDefaultDescription
collectionstring'depot'Collection identifier
propertystring'depot'Property name
filterboolfalseShow search/filter input
previewboolfalseShow preview buttons with modal
commentsboolfalseDisplay file comments
downloadbooltrueMake files downloadable (vs stream)
tagsboolfalseDisplay file tags
foldersbooltruePreserve folder structure
humanizebooltrueConvert filenames to title case
classstring''Custom CSS class
reverseSortboolfalseReverse file sort order
filterTagsarray[]Filter files by tags (OR logic, case-insensitive)

Render a clone dialog for duplicating objects in a collection. Used in the admin interface.

{{ cms.render.cloneDialog('blog') }}

The render adapter includes a grid sub-object with helper methods for content grids:

{{ cms.render.grid.date(item, 'M j, Y') }} {# Format date with fallback #}
{{ cms.render.grid.tags(item, '/blog/tag') }} {# Render tag list with links #}
{{ cms.render.grid.excerpt(item, 160) }} {# Generate text excerpt #}
{{ cms.render.grid.price(item) }} {# Format price #}
{{ cms.render.grid.meta(item) }} {# Render metadata (author, date) #}

See cmsgrid tag for the {% cmsgrid %} template tag documentation.