or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdhooks-extensions.mdindex.mdmain-api.mdrepository-handling.mdtemplate-processing.mduser-interaction.mdutilities-exceptions.md

template-processing.mddocs/

0

# Template Processing

1

2

Context generation, file rendering, and template discovery functionality that powers cookiecutter's core template processing capabilities. This module handles the transformation of template directories into fully-rendered project structures.

3

4

## Capabilities

5

6

### Context Generation

7

8

Generate template context from cookiecutter.json files and user input.

9

10

```python { .api }

11

def generate_context(context_file='cookiecutter.json', default_context=None, extra_context=None):

12

"""

13

Generate context for template processing.

14

15

Parameters:

16

- context_file: str - Path to cookiecutter.json file

17

- default_context: dict, optional - Default context values

18

- extra_context: dict, optional - Additional context to override defaults

19

20

Returns:

21

dict - Generated context dictionary with 'cookiecutter' key containing template variables

22

"""

23

24

def apply_overwrites_to_context(context, overwrite_context, *, in_dictionary_variable=False):

25

"""

26

Modify context with overrides.

27

28

Parameters:

29

- context: dict - Original context dictionary

30

- overwrite_context: dict - Values to override in context

31

- in_dictionary_variable: bool - Whether we're inside a dictionary variable

32

33

Returns:

34

dict - Modified context with overrides applied

35

"""

36

```

37

38

### File Generation

39

40

Core template rendering and file creation functionality.

41

42

```python { .api }

43

def generate_files(

44

repo_dir,

45

context=None,

46

output_dir='.',

47

overwrite_if_exists=False,

48

skip_if_file_exists=False,

49

accept_hooks=True,

50

keep_project_on_failure=False

51

):

52

"""

53

Main function to render templates and save to files.

54

55

Parameters:

56

- repo_dir: str - Path to repository directory containing template

57

- context: dict, optional - Template context dictionary

58

- output_dir: str - Directory to output generated project

59

- overwrite_if_exists: bool - Overwrite existing output directory

60

- skip_if_file_exists: bool - Skip files that already exist

61

- accept_hooks: bool - Execute pre/post generation hooks

62

- keep_project_on_failure: bool - Keep project directory on failure

63

64

Returns:

65

str - Path to generated project directory

66

"""

67

68

def generate_file(project_dir, infile, context, env, skip_if_file_exists=False):

69

"""

70

Render and generate individual files.

71

72

Parameters:

73

- project_dir: str - Path to project directory

74

- infile: str - Input template file path

75

- context: dict - Template context

76

- env: Environment - Jinja2 environment for rendering

77

- skip_if_file_exists: bool - Skip if output file already exists

78

"""

79

80

def render_and_create_dir(dirname, context, output_dir, environment, overwrite_if_exists=False):

81

"""

82

Render directory name and create it.

83

84

Parameters:

85

- dirname: str - Template directory name to render

86

- context: dict - Template context

87

- output_dir: str - Output directory path

88

- environment: Environment - Jinja2 environment

89

- overwrite_if_exists: bool - Overwrite if directory exists

90

91

Returns:

92

str - Path to created directory

93

"""

94

```

95

96

### Template Discovery

97

98

Locate and validate cookiecutter templates.

99

100

```python { .api }

101

def find_template(repo_dir, env):

102

"""

103

Determine which directory is the project template.

104

105

Parameters:

106

- repo_dir: str - Repository directory to search

107

- env: Environment - Jinja2 environment for template validation

108

109

Returns:

110

str - Path to template directory

111

"""

112

```

113

114

### Copy Control

115

116

Control which files are copied vs rendered as templates.

117

118

```python { .api }

119

def is_copy_only_path(path, context):

120

"""

121

Check if path should only be copied, not rendered.

122

123

Parameters:

124

- path: str - File or directory path to check

125

- context: dict - Template context containing copy settings

126

127

Returns:

128

bool - True if path should be copied without rendering

129

"""

130

```

131

132

## Template Structure

133

134

Cookiecutter templates follow a specific directory structure:

135

136

```

137

template-directory/

138

├── cookiecutter.json # Template configuration

139

├── hooks/ # Pre/post generation scripts (optional)

140

│ ├── pre_gen_project.py

141

│ └── post_gen_project.py

142

└── {{cookiecutter.project_name}}/ # Template directory

143

├── {{cookiecutter.module_name}}/

144

│ ├── __init__.py

145

│ └── {{cookiecutter.module_name}}.py

146

├── tests/

147

├── setup.py

148

└── README.md

149

```

150

151

## Usage Examples

152

153

### Basic Context Generation

154

155

```python

156

from cookiecutter.generate import generate_context

157

158

# Generate context from cookiecutter.json

159

context = generate_context('path/to/cookiecutter.json')

160

161

# Context with defaults

162

default_ctx = {'author': 'Default Author', 'version': '1.0.0'}

163

context = generate_context(

164

'path/to/cookiecutter.json',

165

default_context=default_ctx

166

)

167

168

# Context with extra overrides

169

extra_ctx = {'project_name': 'my-awesome-project'}

170

context = generate_context(

171

'path/to/cookiecutter.json',

172

extra_context=extra_ctx

173

)

174

```

175

176

### Template Processing

177

178

```python

179

from cookiecutter.generate import generate_files, find_template

180

from cookiecutter.environment import StrictEnvironment

181

182

# Find template directory

183

env = StrictEnvironment()

184

template_dir = find_template('./my-template-repo', env)

185

186

# Generate files from template

187

context = {

188

'cookiecutter': {

189

'project_name': 'my-project',

190

'author': 'Jane Developer',

191

'version': '1.0.0'

192

}

193

}

194

195

result_path = generate_files(

196

repo_dir=template_dir,

197

context=context,

198

output_dir='./output',

199

overwrite_if_exists=True

200

)

201

```

202

203

### Advanced File Generation

204

205

```python

206

from cookiecutter.generate import generate_files

207

import os

208

209

# Generate with custom settings

210

context = generate_context('./template/cookiecutter.json')

211

212

# Add runtime context

213

context['cookiecutter'].update({

214

'timestamp': '2024-01-01',

215

'user_home': os.path.expanduser('~')

216

})

217

218

# Generate with hooks disabled

219

result_path = generate_files(

220

repo_dir='./template',

221

context=context,

222

output_dir='./projects',

223

accept_hooks=False,

224

skip_if_file_exists=True

225

)

226

227

print(f"Project generated at: {result_path}")

228

```

229

230

### Copy-Only Files

231

232

```python

233

from cookiecutter.generate import generate_context, is_copy_only_path

234

235

# Set up context with copy-only patterns

236

context = generate_context('./template/cookiecutter.json')

237

238

# Check if specific files should be copied without rendering

239

binary_file = 'assets/logo.png'

240

config_file = 'config/app.json'

241

242

if is_copy_only_path(binary_file, context):

243

print(f"{binary_file} will be copied without rendering")

244

245

if is_copy_only_path(config_file, context):

246

print(f"{config_file} will be copied without rendering")

247

```

248

249

### Context Manipulation

250

251

```python

252

from cookiecutter.generate import apply_overwrites_to_context, generate_context

253

254

# Generate base context

255

base_context = generate_context('./template/cookiecutter.json')

256

257

# Apply runtime overrides

258

overrides = {

259

'project_name': 'runtime-project',

260

'features': {

261

'database': True,

262

'authentication': True

263

}

264

}

265

266

final_context = apply_overwrites_to_context(

267

base_context,

268

overrides

269

)

270

271

# Context now includes runtime overrides

272

print(final_context['cookiecutter']['project_name']) # 'runtime-project'

273

```

274

275

### Error Handling

276

277

```python

278

from cookiecutter.generate import generate_files, find_template

279

from cookiecutter.exceptions import (

280

UnknownTemplateDirException,

281

MissingProjectDir,

282

UndefinedVariableInTemplate

283

)

284

285

try:

286

# Find and validate template

287

template_dir = find_template('./template-repo', env)

288

289

# Generate files

290

result = generate_files(

291

repo_dir=template_dir,

292

context=context,

293

output_dir='./output'

294

)

295

296

except UnknownTemplateDirException:

297

print("Could not determine template directory")

298

except MissingProjectDir:

299

print("Generated project directory is missing")

300

except UndefinedVariableInTemplate as e:

301

print(f"Template uses undefined variable: {e}")

302

```