Skip to content

Templating System

Overview

Templating system allows you to define custom templates for languages that aren't currently supported or to customize the output format for existing languages.

Template Configuration Structure

The Wings templating system is configured using JSON files that define how code should be generated for specific programming languages. Each template configuration contains several key sections:

Required Fields

comment (string) required

The language line prefix for comments.

Examples: - // for TypeScript, Java, C++ - # for Python, Ruby, Bash - -- for SQL, Haskell

filename (Case) required

The case/format in which the output filename should be written.

Supported Cases: - camelCase - PascalCase - snake_case - kebab-case - SCREAMING_SNAKE_CASE

filetype (string) required

The file extension for the generated files. This is used for: - Deduplication of language template files - Appending to the generated filename

Examples: - "ts" for TypeScript files - "py" for Python files - "java" for Java files - "cpp" for C++ files

templates (object) required

Defines the template files to use for different code structures.

Structure:

{
  "templates": {
    "struct": "path/to/struct_template.txt",
    "enum": "path/to/enum_template.txt"
  }
}

types (array of objects) required

Maps Wings types to target language types.

Structure:

{
  "types": [
    {
      "wingsType": "str",
      "targetType": "string",
      "targetInit": "\"\"",
      "requiredImport": ""
    }
  ]
}

Optional Fields

implementFormat (string)

Default: "{#IMPLEMENT}"

The string format used to declare that a class extends or implements another class.

Examples: - "extends {#IMPLEMENT}" for Java - "implements {#IMPLEMENT}" for interfaces - ": {#IMPLEMENT}" for C++

importPath (object)

Controls how import statements are generated.

Structure:

{
  "importPath": {
    "format": "{#IMPORT}",
    "separator": "/",
    "pathType": "relative",
    "prefix": "",
    "level": 1
  }
}

Fields: - format: Import statement format (default: "{#IMPORT}") - separator: Path separator (default: "/", some languages use ".") - pathType: "never", "absolute", or "relative" - prefix: Prefix for import paths - level: Folder level for imports (0 = file itself, 1 = parent folder, etc.)

indentation (object)

Controls code indentation in generated files.

Structure:

{
  "indentation": {
    "spacing": "  ",
    "preIndent": false
  }
}

Fields: - spacing: Defines the "tab" width (default: "") - preIndent: Whether imported functions should be indented (default: false)

parseFormat (string)

Default: ""

General fallback option for parsing when more specific targetParse is not defined.

Template Placeholders

The Wings templating system uses specific placeholder syntax that gets replaced during code generation:

Core Placeholders

{#IMPLEMENT}

Used in the implementFormat to specify inheritance or interface implementation.

Example Template:

public class {#CLASS_NAME} {#IMPLEMENT} {
    // class body
}

{#IMPORT}

Used in import statements to specify the import path.

Example Template:

import { {#IMPORT_TYPES} } from '{#IMPORT}';

Type Mapping

The types array maps Wings primitive types to target language types:

Common Type Mappings

String Types:

{
  "wingsType": "str",
  "targetType": "string",
  "targetInit": "\"\"",
  "requiredImport": ""
}

Number Types:

{
  "wingsType": "int",
  "targetType": "number",
  "targetInit": "0",
  "requiredImport": ""
}

Boolean Types:

{
  "wingsType": "bool",
  "targetType": "boolean",
  "targetInit": "false",
  "requiredImport": ""
}

Array Types:

{
  "wingsType": "array",
  "targetType": "Array<{#TYPE}>",
  "targetInit": "[]",
  "requiredImport": ""
}

Template File Structure

Template files are text files that contain the skeleton code for structs and enums, with placeholders that get replaced during generation.

Struct Template Example

// {#COMMENT} Generated by Wings
{#IMPORTS}

export interface {#STRUCT_NAME} {#IMPLEMENT} {
{#FIELDS}
}

Enum Template Example

// {#COMMENT} Generated by Wings
{#IMPORTS}

export enum {#ENUM_NAME} {
{#VALUES}
}

Complete Configuration Example

Here's a complete template configuration for TypeScript:

{
  "comment": "//",
  "filename": "PascalCase",
  "filetype": "ts",
  "implementFormat": "extends {#IMPLEMENT}",
  "importPath": {
    "format": "import {{ {#IMPORT_TYPES} }} from '{#IMPORT}';",
    "separator": "/",
    "pathType": "relative",
    "prefix": "./",
    "level": 1
  },
  "indentation": {
    "spacing": "  ",
    "preIndent": false
  },
  "parseFormat": "",
  "templates": {
    "struct": "templates/typescript/struct.ts.template",
    "enum": "templates/typescript/enum.ts.template"
  },
  "types": [
    {
      "wingsType": "str",
      "targetType": "string",
      "targetInit": "\"\"",
      "requiredImport": ""
    },
    {
      "wingsType": "int",
      "targetType": "number",
      "targetInit": "0",
      "requiredImport": ""
    },
    {
      "wingsType": "bool",
      "targetType": "boolean",
      "targetInit": "false",
      "requiredImport": ""
    },
    {
      "wingsType": "array",
      "targetType": "Array<{#TYPE}>",
      "targetInit": "[]",
      "requiredImport": ""
    }
  ]
}

Usage Workflow

  1. Create Template Files: Write template files for structs and enums with appropriate placeholders
  2. Configure JSON: Create a JSON configuration file defining the language-specific settings
  3. Define Wings Schema: Create your data structures in Wings format
  4. Generate Code: Run Wings to generate code files in your target language

Best Practices

Template Design

  • Keep templates simple and focused on structure
  • Use consistent placeholder naming
  • Include proper commenting and formatting
  • Test templates with various data structures

Configuration Management

  • Use descriptive names for template files
  • Organize templates by language in separate folders
  • Document custom type mappings
  • Validate JSON configuration files

Type Mapping

  • Cover all primitive types used in your Wings schemas
  • Provide sensible default values for initialization
  • Include required imports for complex types
  • Consider nullable and optional type variants

Advanced Features

Custom Import Handling

The importPath configuration allows fine-grained control over how imports are generated:

{
  "importPath": {
    "format": "from {#IMPORT} import {#IMPORT_TYPES}",
    "separator": ".",
    "pathType": "absolute",
    "prefix": "myproject",
    "level": 2
  }
}

Conditional Logic

Templates can include conditional logic based on the presence of certain fields or inheritance:

class {#CLASS_NAME}{#IMPLEMENT}:
    """Generated by Wings"""

    def __init__(self):
{#INIT_FIELDS}

Multiple File Generation

Wings can generate multiple files from a single schema by using different template configurations for different aspects of the code (interfaces, implementations, tests, etc.).

Troubleshooting

Common Issues

  1. Template Not Found: Ensure template file paths are correct and files exist
  2. Invalid JSON: Validate configuration JSON syntax
  3. Missing Type Mappings: Ensure all Wings types used in schemas have corresponding mappings
  4. Import Errors: Check importPath configuration and template import syntax

Debugging Tips

  • Start with simple templates and gradually add complexity
  • Test type mappings with basic data structures first
  • Use the Wings validation tools to check configuration
  • Review generated code for syntax errors in target language

Extending Wings

The templating system is designed to be extensible. To add support for a new language:

  1. Create struct and enum template files
  2. Define type mappings for the target language
  3. Configure language-specific settings (comments, imports, etc.)
  4. Test with various Wings schema files
  5. Contribute back to the Wings project

This templating system provides a flexible foundation for generating consistent, well-structured code across multiple programming languages while maintaining the ability to customize output for specific needs.