or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdcompilation.mdcontext.mdfilters.mdhelpers.mdindex.mdparsing.mdrendering.md

context.mddocs/

0

# Context System

1

2

Stack-based context system for data resolution with scoping, inheritance, and block management in Dust templates.

3

4

## Capabilities

5

6

### Context Creation

7

8

Functions for creating and managing template contexts that provide data resolution during rendering.

9

10

```javascript { .api }

11

/**

12

* Creates base template context

13

* @param global - Global data object accessible throughout template

14

* @param options - Context configuration options

15

* @returns Context instance for template rendering

16

*/

17

function context(global: any, options?: ContextOptions): Context;

18

19

/**

20

* Alias for context() function

21

* @param global - Global data object

22

* @param options - Context configuration options

23

* @returns Context instance

24

*/

25

function makeBase(global: any, options?: ContextOptions): Context;

26

27

interface ContextOptions {

28

/** Template name for debugging */

29

templateName?: string;

30

/** Block definitions for template inheritance */

31

blocks?: { [blockName: string]: any };

32

/** Additional context configuration */

33

[key: string]: any;

34

}

35

```

36

37

**Usage Examples:**

38

39

```javascript

40

const dust = require('dustjs-linkedin');

41

42

// Basic context creation

43

const ctx = dust.context({

44

user: { name: 'Alice', role: 'admin' },

45

site: { title: 'My App', version: '1.0' }

46

});

47

48

// Context with options

49

const ctxWithOptions = dust.context({

50

users: [{ name: 'Bob' }, { name: 'Carol' }]

51

}, {

52

templateName: 'user-list',

53

blocks: { header: 'Custom Header' }

54

});

55

56

// Using makeBase alias

57

const baseCtx = dust.makeBase({

58

config: { debug: true },

59

helpers: { customHelper: () => 'Custom' }

60

});

61

```

62

63

### Context Type Checking

64

65

Utility function to determine if an object is a Dust context.

66

67

```javascript { .api }

68

/**

69

* Tests if object is a Dust context

70

* @param obj - Object to test

71

* @returns true if object is a Context instance

72

*/

73

function isContext(obj: any): boolean;

74

75

/**

76

* Static method to wrap context data

77

* @param context - Context data or existing Context instance

78

* @param name - Template name for debugging

79

* @returns Context instance

80

*/

81

Context.wrap(context: any, name?: string): Context;

82

```

83

84

**Usage Examples:**

85

86

```javascript

87

const ctx = dust.context({ data: 'value' });

88

const plainObject = { data: 'value' };

89

90

console.log(dust.isContext(ctx)); // true

91

console.log(dust.isContext(plainObject)); // false

92

93

// Useful in helper functions

94

function myHelper(chunk, context, bodies, params) {

95

if (!dust.isContext(context)) {

96

throw new Error('Invalid context provided to helper');

97

}

98

// Helper implementation...

99

}

100

```

101

102

## Context Instance Methods

103

104

### Data Access and Resolution

105

106

Methods for accessing and resolving data within the context stack.

107

108

```javascript { .api }

109

interface Context {

110

/**

111

* Get value from context by path

112

* @param path - Dot-separated path or array of keys

113

* @param cur - Current context data (optional)

114

* @returns Resolved value or undefined

115

*/

116

get(path: string | string[], cur?: any): any;

117

118

/**

119

* Get current context data at top of stack

120

* @returns Current data object

121

*/

122

current(): any;

123

124

/**

125

* Get template name for debugging

126

* @returns Template name string or undefined

127

*/

128

getTemplateName(): string | undefined;

129

}

130

```

131

132

**Usage Examples:**

133

134

```javascript

135

const ctx = dust.context({

136

user: {

137

profile: { name: 'Alice', email: 'alice@example.com' },

138

settings: { theme: 'dark', notifications: true }

139

},

140

items: ['apple', 'banana', 'cherry']

141

});

142

143

// Simple path resolution

144

console.log(ctx.get('user.profile.name')); // 'Alice'

145

console.log(ctx.get('user.settings.theme')); // 'dark'

146

147

// Array path resolution

148

console.log(ctx.get(['user', 'profile', 'email'])); // 'alice@example.com'

149

150

// Array index access

151

console.log(ctx.get('items.0')); // 'apple'

152

console.log(ctx.get('items.2')); // 'cherry'

153

154

// Non-existent path

155

console.log(ctx.get('user.invalid.path')); // undefined

156

157

// Current context data

158

console.log(ctx.current()); // Full context object

159

```

160

161

### Context Stack Management

162

163

Methods for manipulating the context stack during template execution.

164

165

```javascript { .api }

166

interface Context {

167

/**

168

* Push new data onto context stack

169

* @param head - New context data to push

170

* @param idx - Index for array iterations (optional)

171

* @param len - Length for array iterations (optional)

172

* @returns New context with pushed data

173

*/

174

push(head: any, idx?: number, len?: number): Context;

175

176

/**

177

* Remove top item from context stack

178

* @returns Context with popped data

179

*/

180

pop(): Context;

181

182

/**

183

* Create new context with different base data

184

* @param head - New base data

185

* @returns New context instance

186

*/

187

rebase(head: any): Context;

188

189

/**

190

* Clone current context

191

* @returns New context instance with same data

192

*/

193

clone(): Context;

194

}

195

```

196

197

**Usage Examples:**

198

199

```javascript

200

const baseCtx = dust.context({

201

global: 'value',

202

config: { debug: true }

203

});

204

205

// Push new context data

206

const userCtx = baseCtx.push({

207

name: 'Bob',

208

role: 'editor'

209

});

210

211

console.log(userCtx.get('name')); // 'Bob' (from pushed data)

212

console.log(userCtx.get('global')); // 'value' (from base context)

213

214

// Push with array iteration info

215

const items = ['a', 'b', 'c'];

216

items.forEach((item, idx) => {

217

const itemCtx = baseCtx.push(item, idx, items.length);

218

console.log(itemCtx.get('@index')); // Current index

219

console.log(itemCtx.get('@length')); // Array length

220

});

221

222

// Pop context

223

const poppedCtx = userCtx.pop();

224

console.log(poppedCtx.get('name')); // undefined (popped)

225

console.log(poppedCtx.get('global')); // 'value' (still available)

226

227

// Rebase context

228

const rebasedCtx = baseCtx.rebase({

229

newBase: 'data',

230

different: 'values'

231

});

232

233

// Clone context

234

const clonedCtx = baseCtx.clone();

235

console.log(clonedCtx.get('global')); // 'value'

236

```

237

238

### Block Management

239

240

Methods for managing template blocks used in template inheritance.

241

242

```javascript { .api }

243

interface Context {

244

/**

245

* Get block by name

246

* @param key - Block name

247

* @returns Block definition or undefined

248

*/

249

getBlock(key: string): any;

250

251

/**

252

* Add local blocks to context

253

* @param locals - Object containing block definitions

254

* @returns New context with added blocks

255

*/

256

shiftBlocks(locals: { [blockName: string]: any }): Context;

257

}

258

```

259

260

**Usage Examples:**

261

262

```javascript

263

// Context with blocks

264

const ctx = dust.context({ data: 'value' }, {

265

blocks: {

266

header: 'Custom Header Block',

267

footer: 'Custom Footer Block'

268

}

269

});

270

271

// Get block by name

272

console.log(ctx.getBlock('header')); // 'Custom Header Block'

273

console.log(ctx.getBlock('sidebar')); // undefined

274

275

// Add local blocks

276

const extendedCtx = ctx.shiftBlocks({

277

sidebar: 'Sidebar Block',

278

navigation: 'Nav Block'

279

});

280

281

console.log(extendedCtx.getBlock('sidebar')); // 'Sidebar Block'

282

console.log(extendedCtx.getBlock('header')); // 'Custom Header Block' (inherited)

283

```

284

285

### Template Body Resolution

286

287

Method for resolving template bodies to string output.

288

289

```javascript { .api }

290

interface Context {

291

/**

292

* Resolve template body to string output

293

* @param body - Template body function or content

294

* @returns Promise resolving to rendered string

295

*/

296

resolve(body: any): Promise<string>;

297

}

298

```

299

300

**Usage Examples:**

301

302

```javascript

303

// Used internally by Dust during template rendering

304

// Typically not called directly by user code

305

const ctx = dust.context({ name: 'Alice' });

306

307

// In a helper function

308

function customHelper(chunk, context, bodies, params) {

309

if (bodies.block) {

310

return context.resolve(bodies.block).then(content => {

311

return chunk.write(`<div class="wrapper">${content}</div>`);

312

});

313

}

314

return chunk;

315

}

316

```

317

318

## Context Data Resolution

319

320

### Path Resolution Rules

321

322

Understanding how Dust resolves data paths within the context stack:

323

324

```javascript

325

const ctx = dust.context({

326

// Global data

327

global: 'global-value',

328

user: { name: 'Alice' }

329

}).push({

330

// Local data (top of stack)

331

local: 'local-value',

332

user: { role: 'admin' } // Shadows global user

333

});

334

335

// Resolution priority (top of stack first)

336

console.log(ctx.get('local')); // 'local-value' (local only)

337

console.log(ctx.get('global')); // 'global-value' (global only)

338

console.log(ctx.get('user.name')); // undefined (local user has no name)

339

console.log(ctx.get('user.role')); // 'admin' (local user.role)

340

341

// Explicit current context access

342

console.log(ctx.current().local); // 'local-value'

343

```

344

345

### Special Context Variables

346

347

Dust provides special variables during iterations and template execution:

348

349

```javascript

350

// Array iteration provides special variables

351

const items = ['apple', 'banana', 'cherry'];

352

const ctx = dust.context({ items });

353

354

// When iterating over array (internally handled by sections)

355

items.forEach((item, idx) => {

356

const iterCtx = ctx.push(item, idx, items.length);

357

358

console.log(iterCtx.get('@index')); // Current index (0, 1, 2)

359

console.log(iterCtx.get('@length')); // Array length (3)

360

console.log(iterCtx.get('@first')); // true for first item

361

console.log(iterCtx.get('@last')); // true for last item

362

console.log(iterCtx.get('@odd')); // true for odd indices

363

console.log(iterCtx.get('@even')); // true for even indices

364

});

365

366

// Object iteration provides key access

367

const obj = { a: 1, b: 2, c: 3 };

368

Object.keys(obj).forEach((key, idx) => {

369

const iterCtx = ctx.push(obj[key], idx, Object.keys(obj).length);

370

iterCtx.key = key; // Key is available as property

371

372

console.log(iterCtx.get('@key')); // Current key ('a', 'b', 'c')

373

console.log(iterCtx.get('.')); // Current value (1, 2, 3)

374

});

375

```

376

377

## Advanced Context Usage

378

379

### Context in Helper Functions

380

381

How context is used within helper functions:

382

383

```javascript

384

// Register a helper that uses context

385

dust.helpers.debugContext = (chunk, context, bodies, params) => {

386

// Access current data

387

const currentData = context.current();

388

389

// Get specific values

390

const userName = context.get('user.name');

391

const templateName = context.getTemplateName();

392

393

// Push new context for body execution

394

const newContext = context.push({

395

debug: true,

396

timestamp: Date.now()

397

});

398

399

// Render body with new context

400

return chunk.render(bodies.block, newContext);

401

};

402

403

// Usage in template: {@debugContext}Content with debug info{/debugContext}

404

```

405

406

### Context Performance Considerations

407

408

Best practices for efficient context usage:

409

410

```javascript

411

// Efficient: Reuse base contexts

412

const baseCtx = dust.context({

413

config: appConfig,

414

helpers: customHelpers

415

});

416

417

// For each render, push specific data

418

function renderUserTemplate(userData) {

419

const userCtx = baseCtx.push(userData);

420

return dust.render('user-template', userCtx, callback);

421

}

422

423

// Avoid: Creating new base contexts repeatedly

424

function inefficientRender(userData) {

425

const ctx = dust.context({

426

config: appConfig, // Recreated each time

427

...userData

428

});

429

return dust.render('user-template', ctx, callback);

430

}

431

```

432

433

### Context Debugging

434

435

Utilities for debugging context resolution:

436

437

```javascript

438

// Debug helper to inspect context

439

dust.helpers.inspectContext = (chunk, context) => {

440

const debug = {

441

current: context.current(),

442

templateName: context.getTemplateName(),

443

stackDepth: 'not directly accessible' // Internal implementation detail

444

};

445

446

return chunk.write(`<!--Context: ${JSON.stringify(debug, null, 2)}-->`);

447

};

448

449

// Usage in template: {@inspectContext/}

450

```