# Document Templates Templates let you create new parts and assemblies from pre-configured `.kc` files. Instead of starting from a bare `App::Part` or `Assembly::AssemblyObject`, a template can include predefined tree structures, jobs, metadata, and workbench-specific features. ## How templates work A template is a normal `.kc` file with an extra `silo/template.json` descriptor inside the ZIP archive. When you select a template during **Silo > New**: 1. The template `.kc` is **copied** to the canonical file path 2. `silo/template.json` and `silo/manifest.json` are **stripped** from the copy 3. The document is **opened** in FreeCAD 4. Silo properties (part number, item ID, revision, type) are **stamped** onto the root object 5. On **save**, `kc_format.py` auto-creates a fresh manifest The original template file is never modified. ## Using templates ### Creating a new item from a template 1. **Silo > New** (Ctrl+N) 2. Select an **Item Type** (Part, Assembly, etc.) 3. The **Template** dropdown shows templates matching the selected type and category 4. Select a template (or leave as "No template" for a blank document) 5. Fill in the remaining fields and click **Create** The template combo updates automatically when you change the item type or category. ### Saving a document as a template 1. Open the document you want to use as a template 2. **Silo > Save as Template** 3. Fill in the template metadata: - **Name** — display name shown in the template picker (pre-filled from document label) - **Description** — what the template is for - **Item Types** — which types this template applies to (part, assembly, etc.) - **Categories** — category prefix filter (e.g. `F`, `M01`); leave empty for all categories - **Author** — pre-filled from your Silo login - **Tags** — comma-separated search tags 4. Click **Save Template** 5. Optionally upload to Silo for team sharing The template is saved as a copy to your personal templates directory. The original document is unchanged. ## Template search paths Templates are discovered from three locations, checked in order. Later paths shadow earlier ones by name (so you can override a system template with a personal one). | Priority | Path | Purpose | |----------|------|---------| | 1 (lowest) | `mods/silo/freecad/templates/` | System templates shipped with the addon | | 2 | `~/.local/share/FreeCAD/Templates/` | Personal templates (sister to `Macro/`) | | 3 (highest) | `~/projects/templates/` | Org-shared project templates | The personal templates directory (`Templates/`) is created automatically when you first save a template. It lives alongside the `Macro/` directory in your FreeCAD user data. ## Template descriptor schema The `silo/template.json` file inside the `.kc` ZIP has the following structure: ```json { "template_version": "1.0", "name": "Sheet Metal Part", "description": "Body with SheetMetal base feature and laser-cut job", "item_types": ["part"], "categories": [], "icon": "sheet-metal", "author": "Kindred Systems", "tags": ["sheet metal", "fabrication"] } ``` | Field | Type | Required | Description | |-------|------|----------|-------------| | `template_version` | string | yes | Schema version, currently `"1.0"` | | `name` | string | yes | Display name in the template picker | | `description` | string | no | Human-readable purpose | | `item_types` | string[] | yes | Controls visibility — `["part"]`, `["assembly"]`, or both | | `categories` | string[] | no | Category prefix filter. Empty array means all categories | | `icon` | string | no | Icon identifier (reserved for future use) | | `author` | string | no | Template author | | `tags` | string[] | no | Searchable metadata tags | ### Filtering rules - **item_types**: The template only appears when the selected item type is in this list - **categories**: If non-empty, the template only appears when the selected category starts with one of the listed prefixes. An empty list means the template is available for all categories ## Creating templates from the command line The `inject_template.py` CLI tool can inject `silo/template.json` into any `.kc` file: ```bash cd mods/silo/freecad/templates/ # Create a template from an existing .kc file python inject_template.py my-part.kc "My Custom Part" \ --type part \ --description "Part with custom features" \ --author "Your Name" \ --tag "custom" # Assembly template python inject_template.py my-assembly.kc "My Assembly" \ --type assembly \ --description "Assembly with predefined joint groups" # Template with category filtering python inject_template.py sheet-metal.kc "Sheet Metal Part" \ --type part \ --category S \ --category X \ --tag "sheet metal" \ --tag "fabrication" ``` ## Module structure ``` mods/silo/freecad/ ├── templates.py # Discovery, filtering, injection helpers ├── templates/ │ └── inject_template.py # CLI tool for injecting template.json ├── schema_form.py # Template combo in New Item form └── silo_commands.py # SaveAsTemplateDialog, Silo_SaveAsTemplate, # SiloSync.create_document_from_template() ``` ### Key functions | Function | File | Purpose | |----------|------|---------| | `discover_templates()` | `templates.py` | Scan search paths for `.kc` files with `silo/template.json` | | `filter_templates()` | `templates.py` | Filter by item type and category prefix | | `inject_template_json()` | `templates.py` | Inject/replace `silo/template.json` in a `.kc` ZIP | | `get_default_template_dir()` | `templates.py` | Returns `{userAppData}/Templates/`, creating if needed | | `get_search_paths()` | `templates.py` | Returns the 3-tier search path list | | `create_document_from_template()` | `silo_commands.py` | Copy template, strip identity, stamp Silo properties | | `_clean_template_zip()` | `silo_commands.py` | Strip `silo/template.json` and `silo/manifest.json` from a copy |