Merge pull request 'feat(templates): document templating system for .kc files' (#306) from feat/document-templates into main
Some checks failed
Deploy Docs / build-and-deploy (push) Successful in 40s
Build and Test / build (push) Has been cancelled

Reviewed-on: #306
This commit was merged in pull request #306.
This commit is contained in:
2026-02-21 15:07:43 +00:00
4 changed files with 156 additions and 2 deletions

View File

@@ -12,6 +12,7 @@
- [Workbenches](./guide/workbenches.md)
- [ztools](./guide/ztools.md)
- [Silo](./guide/silo.md)
- [Document Templates](./guide/templates.md)
# Architecture
@@ -49,6 +50,16 @@
- [Solver Service](./silo-server/SOLVER.md)
- [Roadmap](./silo-server/ROADMAP.md)
# Kindred Solver
- [Overview](./solver/overview.md)
- [Expression DAG](./solver/expression-dag.md)
- [Constraints](./solver/constraints.md)
- [Solving Algorithms](./solver/solving.md)
- [Diagnostics](./solver/diagnostics.md)
- [Assembly Integration](./solver/assembly-integration.md)
- [Writing a Custom Solver](./solver/writing-a-solver.md)
# Reference
- [Configuration](./reference/configuration.md)

View File

@@ -53,6 +53,7 @@ The silo-mod repository was split from a monorepo into three repos: `silo-client
| `Silo_TagProjects` | Multi-select dialog for assigning project tags to items |
| `Silo_Rollback` | Select a previous revision and create a new revision from that point with optional comment |
| `Silo_SetStatus` | Change revision lifecycle status: draft → review → released → obsolete |
| `Silo_SaveAsTemplate` | Save a copy of the current document as a reusable [template](./templates.md) with metadata |
### Administration
@@ -129,9 +130,11 @@ mods/silo/
├── freecad/
│ ├── InitGui.py # SiloWorkbench registration
│ ├── schema_form.py # Schema-driven item creation dialog (SchemaFormDialog)
│ ├── silo_commands.py # 14 commands + dock widgets
│ ├── silo_commands.py # 15 commands + dock widgets
│ ├── silo_origin.py # FileOrigin backend
│ ├── silo_start.py # Native start panel (database items, activity feed)
│ ├── templates.py # Template discovery, filtering, injection
│ ├── templates/ # System template .kc files + CLI injection tool
│ └── resources/icons/ # 10 silo-*.svg icons
├── silo-client/ # Shared Python API client (nested submodule)
│ └── silo_client/

140
docs/src/guide/templates.md Normal file
View File

@@ -0,0 +1,140 @@
# 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 |