All checks were successful
Build and Test / build (pull_request) Successful in 29m12s
Add a template system integrated with Silo new-item creation that lets users create parts from pre-configured .kc templates and save existing documents as reusable templates. Changes: - mods/silo: template discovery, picker UI, Save as Template command, 3-tier search paths (system, personal, org-shared) - docs: template guide, SUMMARY.md entry, silo.md command reference
141 lines
5.9 KiB
Markdown
141 lines
5.9 KiB
Markdown
# 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 |
|