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
- Create Template Files: Write template files for structs and enums with appropriate placeholders
- Configure JSON: Create a JSON configuration file defining the language-specific settings
- Define Wings Schema: Create your data structures in Wings format
- 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
- Template Not Found: Ensure template file paths are correct and files exist
- Invalid JSON: Validate configuration JSON syntax
- Missing Type Mappings: Ensure all Wings types used in schemas have corresponding mappings
- 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:
- Create struct and enum template files
- Define type mappings for the target language
- Configure language-specific settings (comments, imports, etc.)
- Test with various Wings schema files
- 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.