LogoCyanPrint

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:

cyan/index.ts
files: [
{
root: 'templates',
glob: '**/*',
exclude: [],
- type: GlobType.Copy
+ type: GlobType.Template
}
]
cyan/index.py
files=[
CyanGlob(
root="templates",
glob="**/*",
exclude=[],
- type=GlobType.Copy
+ type=GlobType.Template
)
]
cyan/Program.cs
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:

cyan/index.ts
config: {
vars: {
name: 'my-project',
author: 'Your Name',
version: '1.0.0'
}
}
cyan/index.py
config={
"vars": {
"name": "my-project",
"author": "Your Name",
"version": "1.0.0"
}
}
cyan/Program.cs
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:

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:

SyntaxDescription
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:

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:

cyan/index.py
from cyanprintsdk import start_template_with_fn, GlobType
from cyanprintsdk.domain.core.cyan import Cyan, CyanProcessor, CyanGlob
async 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:

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-project
Welcome 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 again
rm -rf ./test-output
cyanprint try template . ./test-output

What You Learned

  • How to change GlobType.Copy to GlobType.Template for 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:

Next: Changing Glob Patterns