or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bytecode-caching.mdenvironment-templates.mderror-handling-debugging.mdextensions-custom-syntax.mdfilters-data-processing.mdindex.mdmeta-analysis.mdnative-types.mdsecurity-sandboxing.mdtemplate-loaders.mdtests-conditionals.md

meta-analysis.mddocs/

0

# Meta Analysis

1

2

Template introspection functions for analyzing template dependencies and variable usage. Useful for dependency tracking, caching systems, and development tools.

3

4

## Capabilities

5

6

### Variable Analysis

7

8

Analyze templates to find all variables that will be looked up from the context at runtime.

9

10

```python { .api }

11

def find_undeclared_variables(ast):

12

"""

13

Returns a set of all variables in the AST that will be looked up from

14

the context at runtime.

15

16

Because at compile time it's not known which variables will be used

17

depending on the path the execution takes at runtime, all variables

18

are returned.

19

20

Parameters:

21

ast: Template AST node from Environment.parse()

22

23

Returns:

24

set: Set of variable names that will be looked up from context

25

26

Raises:

27

TemplateAssertionError: During compilation if template is invalid

28

"""

29

```

30

31

### Template Dependency Analysis

32

33

Find all templates referenced by extends, includes, and imports in a template.

34

35

```python { .api }

36

def find_referenced_templates(ast):

37

"""

38

Finds all the referenced templates from the AST.

39

40

Returns an iterator over all the hardcoded template extensions, inclusions

41

and imports. If dynamic inheritance or inclusion is used, None will be

42

yielded for those entries.

43

44

Parameters:

45

ast: Template AST node from Environment.parse()

46

47

Yields:

48

str or None: Template names found, or None for dynamic references

49

"""

50

```

51

52

## Usage Examples

53

54

### Finding Undeclared Variables

55

56

```python

57

from jinja2 import Environment, meta

58

59

env = Environment()

60

61

# Simple template with variables

62

template_source = '{{ user.name }} has {{ count }} items'

63

ast = env.parse(template_source)

64

variables = meta.find_undeclared_variables(ast)

65

print(variables) # {'user', 'count'}

66

67

# Template with loops and conditions

68

template_source = '''

69

{% for item in items %}

70

{{ item.name }} - {{ item.price }}

71

{% endfor %}

72

{% if total > 100 %}

73

Discount: {{ discount }}

74

{% endif %}

75

'''

76

ast = env.parse(template_source)

77

variables = meta.find_undeclared_variables(ast)

78

print(variables) # {'items', 'total', 'discount'}

79

```

80

81

### Finding Template Dependencies

82

83

```python

84

from jinja2 import Environment, meta

85

86

env = Environment()

87

88

# Template with static dependencies

89

template_source = '''

90

{% extends "base.html" %}

91

{% include "header.html" %}

92

{% from "macros.html" import button %}

93

'''

94

ast = env.parse(template_source)

95

dependencies = list(meta.find_referenced_templates(ast))

96

print(dependencies) # ['base.html', 'header.html', 'macros.html']

97

98

# Template with dynamic dependencies

99

template_source = '''

100

{% extends layout_template %}

101

{% include "static.html" %}

102

{% include dynamic_include %}

103

'''

104

ast = env.parse(template_source)

105

dependencies = list(meta.find_referenced_templates(ast))

106

print(dependencies) # [None, 'static.html', None]

107

```

108

109

### Dependency Tracking System

110

111

```python

112

from jinja2 import Environment, meta

113

import os

114

115

def analyze_template_dependencies(template_path):

116

"""Analyze a template file and return its variable and template dependencies."""

117

env = Environment()

118

119

with open(template_path) as f:

120

source = f.read()

121

122

ast = env.parse(source)

123

124

# Find variables needed from context

125

variables = meta.find_undeclared_variables(ast)

126

127

# Find referenced templates

128

templates = [t for t in meta.find_referenced_templates(ast) if t is not None]

129

130

return {

131

'variables': variables,

132

'templates': templates,

133

'has_dynamic_dependencies': None in meta.find_referenced_templates(ast)

134

}

135

136

# Example usage

137

dependencies = analyze_template_dependencies('templates/user_profile.html')

138

print(f"Variables needed: {dependencies['variables']}")

139

print(f"Template dependencies: {dependencies['templates']}")

140

print(f"Has dynamic deps: {dependencies['has_dynamic_dependencies']}")

141

```

142

143

### Template Variable Validation

144

145

```python

146

from jinja2 import Environment, meta

147

148

def validate_template_context(template_source, provided_context):

149

"""Validate that all required variables are provided in context."""

150

env = Environment()

151

ast = env.parse(template_source)

152

required_vars = meta.find_undeclared_variables(ast)

153

154

missing_vars = required_vars - set(provided_context.keys())

155

156

if missing_vars:

157

raise ValueError(f"Missing required variables: {missing_vars}")

158

159

return True

160

161

# Example usage

162

template = "Hello {{ name }}, you have {{ count }} messages"

163

context = {"name": "Alice", "count": 5}

164

165

try:

166

validate_template_context(template, context)

167

print("All variables provided!")

168

except ValueError as e:

169

print(f"Validation error: {e}")

170

```

171

172

### Build System Integration

173

174

```python

175

from jinja2 import Environment, meta

176

import os

177

from pathlib import Path

178

179

def get_template_dependency_graph(template_dir):

180

"""Build dependency graph for all templates in a directory."""

181

env = Environment()

182

dependency_graph = {}

183

184

for template_file in Path(template_dir).glob('**/*.html'):

185

template_path = str(template_file.relative_to(template_dir))

186

187

with open(template_file) as f:

188

source = f.read()

189

190

ast = env.parse(source)

191

dependencies = [

192

dep for dep in meta.find_referenced_templates(ast)

193

if dep is not None

194

]

195

196

dependency_graph[template_path] = dependencies

197

198

return dependency_graph

199

200

# Example usage for build system

201

deps = get_template_dependency_graph('templates/')

202

for template, dependencies in deps.items():

203

print(f"{template} depends on: {dependencies}")

204

```

205

206

## Import Pattern

207

208

```python

209

from jinja2 import meta

210

211

# Access meta functions through the meta module

212

variables = meta.find_undeclared_variables(ast)

213

templates = meta.find_referenced_templates(ast)

214

```