or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

action-system.mdcli.mdconsole.mdgenerator-api.mdindex.mdprogrammatic.mdtemplate-system.md

template-system.mddocs/

0

# Template System

1

2

Plop uses Handlebars templating with built-in helpers, custom helpers, and partials for flexible file generation. The template system supports both inline templates and external template files.

3

4

## Capabilities

5

6

### Helper Management

7

8

Register and use custom Handlebars helpers for template processing.

9

10

```javascript { .api }

11

/**

12

* Register a custom Handlebars helper

13

* @param name - Helper name for use in templates

14

* @param fn - Helper function

15

*/

16

setHelper(name: string, fn: HelperFunction): void;

17

18

/**

19

* Get a registered helper function by name

20

* @param name - Helper name

21

* @returns Helper function

22

*/

23

getHelper(name: string): Function;

24

25

/**

26

* Get list of all registered helper names

27

* @returns Array of helper names

28

*/

29

getHelperList(): string[];

30

31

/**

32

* @deprecated Use setHelper instead

33

*/

34

addHelper(name: string, fn: Function): void;

35

```

36

37

**Usage Examples:**

38

39

```javascript

40

import { nodePlop } from "plop";

41

42

const plop = await nodePlop();

43

44

// Register a custom helper

45

plop.setHelper('upperCase', (text) => text.toUpperCase());

46

47

// Register a helper with options

48

plop.setHelper('repeat', (text, count) => {

49

return new Array(count + 1).join(text);

50

});

51

52

// Use in templates

53

const template = '{{upperCase name}} - {{repeat "!" 3}}';

54

const result = plop.renderString(template, { name: 'hello' });

55

console.log(result); // "HELLO - !!!"

56

57

// List all helpers

58

const helpers = plop.getHelperList();

59

console.log(helpers);

60

```

61

62

### Built-in Helpers

63

64

Plop includes numerous built-in case conversion and utility helpers.

65

66

```javascript { .api }

67

// Case conversion helpers (all available by default)

68

const BUILT_IN_HELPERS = {

69

// Basic case transformations

70

camelCase: Function; // myVariableName

71

pascalCase: Function; // MyVariableName

72

properCase: Function; // Alias for pascalCase

73

snakeCase: Function; // my_variable_name

74

kebabCase: Function; // my-variable-name

75

dashCase: Function; // Alias for kebabCase

76

kabobCase: Function; // Alias for kebabCase

77

constantCase: Function; // MY_VARIABLE_NAME

78

dotCase: Function; // my.variable.name

79

pathCase: Function; // my/variable/name

80

sentenceCase: Function; // My variable name

81

titleCase: Function; // My Variable Name

82

lowerCase: Function; // my variable name

83

upperCase: Function; // MY VARIABLE NAME

84

85

// Package helper

86

pkg: Function; // Access package.json properties

87

};

88

```

89

90

**Usage Examples:**

91

92

```javascript

93

// Template using built-in helpers

94

const template = `

95

class {{pascalCase name}} {

96

constructor() {

97

this.{{camelCase name}} = '{{kebabCase name}}';

98

this.version = '{{pkg "version"}}';

99

}

100

}

101

`;

102

103

const result = plop.renderString(template, { name: 'my-component' });

104

```

105

106

### Partial Management

107

108

Register and use Handlebars partials for reusable template components.

109

110

```javascript { .api }

111

/**

112

* Register a Handlebars partial

113

* @param name - Partial name for use in templates

114

* @param str - Partial template string

115

*/

116

setPartial(name: string, str: string): void;

117

118

/**

119

* Get a registered partial by name

120

* @param name - Partial name

121

* @returns Partial template string

122

*/

123

getPartial(name: string): string;

124

125

/**

126

* Get list of all registered partial names

127

* @returns Array of partial names

128

*/

129

getPartialList(): string[];

130

131

/**

132

* @deprecated Use setPartial instead

133

*/

134

addPartial(name: string, str: string): void;

135

```

136

137

**Usage Examples:**

138

139

```javascript

140

const plop = await nodePlop();

141

142

// Register partials

143

plop.setPartial('header', '// Generated by Plop on {{date}}');

144

plop.setPartial('footer', '// End of generated file');

145

146

// Register a partial with parameters

147

plop.setPartial('method', `

148

{{#if async}}async {{/if}}{{name}}({{#each params}}{{name}}{{#unless @last}}, {{/unless}}{{/each}}) {

149

{{body}}

150

}

151

`);

152

153

// Use partials in templates

154

const template = `

155

{{> header}}

156

157

class {{pascalCase name}} {

158

{{#each methods}}

159

{{> method this}}

160

{{/each}}

161

}

162

163

{{> footer}}

164

`;

165

166

const result = plop.renderString(template, {

167

name: 'my-class',

168

date: new Date().toISOString(),

169

methods: [

170

{

171

name: 'getData',

172

async: true,

173

params: [{ name: 'id' }],

174

body: 'return await api.get(id);'

175

}

176

]

177

});

178

```

179

180

### Template Sources

181

182

Specify templates using inline strings or external files.

183

184

```javascript { .api }

185

// Template source configuration

186

interface TemplateStrOrFile {

187

template?: string; // Inline template string

188

templateFile?: string; // Path to template file

189

}

190

191

// Used in action configurations

192

interface ActionWithTemplate extends ActionConfig, TemplateStrOrFile {

193

// Action-specific properties

194

}

195

```

196

197

**Usage Examples:**

198

199

```javascript

200

// Using inline template

201

{

202

type: 'add',

203

path: 'src/{{name}}.js',

204

template: 'export const {{name}} = "{{value}}";'

205

}

206

207

// Using template file

208

{

209

type: 'add',

210

path: 'src/{{name}}.js',

211

templateFile: 'templates/module.hbs'

212

}

213

214

// Template file: templates/module.hbs

215

```

216

217

```handlebars

218

import React from 'react';

219

220

export const {{pascalCase name}} = ({{#if props}}{ {{#each props}}{{name}}{{#unless @last}}, {{/unless}}{{/each}} }{{/if}}) => {

221

return (

222

<div className="{{kebabCase name}}">

223

{{#if children}}

224

{children}

225

{{else}}

226

<h1>{{titleCase name}}</h1>

227

{{/if}}

228

</div>

229

);

230

};

231

```

232

233

### Template Processing

234

235

Advanced template processing with transform functions and data manipulation.

236

237

```javascript { .api }

238

/**

239

* Transform function applied after template rendering

240

* @param template - Rendered template string

241

* @param data - Template data object

242

* @param config - Action configuration

243

* @returns Transformed template string

244

*/

245

type TransformFn<T> = (template: string, data: any, config: T) => string;

246

```

247

248

**Usage Examples:**

249

250

```javascript

251

// Action with transform function

252

{

253

type: 'add',

254

path: 'src/{{name}}.js',

255

templateFile: 'templates/component.hbs',

256

transform: (template, data, config) => {

257

// Add custom processing

258

if (data.typescript) {

259

template = template.replace(/\.js/g, '.ts');

260

}

261

262

// Add prettier formatting

263

return prettier.format(template, { parser: 'babel' });

264

}

265

}

266

267

// Advanced data processing in template

268

const template = `

269

{{#each items}}

270

{{#if (eq type "component")}}

271

{{> component-partial this}}

272

{{else if (eq type "service")}}

273

{{> service-partial this}}

274

{{/if}}

275

{{/each}}

276

`;

277

```

278

279

### Template Data Context

280

281

Template data includes user answers plus built-in context variables.

282

283

```javascript { .api }

284

interface TemplateData extends UserAnswers {

285

// Built-in context available in all templates

286

[key: string]: any; // User-provided answers from prompts

287

}

288

```

289

290

**Template Context Examples:**

291

292

```handlebars

293

{{!-- User answers from prompts --}}

294

Component: {{name}}

295

Type: {{type}}

296

Props: {{#each props}}{{name}}: {{type}}{{/each}}

297

298

{{!-- Built-in helpers --}}

299

File: {{kebabCase name}}.jsx

300

Class: {{pascalCase name}}

301

Constant: {{constantCase name}}_CONFIG

302

303

{{!-- Package.json access --}}

304

Version: {{pkg "version"}}

305

Author: {{pkg "author.name"}}

306

307

{{!-- Conditional rendering --}}

308

{{#if typescript}}

309

interface {{pascalCase name}}Props {

310

{{#each props}}

311

{{name}}: {{type}};

312

{{/each}}

313

}

314

{{/if}}

315

316

{{!-- Loops and arrays --}}

317

{{#each methods}}

318

{{#unless @first}}

319

320

{{/unless}}

321

{{name}}(): {{returnType}} {

322

// TODO: Implement {{name}}

323

}

324

{{/each}}

325

```

326

327

## Advanced Template Features

328

329

### Conditional Logic

330

331

Use Handlebars conditionals for dynamic template generation.

332

333

```handlebars

334

{{#if condition}}

335

Render this when condition is true

336

{{else if otherCondition}}

337

Render this when otherCondition is true

338

{{else}}

339

Default content

340

{{/if}}

341

342

{{#unless disabled}}

343

Render this when disabled is false

344

{{/unless}}

345

```

346

347

### Loops and Iteration

348

349

Iterate over arrays and objects in templates.

350

351

```handlebars

352

{{#each items}}

353

Item {{@index}}: {{name}} ({{@first}} {{@last}})

354

{{/each}}

355

356

{{#each object}}

357

{{@key}}: {{this}}

358

{{/each}}

359

```

360

361

### Helper Combinations

362

363

Combine multiple helpers for complex transformations.

364

365

```handlebars

366

{{pascalCase (replace name "-" "")}}

367

{{upperCase (substring description 0 50)}}

368

{{#each (sort items "name")}}

369

{{camelCase name}}: {{value}}

370

{{/each}}

371

```