Tutorial 2 - Adding Variables
Add variable substitution to your templates
Tutorial 2: Adding Variables
Add variable substitution to your template. This enables dynamic content generation based on variables, making your templates reusable across different projects.
The Change: GlobType.Template
In Tutorial 1, we used GlobType.Copy which simply copies files. To enable variable substitution, change to GlobType.Template:
files: [{root: 'templates',glob: '**/*',exclude: [],- type: GlobType.Copy+ type: GlobType.Template}]
files=[CyanGlob(root="templates",glob="**/*",exclude=[],- type=GlobType.Copy+ type=GlobType.Template)]
Files =[new CyanGlob{Root = "templates",Glob = "**/*",Exclude = [],- Type = GlobType.Copy+ Type = GlobType.Template}]
Using GlobType.Template on binary files (images, PDFs) will corrupt them. See Tutorial 3 for handling mixed file types.
Define Variables in Config
Add variables to your processor configuration:
config: {vars: {name: 'my-project',author: 'Your Name',version: '1.0.0'}}
config={"vars": {"name": "my-project","author": "Your Name","version": "1.0.0"}}
Config = new{vars = new{name = "my-project",author = "Your Name",version = "1.0.0"}}
Use Variables in Template Files
The default processor uses var__name__ syntax for variable substitution.
Create templates/README.md:
# var__name__Welcome to var__name__!**Author:** var__author__**Version:** var__version__
Variable Syntax
The default processor uses Eta templating with custom delimiters:
| Syntax | Description |
|---|---|
var__name__ | Variable substitution |
var__user.name__ | Nested variable access |
The default delimiter var__ and __ is chosen to avoid conflicts with common template syntaxes like ${} or {{}}.
Complete Code
Update your template logic with all the changes:
Update cyan/index.ts:
import { startTemplateWithFn, GlobType } from '@atomicloud/cyan-sdk';startTemplateWithFn(async (i, d) => {const name = await i.text('What is your project name?', 'myuser/my-first-template/name');return {processors: [{name: 'cyan/default',files: [{root: 'templates',glob: '**/*',exclude: [],type: GlobType.Template}],config: {vars: {name,author: 'Your Name',version: '1.0.0'}}}]};});
Note that name comes from user input while author and version are hardcoded defaults.
Update cyan/index.py:
from cyanprintsdk import start_template_with_fn, GlobTypefrom cyanprintsdk.domain.core.cyan import Cyan, CyanProcessor, CyanGlobasync def my_template(i, d):name = await i.text("What is your project name?", "myuser/my-first-template/name")return Cyan(processors=[CyanProcessor(name="cyan/default",files=[CyanGlob(root="templates",glob="**/*",exclude=[],type=GlobType.Template)],config={"vars": {"name": name,"author": "Your Name","version": "1.0.0"}})])start_template_with_fn(my_template)
Note that name comes from user input while author and version are hardcoded defaults.
Update cyan/Program.cs:
using sulfone_helium;using sulfone_helium.Domain.Core;CyanEngine.StartTemplate(args, async (i, d) =>{var name = await i.Text("What is your project name?", "myuser/my-first-template/name");return new Cyan{Processors =[new CyanProcessor{Name = "cyan/default",Files =[new CyanGlob{Root = "templates",Glob = "**/*",Exclude = [],Type = GlobType.Template}],Config = new{vars = new{name,author = "Your Name",version = "1.0.0"}}}]};});
Note that name comes from user input while author and version are hardcoded defaults.
Test Your Template
Use the try command to test your template:
cyanprint try template . ./test-output
When prompted, enter a project name like my-project.
Check the Output
cat ./test-output/README.md
Expected output:
# my-projectWelcome to my-project!**Author:** Your Name**Version:** 1.0.0
The variables have been replaced with their values.
Development Workflow
Iterate quickly with the try command:
# Make changes to your template or variables...# Test againrm -rf ./test-outputcyanprint try template . ./test-output
What You Learned
- How to change
GlobType.CopytoGlobType.Templatefor variable processing - How to define variables in processor config
- How to use
var__name__syntax for substitution in template files - How to combine user input with hardcoded default values
Next Steps
Learn how to handle different file types with different processing strategies: