This guide provides comprehensive documentation for Go template rendering patterns used in the Commerce Cloud theme system.
Go templates power dynamic rendering across blocks, sections, layouts, and snippets. Understanding these patterns is essential when building or modifying theme templates.
This guide covers:
- Core Go template syntax
- Variable handling
- Conditional rendering
- Loops and context management
- Custom theme functions
- Common rendering patterns
- Best practices from the codebase
Introduction to Go Templates
Go templates use a simple syntax with double curly braces {{ }} to embed template actions. This guide covers the fundamental rendering patterns you'll use when building theme templates.
Basic Syntax
- Actions:
{{ action }}- Executes template logic- Example:
{{ render_block .Block }}
- Comments:
{{/* comment */}} - Documentation within templates - Pipelines
{{ value | function }}- Pass values through functions- Example:
{{ .Block.Settings.background | asset_url }}
VariablesVariables are defined using the := operator and must be prefixed with $.
Basic Variable Definition
{{ $variableName := .Value }}
Example:
{{ $settings := .Block.Settings }}{{ $title := $settings.title }}
Variable with Default Value
Use or to provide fallback values.
{{ $value := or .Value "default" }}
Example:
{{ $transparency := or $settings.background.transparency 100 }}
{{ $numberOfColumns := or $settings.columns 3 }}
This prevents rendering failures when values are missing.
Conditional StatementsConditionals control whether content is rendered.
If Statement
{{ if .condition }}
Content
{{ end }}
Example:
{{ if .Block.Settings.background }}
<div style="background: url({{ .Block.Settings.background | asset_url }})"></div>
{{ end }}
If–Else
{{ if .condition }}
True
{{ else }}
False
{{ end }}
Example:
{{ if .Block.Settings.show_title }}
<h1>{{ .Block.Settings.title }}</h1>
{{ else }}
<h1>Default Title</h1>
{{ end }}
If–Else If–Else
{{ if .condition1 }}
{{ else if .condition2 }}
{{ else }}
{{ end }}
Conditional OperatorsEquality (eq)
{{ if eq $a $b }}
Example:
{{ if eq $blockID "header-actions" }}
<div class="header-actions">{{ render_block . }}</div>
{{ end }}
Not Equal (ne)
{{ if ne $a $b }}
Logical AND
{{ if and .condition1 .condition2 }}
Example:
{{ if and $settings.show_title $settings.title }}
<h1>{{ $settings.title }}</h1>
{{ end }}
Logical OR
{{ if or .condition1 .condition2 }}
Example:
{{ if or (eq $paginationType "lazy") (eq $paginationType "combined") }}
{{ snippet "lazy-loader" . }}
{{ end }}
Logical NOT
{{ if not .condition }}
Loops and IterationGo templates use range to iterate over slices, arrays, and maps.
Basic Range Loop
{{ range .items }}
{{ . }}
{{ end }}
Range with Index
{{ range $index, $item := .items }}
Index: {{ $index }}
{{ end }}
Range with Key–Value (Maps)
{{ range $key, $value := .map }}
Example:
{{ range $blockID, $block := .Blocks }}
<div data-id="{{ $blockID }}">
{{ render_block $block }}
</div>
{{ end }}
Range with Context Switching
{{ range $blockID := .BlockOrder }}
{{ with index $.Blocks $blockID }}
{{ render_block . }}
{{ end }}
{{ end }}
This is the most common block rendering pattern in Commerce Cloud.
Context and ScopingThe Dot (.)
The dot represents the current context.
{{ .Block.Settings.title }}
When inside a range, . changes to the current item.
Root Context ($)
Use $ to access the root scope when nested.
{{ $.Blocks }}
With Statement
Sets context only if the value exists.
{{ with .value }}
{{ . }}
{{ end }}
Example:
{{ with .Block.Settings.background }}
<div style="background: {{ . }}"></div>
{{ end }}
Template FunctionsThe theme system includes custom rendering functions.
render_block
Renders a block based on its type.
{{ render_block .Block }}
Common usage:
{{ range $blockID := .BlockOrder }}
{{ with index $.Blocks $blockID }}
{{ render_block . }}
{{ end }}
{{ end }}
render_grid_block
Used for grid layout blocks.
{{ render_grid_block .Block }}
snippet
Includes reusable template snippets.
{{ snippet "snippet-name" .Context }}
Example:
{{ snippet "product-card" . }}
{{ snippet "mobile-menu" . }}
With dictionary:
{{ snippet "mobile-actions" (dict "sortingEnabled" $sortingEnabled "originalContext" .) }}
asset_url
Generates URL for theme assets.
{{ asset_url "filename.css" }}
Example:
<link rel="stylesheet" href='{{ asset_url "blog-page.css" }}'/>
image_url
Generates image URLs.
{{ image_url .image }}
printf
Formats strings.
{{ printf "format" args... }}
Example:
{{ $background := printf "background-image: url('%s');" $image }}
Built-in Functionsindex
{{ index .array 0 }}{{ index .map "key" }}
Comparison Functions
eq ne lt le gt ge
slice
{{ slice .string start end }}
Example:
{{ if eq (slice $image 0 5) "https" }}
Common Rendering PatternsPattern 1: Standard Block Iteration
{{ range $blockID := .BlockOrder }}
{{ with index $.Blocks $blockID }}
{{ render_block . }}
{{ end }}
{{ end }}
This is the primary pattern used in container and section blocks.
Pattern 2: Conditional Block Rendering
Handles fallback logic.
{{ if .Block.BlockOrder }}
...
{{ else }}
...
{{ end }}
Pattern 3: Settings Extraction
{{ $block := .Block }}
{{ $settings := $block.Settings }}
Extract frequently used values into variables.
Pattern 4: Conditional Attribute Rendering
<div
class="component {{ $settings.custom_class }}"
{{ if $settings.section_id }}
id="{{ $settings.section_id }}"
{{ else }}
id="{{ .Block.ID }}"
{{ end }}
>
Pattern 5: Data Structure Handling
Supports both builder and engine data formats.
{{ $data := .Data }}
{{ if .Data.data }}
{{ $data = index .Data.data 0 }}
{{ end }}
Pattern 6: Multiple Condition Checks
{{ if or (eq $paginationType "lazy") (eq $paginationType "combined") }}
{{ snippet "lazy-loader" . }}
{{ end }}
Best Practices1. Variable Naming
- Use descriptive names
- Use consistent prefixes
- Use snake_case for multi-word variables
2. Context Management
- Use
$ to access root scope - Use
with for nested values - Always check existence before access
3. Error Prevention
- Provide default values using
or - Guard nested properties
- Check before iterating
4. Performance
- Cache repeated values in variables
- Avoid deep nesting
- Extract reusable logic into snippets
5. Readability
- Use comments for complex logic
- Group variable definitions
- Break complex conditions into variables
Codebase ExamplesContainer Block
{{ $block := .Block }}
{{ $blocks := .Block.Blocks }}
{{ $settings := $block.Settings }}
{{ $blockOrder := $block.BlockOrder }}
<div data-component-id="{{ .Block.ID }}" class="container-block">
{{ range $blockID := $blockOrder }}
{{ with index $blocks $blockID }}
{{ render_block . }}
{{ end }}
{{ end }}
</div>
Section with Conditional Background
<section
data-component-id="{{ .Block.ID }}"
{{ if .Block.Settings.background }}
style="background: url({{ .Block.Settings.background | asset_url }})"
{{ end }}
>
Complex Conditional Background Logic
{{ $image := $settings.background.image }}
{{ $background := "" }}
{{ if $image }}
{{ if eq (slice $image 0 5) "https" }}
{{ $background = printf "background-image: url('%s');" $image }}
{{ else }}
{{ $url := asset_url $settings.background.image }}
{{ $background = printf "background-image: url('%s');" $url }}
{{ end }}
{{ else if $settings.background.color }}
{{ $background = printf "background-color: %s;" $settings.background.color }}
{{ end }}