or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

build-processing.mdcli.mdcore-configuration.mddebugging.mdfile-operations.mdfrontmatter.mdindex.mdplugin-system.mdutilities.md

utilities.mddocs/

0

# Utilities and Helpers

1

2

Utility methods for path resolution, file matching, environment variables, ignore patterns, and file watching. These helpers provide essential functionality for configuring and extending Metalsmith behavior.

3

4

## Capabilities

5

6

### Path Resolution

7

8

Resolve paths relative to the Metalsmith working directory.

9

10

```javascript { .api }

11

/**

12

* Resolve paths relative to the metalsmith working directory

13

* @param paths - Path segments to resolve

14

* @returns Absolute path resolved from working directory

15

*/

16

path(...paths: string[]): string;

17

```

18

19

**Usage Examples:**

20

21

```javascript

22

import Metalsmith from "metalsmith";

23

24

const metalsmith = Metalsmith(__dirname);

25

26

// Resolve paths relative to working directory

27

const srcPath = metalsmith.path('src', 'content');

28

const buildPath = metalsmith.path('build');

29

const configPath = metalsmith.path('config', 'site.json');

30

31

console.log(srcPath); // "/absolute/path/to/project/src/content"

32

console.log(buildPath); // "/absolute/path/to/project/build"

33

console.log(configPath); // "/absolute/path/to/project/config/site.json"

34

35

// Use in plugins

36

function customPlugin(files, metalsmith, done) {

37

const dataPath = metalsmith.path('data', 'api.json');

38

const templatePath = metalsmith.path('templates');

39

40

// Use resolved paths for file operations

41

done();

42

}

43

```

44

45

### File Pattern Matching

46

47

Match file paths against glob patterns using micromatch.

48

49

```javascript { .api }

50

/**

51

* Match filepaths against glob patterns

52

* @param patterns - Glob pattern(s) to match against

53

* @param input - Array of file paths to test (defaults to current files)

54

* @param options - Micromatch options (excluding 'format')

55

* @returns Array of matching file paths

56

*/

57

match(

58

patterns: string | string[],

59

input?: string[],

60

options?: MatchOptions

61

): string[];

62

63

interface MatchOptions {

64

/** Include dotfiles in matches */

65

dot?: boolean;

66

/** Case-sensitive matching */

67

nocase?: boolean;

68

/** Additional micromatch options */

69

[key: string]: any;

70

}

71

```

72

73

**Usage Examples:**

74

75

```javascript

76

const files = await metalsmith.read();

77

const filePaths = Object.keys(files);

78

79

// Match all markdown files

80

const markdownFiles = metalsmith.match('**/*.md', filePaths);

81

82

// Match multiple patterns

83

const contentFiles = metalsmith.match([

84

'**/*.md',

85

'**/*.html',

86

'**/*.txt'

87

], filePaths);

88

89

// Match with options

90

const draftFiles = metalsmith.match('**/*draft*', filePaths, {

91

nocase: true // Case-insensitive

92

});

93

94

// Use in plugins

95

function selectivePlugin(files, metalsmith, done) {

96

const targetFiles = metalsmith.match('posts/*.md');

97

98

targetFiles.forEach(filepath => {

99

// Process only matching files

100

const file = files[filepath];

101

file.processed = true;

102

});

103

104

done();

105

}

106

107

// Default input uses current files

108

metalsmith.use((files, metalsmith, done) => {

109

// Automatically matches against Object.keys(files)

110

const jsFiles = metalsmith.match('**/*.js');

111

done();

112

});

113

```

114

115

### Environment Variables

116

117

Get and set Metalsmith environment variables (case-insensitive).

118

119

```javascript { .api }

120

/**

121

* Get single environment variable

122

* @param name - Variable name (case-insensitive)

123

* @returns Variable value or undefined

124

*/

125

env(name: string): string | number | boolean | null;

126

127

/**

128

* Get all environment variables

129

* @returns Object with all environment variables

130

*/

131

env(): { [key: string]: string | number | boolean | null };

132

133

/**

134

* Set single environment variable

135

* @param name - Variable name (case-insensitive)

136

* @param value - Variable value (primitives only)

137

* @returns Metalsmith instance for chaining

138

*/

139

env(name: string, value: string | number | boolean | null): Metalsmith;

140

141

/**

142

* Set multiple environment variables

143

* @param env - Object with variable names and values

144

* @returns Metalsmith instance for chaining

145

*/

146

env(env: { [key: string]: string | number | boolean | null }): Metalsmith;

147

```

148

149

**Usage Examples:**

150

151

```javascript

152

// Set environment variables

153

metalsmith

154

.env('NODE_ENV', 'production')

155

.env('DEBUG', '@metalsmith/*')

156

.env('SITE_URL', 'https://example.com');

157

158

// Set multiple at once

159

metalsmith.env({

160

NODE_ENV: process.env.NODE_ENV,

161

DEBUG: false,

162

BUILD_TIME: Date.now()

163

});

164

165

// Get environment variables

166

const nodeEnv = metalsmith.env('NODE_ENV');

167

const isDebug = metalsmith.env('DEBUG');

168

const allEnv = metalsmith.env();

169

170

console.log('Environment:', nodeEnv);

171

console.log('Debug mode:', isDebug);

172

console.log('All vars:', allEnv);

173

174

// Use in plugins

175

function environmentAwarePlugin(files, metalsmith, done) {

176

const isDev = metalsmith.env('NODE_ENV') === 'development';

177

const debugEnabled = metalsmith.env('DEBUG');

178

179

if (isDev) {

180

// Development-specific processing

181

}

182

183

if (debugEnabled) {

184

console.log('Processing files in debug mode');

185

}

186

187

done();

188

}

189

190

// Environment variables are case-insensitive

191

metalsmith.env('debug', true);

192

console.log(metalsmith.env('DEBUG')); // true

193

```

194

195

### Ignore Patterns

196

197

Configure which files and directories to ignore during processing.

198

199

```javascript { .api }

200

/**

201

* Add files/paths to ignore list

202

* @param files - File patterns, paths, or filter functions to ignore

203

* @returns Metalsmith instance for chaining

204

*/

205

ignore(files: string | string[] | IgnoreFunction | IgnoreFunction[]): Metalsmith;

206

207

/**

208

* Get current ignore list

209

* @returns Array of ignore patterns and functions

210

*/

211

ignore(): (string | IgnoreFunction)[];

212

213

type IgnoreFunction = (filepath: string, stats: import('fs').Stats) => boolean;

214

```

215

216

**Usage Examples:**

217

218

```javascript

219

import { Stats } from 'fs';

220

221

// Ignore specific files

222

metalsmith.ignore('README.md');

223

224

// Ignore patterns

225

metalsmith.ignore([

226

'**/.DS_Store',

227

'**/Thumbs.db',

228

'**/*.tmp',

229

'drafts/**'

230

]);

231

232

// Ignore using functions

233

metalsmith.ignore((filepath, stats) => {

234

// Ignore hidden files

235

return filepath.startsWith('.');

236

});

237

238

metalsmith.ignore((filepath, stats) => {

239

// Ignore large files (>1MB)

240

return stats.size > 1024 * 1024;

241

});

242

243

// Multiple ignore rules

244

metalsmith

245

.ignore('node_modules/**')

246

.ignore('*.log')

247

.ignore((filepath, stats) => {

248

// Ignore directories named 'temp'

249

return stats.isDirectory() && filepath.endsWith('/temp');

250

});

251

252

// Get current ignore list

253

const ignoreList = metalsmith.ignore();

254

console.log('Ignoring:', ignoreList);

255

```

256

257

### File Watching

258

259

Configure file watching for automatic rebuilds (experimental feature).

260

261

```javascript { .api }

262

/**

263

* Get current watch configuration

264

* @returns Current watch settings or false if disabled

265

*/

266

watch(): false | WatchOptions;

267

268

/**

269

* Enable/disable file watching

270

* @param enabled - True to watch source directory, false to disable

271

* @returns Metalsmith instance for chaining

272

*/

273

watch(enabled: boolean): Metalsmith;

274

275

/**

276

* Watch specific paths

277

* @param paths - Directory paths or glob patterns to watch

278

* @returns Metalsmith instance for chaining

279

*/

280

watch(paths: string | string[]): Metalsmith;

281

282

/**

283

* Configure watch options

284

* @param options - Chokidar watch options

285

* @returns Metalsmith instance for chaining

286

*/

287

watch(options: WatchOptions): Metalsmith;

288

289

interface WatchOptions {

290

/** Paths to watch (default: source directory) */

291

paths?: string[];

292

/** Wait for write operations to complete before triggering */

293

awaitWriteFinish?: boolean;

294

/** Ignore initial add events */

295

ignoreInitial?: boolean;

296

/** Use polling instead of native events */

297

usePolling?: boolean;

298

/** Polling interval in milliseconds */

299

interval?: number;

300

/** Additional chokidar options */

301

[key: string]: any;

302

}

303

```

304

305

**Usage Examples:**

306

307

```javascript

308

// Enable watching (experimental)

309

metalsmith

310

.clean(false) // Use partial rebuilds for better performance

311

.watch(true) // Watch source directory

312

.build((error, files) => {

313

if (error) {

314

console.error('Build error:', error);

315

metalsmith.watch(false); // Stop watching on error

316

return;

317

}

318

console.log(`Rebuilt ${Object.keys(files).length} files`);

319

});

320

321

// Watch specific directories

322

metalsmith.watch(['src', 'templates', 'data']);

323

324

// Advanced watch configuration

325

metalsmith.watch({

326

paths: ['src/**/*.md', 'templates/**/*.hbs'],

327

awaitWriteFinish: {

328

stabilityThreshold: 2000,

329

pollInterval: 100

330

},

331

ignoreInitial: true

332

});

333

334

// Get watch status

335

const watchConfig = metalsmith.watch();

336

if (watchConfig) {

337

console.log('Watching:', watchConfig.paths);

338

} else {

339

console.log('Watch mode disabled');

340

}

341

342

// Stop watching

343

metalsmith.watch(false);

344

```

345

346

### Utility Usage Patterns

347

348

Common patterns for using utilities in plugins and workflows.

349

350

```javascript

351

// Plugin using multiple utilities

352

function utilityPlugin(options = {}) {

353

return function plugin(files, metalsmith, done) {

354

const debug = metalsmith.env('DEBUG');

355

const pattern = options.pattern || '**/*.md';

356

357

// Use path utility for file operations

358

const dataPath = metalsmith.path('data', 'config.json');

359

360

// Match files using pattern

361

const targetFiles = metalsmith.match(pattern);

362

363

if (debug) {

364

console.log(`Processing ${targetFiles.length} files matching ${pattern}`);

365

}

366

367

targetFiles.forEach(filepath => {

368

const file = files[filepath];

369

// Process file...

370

});

371

372

done();

373

};

374

}

375

376

// Environment-based configuration

377

const isProduction = metalsmith.env('NODE_ENV') === 'production';

378

const debugEnabled = metalsmith.env('DEBUG');

379

380

metalsmith

381

.clean(isProduction) // Only clean in production

382

.concurrency(isProduction ? 50 : 10) // Higher concurrency in production

383

.ignore(isProduction ? [] : ['drafts/**']) // Include drafts in development

384

.env('MINIFY', isProduction); // Set flags for plugins

385

386

// Dynamic ignore patterns

387

metalsmith.ignore((filepath, stats) => {

388

const isDraft = files[filepath]?.draft === true;

389

const isProduction = metalsmith.env('NODE_ENV') === 'production';

390

391

// Ignore drafts in production

392

return isProduction && isDraft;

393

});

394

```