feat(templates): document templating system for .kc files
All checks were successful
Build and Test / build (pull_request) Successful in 29m12s
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
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
140
docs/src/guide/templates.md
Normal 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 |
|
||||
Reference in New Issue
Block a user