Handlebars Templates
This page demonstrates how Synticore uses Handlebars templates and custom helpers. Each section below provides a short explanation, a live compiled output, and template source code.
about.hbs
This template renders each paragraph from custom.brand.about. If that array is missing, it falls back to a default message.
Live Output (Compiled Template)
This is the official example project for Synticore, a flexible and efficient static site compiler. Designed to demonstrate a wide range of layout, style, and content features, this project provides a working showcase of how Synticore can structure, render, and enhance websites with minimal setup and maximum control.
The sections in this example cover layout styling, module integration, and individual page generation. You'll find demonstrations of syntax highlighting, markdown processing, slideshows, image watermarking, blog posts, and more—all powered by Synticore’ modular and declarative configuration approach.
Whether you're just getting started or evaluating Synticore for a larger project, this example serves as a foundational reference for building powerful, maintainable static sites.
Template Code
Reference: line 1 checks data availability, line 2 starts iteration, and line 5 is the fallback branch.
{{#if custom.brand.about}}
{{#each custom.brand.about}}
<p>{{this}}</p>
{{/each}}
{{else}}
<p>No information available about the brand.</p>
{{/if}}social-link.hbs
This template loops through custom.brand.social and builds one button link per social platform. It also uses the lowercase helper to generate class names.
Live Output (Compiled Template)
Template Code
Reference: line 1 is the main loop, and line 2 applies the lowercase helper for class naming.
{{#each custom.brand.social}}
<a class="button font-icon--color--social--{{lowercase name}}--background"
href="{{link}}"
title="Visit {{../require.site.title}} on {{name}}">
<span class="font-icon--social--{{lowercase name}}"></span>
{{name}}
<span class="font-icon--interface--external"></span>
</a>
{{/each}}location-embed.hbs
This template reads custom.brand.location and renders an embeddable map iframe. The map URL is generated by the googleMapsEmbed helper.
Live Output (Compiled Template)
Template Code
Reference: line 1 scopes location data, and line 4 is the helper call that builds the embed URL.
{{#with custom.brand.location}}
<iframe
style="border: 0px none; width: 100%; height: 100%;"
src="{{googleMapsEmbed address zoom}}"
frameborder="0"
allowfullscreen=""
loading="lazy"
referrerpolicy="no-referrer-when-downgrade">
</iframe>
{{/with}}copyright.hbs
This template conditionally renders author copyright details, then always renders brand/site copyright details. It uses notEquals to decide whether to show an external-link icon beside the author name.
Live Output (Compiled Template)
Template Code
Reference: line 1 gates the author block, line 7 is the notEquals condition, and line 15 starts the always-rendered site copyright block.
{{#if custom.site.author}}
<span class="copyright">
Content ©
<span id="copyrightyears__author">{{custom.site.author.copyright_years}}</span>
<a href="{{custom.site.author.url}}" title="{{custom.site.author.name}}: Home">
{{custom.site.author.name}}
{{#if (notEquals custom.site.author.url require.site.url)}}
<span class="font-icon--interface--external"></span>
{{/if}}
</a>
<span>, All Rights Reserved.</span>
</span>
{{/if}}
<span class="copyright">
{{#if custom.site.author}}Website {{/if}}©
<span id="copyrightyears__brand">{{custom.brand.copyright_years}}</span>
<a href="/" title="{{require.site.title}}: Home">{{require.site.title}}</a>
<span>, All Rights Reserved.</span>
</span>Helper-Driven Links
These templates show helper usage for transformed output: obfuscated email display, normalized phone link values, and encoded Google Maps links.
Live Output (Compiled Templates)
Template Code
Reference: lines 4, 11, and 16 are the key helper calls: splitEmail, phoneLink, and googleMapsLink.
<!-- email.hbs -->
{{#with custom.brand}}
<a href="mailto:{{email}}?subject=Website%20Message">
<span class="email">{{splitEmail email}}</span>
<span class="font-icon--interface--external"></span>
</a>
{{/with}}
<!-- phone.hbs -->
{{#with custom.brand}}
<a href="tel:{{phoneLink phone}}">{{phone}} <span class="font-icon--interface--external"></span></a>
{{/with}}
<!-- location-link.hbs -->
{{#with custom.brand.location}}
<a href="{{googleMapsLink address}}">{{address}} <span class="font-icon--interface--external"></span></a>
{{/with}}Custom Helper Registration Code (handlebars.js)
This is the helper module used by the example project. These functions are registered into Handlebars and then called by templates such as social-link.hbs, email.hbs, phone.hbs, and location-embed.hbs.
Source
Reference: line 2 defines lowercase, line 3 begins splitEmail, and line 18 begins googleMapsEmbed.
module.exports = (Handlebars) => ({
lowercase: (text) => text.toLowerCase().replace(/\s+/g, '-'),
splitEmail: (email) => {
if (typeof email !== 'string') return '';
const formattedEmail = email.replace('@', '​@');
return new Handlebars.SafeString(formattedEmail);
},
phoneLink: (phone) => {
if (typeof phone !== 'string') return '';
const formattedPhone = phone.replace(/[^+\d]/g, '');
return new Handlebars.SafeString(formattedPhone);
},
googleMapsLink: (address) => {
if (typeof address !== 'string' || address.trim() === '') return '#';
const encodedAddress = encodeURIComponent(address);
return new Handlebars.SafeString(`https://www.google.com/maps?q=${encodedAddress}`);
},
googleMapsEmbed: (address, zoom) => {
if (typeof address !== 'string' || address.trim() === '') return '';
const encodedAddress = encodeURIComponent(address);
const zoomParam = zoom ? `&z=${encodeURIComponent(zoom)}` : '';
return new Handlebars.SafeString(
`https://www.google.com/maps?q=${encodedAddress}&output=embed${zoomParam}`
);
},
notEquals: (value1, value2) => value1 !== value2
});