CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-metalsmith

An extremely simple, pluggable static site generator for NodeJS

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

file-operations.mddocs/

File Operations

File reading and writing operations for handling individual files and file collections. These methods provide direct access to Metalsmith's file I/O system for custom processing workflows.

Capabilities

Read Directory

Read all files from a directory, parsing front-matter and creating file objects.

/**
 * Read files from directory (Promise version)
 * @param directory - Directory to read (defaults to source directory) 
 * @returns Promise resolving to Files object
 */
read(directory?: string): Promise<Files>;

/**
 * Read files from directory (callback version)
 * @param directory - Directory to read (defaults to source directory)
 * @param callback - Callback receiving error and files
 */
read(directory: string, callback: FileCallback): void;

type FileCallback = (error: Error | null, files: Files) => void;

Usage Examples:

import Metalsmith from "metalsmith";

const metalsmith = Metalsmith(__dirname);

// Read from default source directory
const files = await metalsmith.read();
console.log(`Read ${Object.keys(files).length} files`);

// Read from specific directory
const templateFiles = await metalsmith.read('./templates');

// Callback version
metalsmith.read((error, files) => {
  if (error) throw error;
  Object.keys(files).forEach(filepath => {
    console.log(`File: ${filepath}`);
    console.log(`Size: ${files[filepath].contents.length} bytes`);
  });
});

Read Single File

Read a single file by path, parsing front-matter if enabled.

/**
 * Read single file by path (Promise version)
 * @param filepath - File path (relative to source directory or absolute)
 * @returns Promise resolving to File object
 */
readFile(filepath: string): Promise<File>;

/**
 * Read single file by path (callback version)
 * @param filepath - File path (relative to source directory or absolute)
 * @param callback - Callback receiving error and file
 */
readFile(filepath: string, callback: SingleFileCallback): void;

type SingleFileCallback = (error: Error | null, file?: File) => void;

Usage Examples:

// Read specific file
const indexFile = await metalsmith.readFile('index.md');
console.log('Title:', indexFile.title);
console.log('Content:', indexFile.contents.toString());

// Read with absolute path
const configFile = await metalsmith.readFile('/path/to/config.json');

// Callback version
metalsmith.readFile('about.md', (error, file) => {
  if (error) {
    console.error('Failed to read file:', error.message);
    return;
  }
  
  console.log('File metadata:', {
    title: file.title,
    date: file.date,
    size: file.contents.length
  });
});

Write Files

Write a collection of files to the destination directory.

/**
 * Write files to destination directory (Promise version)
 * @param files - Files object to write
 * @param directory - Target directory (defaults to destination directory)
 * @returns Promise that resolves when writing is complete
 */
write(files: Files, directory?: string): Promise<void>;

/**
 * Write files to directory (callback version)
 * @param files - Files object to write
 * @param directory - Target directory (defaults to destination directory)
 * @param callback - Callback for completion
 */
write(files: Files, directory: string, callback: BuildCallback): void;

/**
 * Write files with callback only
 * @param files - Files object to write
 * @param callback - Callback for completion
 */
write(files: Files, callback: BuildCallback): void;

Usage Examples:

// Write processed files to default destination
const files = await metalsmith.read();
// ... process files with plugins
await metalsmith.write(files);

// Write to specific directory
await metalsmith.write(files, './output');

// Callback version
metalsmith.write(files, (error) => {
  if (error) {
    console.error('Write failed:', error.message);
    return;
  }
  console.log('Files written successfully');
});

Write Single File

Write a single file to the destination directory.

/**
 * Write single file (Promise version)
 * @param filepath - Target file path (relative to destination or absolute)
 * @param data - File object to write
 * @returns Promise that resolves when writing is complete
 */
writeFile(filepath: string, data: File): Promise<void>;

/**
 * Write single file (callback version)
 * @param filepath - Target file path (relative to destination or absolute)
 * @param data - File object to write  
 * @param callback - Callback for completion
 */
writeFile(filepath: string, data: File, callback: ErrorCallback): void;

type ErrorCallback = (error: Error | null) => void;

Usage Examples:

// Create and write a new file
const newFile = {
  contents: Buffer.from('# New Page\n\nThis is content.'),
  title: 'New Page',
  date: new Date()
};

await metalsmith.writeFile('new-page.html', newFile);

// Write to specific location
await metalsmith.writeFile('/absolute/path/file.txt', {
  contents: Buffer.from('File content')
});

// Callback version
metalsmith.writeFile('output.json', {
  contents: Buffer.from(JSON.stringify(data, null, 2))
}, (error) => {
  if (error) throw error;
  console.log('JSON file written');
});

File Object Structure

Understanding the File object structure for reading and writing operations.

interface File {
  /** File contents as Buffer (always present) */
  contents: Buffer;
  /** Node.js fs.Stats object with file system metadata */
  stats?: import('fs').Stats;
  /** Octal file permission mode (e.g., "0644") */
  mode?: string;
  /** Front-matter properties and custom metadata */
  [key: string]: any;
}

interface Files {
  /** File path mapped to File object */
  [filepath: string]: File;
}

File Manipulation Examples:

// Reading and modifying file contents
const files = await metalsmith.read();

Object.keys(files).forEach(filepath => {
  const file = files[filepath];
  
  // Access file contents
  const content = file.contents.toString();
  
  // Access front-matter data
  console.log('Title:', file.title);
  console.log('Date:', file.date);
  console.log('Tags:', file.tags);
  
  // Modify contents
  file.contents = Buffer.from(content.toUpperCase());
  
  // Add custom metadata
  file.processedAt = new Date();
  file.wordCount = content.split(/\s+/).length;
  
  // Preserve file stats and mode
  console.log('File size:', file.stats?.size);
  console.log('File mode:', file.mode);
});

await metalsmith.write(files);

Custom File Processing Workflows

Examples of custom workflows using file operations directly.

// Custom build pipeline
async function customBuild() {
  const metalsmith = Metalsmith(__dirname);
  
  // Read source files
  const sourceFiles = await metalsmith.read();
  console.log(`Read ${Object.keys(sourceFiles).length} source files`);
  
  // Read template files separately
  const templates = await metalsmith.read('./templates');
  console.log(`Read ${Object.keys(templates).length} templates`);
  
  // Process files through plugins
  const processedFiles = await metalsmith.run(sourceFiles);
  
  // Write to multiple locations
  await metalsmith.write(processedFiles, './public');
  await metalsmith.write(processedFiles, './backup');
  
  console.log('Custom build complete');
}

// Selective file processing
async function processSpecificFiles() {
  const metalsmith = Metalsmith(__dirname);
  
  // Read only markdown files
  const allFiles = await metalsmith.read();
  const markdownFiles = {};
  
  Object.keys(allFiles)
    .filter(filepath => filepath.endsWith('.md'))
    .forEach(filepath => {
      markdownFiles[filepath] = allFiles[filepath];
    });
  
  // Process only markdown files
  const processed = await metalsmith.run(markdownFiles);
  
  // Write processed files
  await metalsmith.write(processed);
}

Error Handling for File Operations

Common error scenarios and handling patterns.

try {
  const files = await metalsmith.read();
} catch (error) {
  if (error.code === 'ENOENT') {
    console.error('Source directory not found');
  } else if (error.code === 'EACCES') {
    console.error('Permission denied reading files');
  } else if (error.code === 'invalid_frontmatter') {
    console.error('Invalid front-matter in file:', error.message);
  } else {
    console.error('Read error:', error.message);
  }
}

// Write error handling
try {
  await metalsmith.write(files);
} catch (error) {
  if (error.code === 'failed_write') {
    console.error('Failed to write file:', error.message);
  } else if (error.code === 'EACCES') {
    console.error('Permission denied writing files');
  } else {
    console.error('Write error:', error.message);
  }
}

docs

build-processing.md

cli.md

core-configuration.md

debugging.md

file-operations.md

frontmatter.md

index.md

plugin-system.md

utilities.md

tile.json