Skip to content

Guide: Authoring Plating Bundles

This guide provides a practical walkthrough for developers on how to create and maintain documentation, examples, and tests for their components using the .plating system.

๐Ÿค– AI-Generated Content

This documentation was generated with AI assistance and is still being audited. Some, or potentially a lot, of this information may be inaccurate. Learn more.

Step 1: Adorn Components with Templates

When you create a new component (e.g., a resource named my_resource.py), the first step is to create its documentation bundle using the adorn command.

Run the adorn command:

plating adorn --component-type resource
This command will find my_resource.py and, seeing it has no documentation template, create the following structure:
src/pyvider/components/resources/
โ”œโ”€โ”€ my_resource.py
โ””โ”€โ”€ my_resource.plating/          # <-- Created
    โ”œโ”€โ”€ docs/
    โ”‚   โ””โ”€โ”€ my_resource.tmpl.md     # <-- Created
    โ””โ”€โ”€ examples/
        โ””โ”€โ”€ basic.tf                # <-- Created
The created files will contain standard boilerplate to get you started.

Step 2: Populate the Documentation Template

Open the main template file, my_resource.plating/docs/my_resource.tmpl.md. This is where you write the primary documentation for your component.

  • Update the Frontmatter: Edit the page_title and description fields.
  • Write the Introduction: Add a clear, high-level description of what your component does.
  • Use Template Functions: The boilerplate will already contain {{ example("basic") }} and {{ schema() }}. These are essential and should be kept.

Step 3: Write Meaningful Examples

Open my_resource.plating/examples/basic.tf and replace the placeholder content with a realistic, working example of your component. For components with multiple use cases, you can add more files (e.g., advanced.tf) and include them by name with {{ example("advanced") }}.

Step 4: Plate and Verify Documentation

Once you have authored your documentation template and examples, run the plate command to generate the final documentation.

plating plate --output-dir docs/
This will create the final Markdown file (e.g., docs/resources/my_resource.md). Always review the generated file to ensure it looks correct.

Step 5: Validate Documentation

After generating documentation, validate it for markdown quality:

plating validate --output-dir docs/

This will check your documentation for: - Markdown linting errors - Broken links - Formatting issues - Schema consistency

Advanced: Grouped Examples

For comprehensive examples that demonstrate multiple components working together, you can create grouped examples:

Creating Grouped Examples

Create subdirectories within your examples/ folder:

my_resource.plating/examples/
โ”œโ”€โ”€ basic.tf              # Simple flat example
โ””โ”€โ”€ full_stack/          # Grouped example directory
    โ””โ”€โ”€ main.tf          # Required entry point

How Grouped Examples Work

  1. Discovery: Plating finds all directories with main.tf files
  2. Compilation: Examples from multiple components are combined
  3. Generation: Creates:
  4. provider.tf with required_providers block
  5. Component-specific .tf files
  6. README.md with terraform commands
  7. Fixtures: Any fixtures in fixtures/ are copied to the output

Example Structure

# Multiple components contribute to the same group
resource1.plating/examples/full_stack/main.tf
resource2.plating/examples/full_stack/main.tf
data_source1.plating/examples/full_stack/main.tf

# Compiles to:
examples/full_stack/
โ”œโ”€โ”€ provider.tf           # Auto-generated
โ”œโ”€โ”€ resource1.tf          # From resource1
โ”œโ”€โ”€ resource2.tf          # From resource2
โ”œโ”€โ”€ data_source1.tf       # From data_source1
โ””โ”€โ”€ README.md            # Auto-generated with instructions

Best Practices for Grouped Examples

  1. Use meaningful group names: full_stack, minimal, advanced
  2. Always include main.tf: Required for group discovery
  3. Add fixtures if needed: Place test data in fixtures/ directory
  4. Avoid filename conflicts: Each component's files should be uniquely named

Bundle Structure Reference

Each component has a .plating bundle with a standardized directory structure:

my_resource.plating/
โ”œโ”€โ”€ docs/
โ”‚   โ”œโ”€โ”€ my_resource.tmpl.md    # Main template
โ”‚   โ””โ”€โ”€ _partial.md             # Reusable partials (optional)
โ”œโ”€โ”€ examples/
โ”‚   โ”œโ”€โ”€ basic.tf                # Example configurations
โ”‚   โ”œโ”€โ”€ advanced.tf             # (optional)
โ”‚   โ””โ”€โ”€ full_stack/             # Grouped examples (optional)
โ”‚       โ””โ”€โ”€ main.tf             # Required entry point
โ””โ”€โ”€ fixtures/                   # Test fixtures (optional)
    โ””โ”€โ”€ data.json               # Test data files

Directory Details

docs/ - Documentation templates - *.tmpl.md - Jinja2 templates that render to final markdown - _partial.md - Reusable template fragments (use with include() or render())

examples/ - Terraform/Python examples - .tf files for resources/data sources (flat examples) - .py files for Python API examples - Subdirectories with main.tf for grouped examples that combine multiple components

fixtures/ - Test data (optional) - JSON, YAML, or other data files used in examples or tests

Template Functions Reference

Plating provides powerful template functions you can use in your .tmpl.md files:

{{ schema() }}

Renders the component's schema as a formatted markdown table with attributes, types, and descriptions.

Example:

## Schema

{{ schema() }}

{{ example('name') }}

Includes an example file from the examples/ directory in a terraform code block.

Example:

## Example Usage

{{ example('basic') }}

## Advanced Example

{{ example('advanced') }}

{{ include('filename') }}

Includes a static partial file from the docs/ directory without rendering.

Example:

{{ include('_partial.md') }}

{{ render('filename') }}

Renders a dynamic template partial with the current context (variables, functions).

Example:

{{ render('_partial.md') }}

When to use include() vs render(): - Use include() for static markdown content - Use render() when partials need access to template functions or variables