Add contract parsing, i18n extraction, template rendering, and roundtrip support for Nickel. Update backends and form parser for integration. Add testing and build infrastructure.
11 KiB
Nickel Schema to TOML Form Generation Examples
This directory contains complete, runnable examples of the TypeDialog Nickel integration workflow:
Nickel Schema → TOML Form → User Input → JSON Results → Nickel Output
Quick Start
Example 1: Simple Schema (Learning)
Generate a TOML form from a basic Nickel schema:
# Generate form
just nickel::nickel-to-form schemas/simple.ncl generated/simple/
# Execute form interactively
typedialog form generated/simple/form.toml -o results/simple_results.json
# View results
cat results/simple_results.json | jq .
What it demonstrates:
- Basic type mapping (String, Number, Bool)
- Doc comment extraction
- Default value handling
- Simple form generation
Example 2: Complex Schema (Fragmentation)
Generate fragmented forms from a schema with multiple sections:
# Generate with automatic fragmentation
just nickel::nickel-to-form schemas/complex.ncl generated/complex/
# List generated files
ls -la generated/complex/
ls -la generated/complex/fragments/
# Execute main form
typedialog form generated/complex/main_form.toml -o results/complex_results.json
What it demonstrates:
- Fragment markers (
# @fragment: name) - Multi-file form composition
- Fragment includes in main form
- Large schema organization
Generated structure:
generated/complex/
├── main_form.toml # Form with includes
└── fragments/
├── app_config.toml
├── server_config.toml
├── database_config.toml
└── cache_config.toml
Example 3: Conditional Fields (Smart Visibility)
Generate conditionals automatically from optional fields:
# Generate with conditionals
just nickel::nickel-to-form schemas/conditional.ncl generated/conditional/
# View generated conditionals
grep -A 2 'when =' generated/conditional/form.toml
# Execute form - notice conditional visibility
typedialog form generated/conditional/form.toml
What it demonstrates:
- Optional field handling
- Automatic conditional generation from contracts
- Boolean dependency detection
- Dynamic form visibility
Example generated conditionals:
[[fields]]
name = "tls_cert_path"
when = "tls_enabled == true" # Auto-generated!
[[fields]]
name = "database_url"
when = "database_enabled == true" # Auto-generated!
Example 4: i18n Extraction (Multi-Language)
Generate Fluent translation files from schema:
# Extract i18n only
just nickel::nickel-i18n schemas/i18n.ncl generated/i18n/
# View generated translations
ls -la generated/i18n/locales/
cat generated/i18n/locales/en/forms.ftl
cat generated/i18n/locales/es/forms.ftl
# Execute with Spanish locale
LOCALE=es typedialog form generated/i18n/form.toml
What it demonstrates:
- Multi-language doc comment parsing
- Fluent (.ftl) file generation
- Locale-specific form generation
- Translation key mapping
Generated translations:
# en/forms.ftl
app-name-prompt = Application name
app-name-help = Enter the application display name
# es/forms.ftl
app-name-prompt = Nombre de la aplicación
app-name-help = Ingrese el nombre de la aplicación
Example 5: Full Workflow (Schema → Results → Nickel)
Complete workflow: generate form, execute with results, render Nickel output:
# Full workflow: schema → form → results → Nickel
just nickel::nickel-workflow \
schemas/simple.ncl \
templates/config.ncl.j2 \
generated/output_config.ncl
# Validate generated Nickel
nickel typecheck generated/output_config.ncl
# View generated configuration
cat generated/output_config.ncl
What it demonstrates:
- End-to-end workflow automation
- Form execution with user input
- Template rendering with results
- Nickel validation
- Configuration generation
Directory Structure
examples/07-nickel-generation/
├── README.md # This file
├── schemas/ # Nickel schema files
│ ├── simple.ncl # Basic types only
│ ├── complex.ncl # With fragment markers
│ ├── conditional.ncl # With optional fields + boolean deps
│ └── i18n.ncl # With English/Spanish docs
├── templates/ # Jinja2 templates for rendering
│ ├── config.ncl.j2 # Basic config template
│ ├── service_spec.ncl.j2 # Kubernetes service template
│ └── deployment.ncl.j2 # Kubernetes deployment template
├── generated/ # Example outputs (reference)
│ ├── simple/
│ │ └── form.toml
│ ├── complex/
│ │ ├── main_form.toml
│ │ └── fragments/
│ ├── conditional/
│ │ └── form.toml
│ └── i18n/
│ ├── form.toml
│ └── locales/
└── results/ # Example results (reference)
└── simple_results.json
Schema Features Explained
Fragment Markers
Mark sections for automatic splitting:
# @fragment: database_config
database = { ... }
Generates separate file: fragments/database_config.toml
When to use:
- Schemas with 20+ fields
- Logical section boundaries
- Independent configuration areas
Optional Fields with Dependencies
Automatically generate conditionals:
tls_enabled | doc "Enable TLS" : Bool,
tls_cert | optional
| doc "Certificate path"
: String,
Generates:
[[fields]]
name = "tls_cert"
when = "tls_enabled == true"
Pattern: <feature>_enabled → dependent fields
Multi-Language Docs
Support multiple languages in doc comments:
field_name
| doc "English text"
| doc.es "Texto en español"
: String
Generates .ftl files for each locale with translations
Templates
config.ncl.j2
Basic application configuration template:
- Renders app metadata
- Server configuration
- Database connection (optional)
- Cache settings (conditional)
Usage:
just nickel::nickel-workflow \
schemas/simple.ncl \
templates/config.ncl.j2 \
config.ncl
service_spec.ncl.j2
Kubernetes service specification:
- Service metadata
- Port configuration
- Selector rules
- Service type (ClusterIP, NodePort, LoadBalancer)
Usage:
typedialog form <form> -o results.json
typedialog nickel-template templates/service_spec.ncl.j2 results.json -o service.ncl
nickel export service.ncl
deployment.ncl.j2
Kubernetes deployment configuration:
- Deployment metadata
- Pod replica count
- Container specification
- Resource limits and requests
- Health checks (liveness, readiness probes)
- Environment variables
Usage:
just nickel::nickel-workflow \
<schema> \
templates/deployment.ncl.j2 \
deployment.ncl
Common Workflows
Preview Form Before Generation
# Preview without writing files
just nickel::nickel-preview schemas/complex.ncl
# Then generate with full options
just nickel::nickel-to-form schemas/complex.ncl generated/complex/
Extract i18n Only
# Generate only translation files
just nickel::nickel-i18n schemas/i18n.ncl translations/
# Review translations
cat translations/locales/en/forms.ftl
cat translations/locales/es/forms.ftl
Render Template with Sample Data
# Use example results to render template
typedialog nickel-template templates/config.ncl.j2 \
results/simple_results.json \
-o sample_output.ncl
# Review output
cat sample_output.ncl
Full Interactive Workflow
# 1. Generate form
just nickel::nickel-to-form schemas/simple.ncl /tmp/form_gen/
# 2. Execute form interactively
typedialog form /tmp/form_gen/form.toml -o /tmp/results.json
# 3. Review results
cat /tmp/results.json | jq .
# 4. Render template
typedialog nickel-template templates/config.ncl.j2 \
/tmp/results.json \
-o /tmp/generated_config.ncl
# 5. Validate Nickel
nickel typecheck /tmp/generated_config.ncl
# 6. Export to JSON
nickel export /tmp/generated_config.ncl
Testing Examples
Run All Examples
#!/bin/bash
EXAMPLES_DIR="examples/07-nickel-generation"
# Test 1: Simple
echo "Testing simple schema..."
just nickel::nickel-to-form "$EXAMPLES_DIR/schemas/simple.ncl" /tmp/test_simple
[ -f /tmp/test_simple/form.toml ] && echo "✓ Simple form generated"
# Test 2: Complex
echo "Testing complex schema..."
just nickel::nickel-to-form "$EXAMPLES_DIR/schemas/complex.ncl" /tmp/test_complex
[ -f /tmp/test_complex/main_form.toml ] && echo "✓ Complex form generated"
[ -d /tmp/test_complex/fragments ] && echo "✓ Fragments created"
# Test 3: Conditional
echo "Testing conditional schema..."
just nickel::nickel-to-form "$EXAMPLES_DIR/schemas/conditional.ncl" /tmp/test_conditional
grep -q "when =" /tmp/test_conditional/form.toml && echo "✓ Conditionals generated"
# Test 4: i18n
echo "Testing i18n schema..."
just nickel::nickel-i18n "$EXAMPLES_DIR/schemas/i18n.ncl" /tmp/test_i18n
[ -f /tmp/test_i18n/locales/en/forms.ftl ] && echo "✓ English translations generated"
[ -f /tmp/test_i18n/locales/es/forms.ftl ] && echo "✓ Spanish translations generated"
echo ""
echo "All tests passed!"
Extending Examples
Adding New Schemas
- Create
schemas/my_schema.nclwith Nickel configuration - Add fragment markers (
# @fragment: name) for sections - Use optional fields for conditionals
- Use multi-language docs for i18n
{
# @fragment: my_section
my_field | doc "English" | doc.es "Español" : String,
feature_enabled | doc "Enable feature" : Bool = false,
feature_config | optional
| doc "Feature configuration"
: String,
}
Adding New Templates
- Create
templates/my_template.ncl.j2 - Use Jinja2 syntax for conditionals and loops
- Reference form result variables
- Test with sample data
{
config = {
{% for item in items %}
{{ item.name }} : String = "{{ item.value }}",
{% endfor %}
},
}
Troubleshooting
Form Generation Fails
# Verify schema syntax
nickel typecheck schemas/simple.ncl
# Check for schema-specific issues
nickel query schemas/simple.ncl
Fragment Includes Not Found
# Verify fragments directory exists
ls -la generated/complex/fragments/
# Check include paths in main form
grep includes generated/complex/main_form.toml
Conditionals Not Generated
# Verify optional fields exist
grep -A 2 "optional" schemas/conditional.ncl
# Check for boolean enable flags
grep "_enabled" schemas/conditional.ncl
i18n Not Working
# Verify locale directories created
find generated/i18n/locales/ -name "*.ftl"
# Check .ftl file format
cat generated/i18n/locales/en/forms.ftl | head
See Also
.claude/guidelines/typedialog.md- Complete TypeDialog guidetemplates/nickel/README.md- Template library documentationjust nickel::help- All available recipes/nickel-gen- Interactive slash command