Jesús Pérez 82e52fc632
feat(nickel): implement roundtrip and contract parsing
Add contract parsing, i18n extraction, template rendering, and roundtrip
support for Nickel. Update backends and form parser for integration.
Add testing and build infrastructure.
2025-12-19 03:18:48 +00:00
..

Nickel Template Library

Reutilizable template library for generating Nickel configuration schemas from TypeDialog forms.

Structure

Fields (fields/)

Basic field templates for different data types. Each template generates a single field definition.

  • string_field.ncl.j2 - String field with optional doc and contract
  • number_field.ncl.j2 - Number field with validation
  • boolean_field.ncl.j2 - Boolean flag field
  • optional_field.ncl.j2 - Optional field wrapper (any type)
  • enum_field.ncl.j2 - Enumerated field with predefined options

Forms (forms/)

Complete schema templates for specific use cases. Each generates a full configuration structure.

  • config_schema.ncl.j2 - General application configuration
  • service_spec.ncl.j2 - Kubernetes service specification
  • deployment.ncl.j2 - Deployment configuration with environment and health checks

Macros (macros/)

Reusable macro definitions for common patterns.

  • contracts.ncl.j2 - Validation contract definitions (NonEmpty, port ranges, etc.)
  • validation.ncl.j2 - Predicate macros (length, range, etc.)
  • metadata.ncl.j2 - Documentation and type annotation helpers

Usage

Field Templates

Use in form templates with Tera include syntax:

{% include "fields/string_field.ncl.j2" with {
  name: "app_name",
  doc: "Application name",
  contract: "std.string.NonEmpty",
  default: "myapp"
} %}

Form Templates

Render a complete schema:

typedialog nickel-template forms/config_schema.ncl.j2 form_results.json -o config.ncl

Macro Templates

Include macros in custom templates:

{% include "macros/contracts.ncl.j2" %}
{% include "macros/validation.ncl.j2" %}

Then use the defined macros:

{{ non_empty_string("username", "User login name") }}
{{ port_number("server_port", "HTTP port") }}

Template Context Variables

Templates expect the following context from form results:

{
  "name": "field_name",
  "doc": "field description",
  "contract": "std.string.NonEmpty",
  "default": "default_value",
  "field_type": "String|Number|Bool",
  "options": ["option1", "option2"],
  "groups_by_section": { "section_name": [...fields...] }
}

Examples

Simple Configuration Schema

Create a form with fields for app name, version, and debug mode:

[[fields]]
name = "app_name"
type = "text"
prompt = "Application name"
required = true

[[fields]]
name = "app_version"
type = "text"
prompt = "Version"
default = "1.0.0"

[[fields]]
name = "debug_mode"
type = "confirm"
prompt = "Enable debug mode"

Render with template:

typedialog nickel-template forms/config_schema.ncl.j2 results.json -o config.ncl

Output:

{
  app = {
    name | doc "Application name" : String = "myapp",
    version | doc "Version" : String = "1.0.0",
    debug_mode | doc "Enable debug mode" : Bool = true,
  },
}

Service Specification

Use for Kubernetes or containerized deployments:

typedialog form forms/service_spec.ncl.j2 \
  -o service_results.json

typedialog nickel-template forms/service_spec.ncl.j2 \
  service_results.json -o service.ncl

nickel export service.ncl

Extending

Create new templates following these conventions:

  1. Single-field templatesfields/{type}_field.ncl.j2
  2. Schema templatesforms/{purpose}_schema.ncl.j2
  3. Macro librariesmacros/{category}.ncl.j2

All templates use Jinja2 syntax. Refer to Tera documentation for available filters and functions.

Best Practices

  • Use meaningful variable names in templates
  • Document required context variables with comments
  • Keep templates DRY by using macros for common patterns
  • Validate generated Nickel with nickel typecheck
  • Version templates with your forms for consistency