generated from coulomb/repo-seed
refactor: use abstract ITEM placeholders with dynamic property mapping
Changed from fixed TASK placeholders to flexible ITEM placeholders that
automatically map all CSV fields to template placeholders.
Key changes:
- Renamed task-template → item-template in all templates
- Changed TASK_* → ITEM_* placeholder naming
- Implemented dynamic placeholder generation from item properties
- Any field in fieldMapping now creates ITEM_{FIELD} placeholder
- Updated all tests and documentation
Naming convention: CSV field → item.property → ITEM_PROPERTY
Example: "assignee" → item.assignee → {{ITEM_ASSIGNEE}}
This enables users to add custom fields without modifying generator code:
- Add "assignee": "Assignee" to fieldMapping
- Use {{ITEM_ASSIGNEE}} in template
- No code changes required
Benefits:
- More flexible and extensible
- Clearer abstraction (items vs tasks)
- Consistent naming convention
- Better documented
All 56 tests passing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -12,7 +12,7 @@ A valid template-v2.svg file must contain:
|
||||
2. **`<defs>` section** containing three required template elements:
|
||||
- `<g id="month-template">` - Defines how each month column is rendered
|
||||
- `<g id="lane-template">` - Defines how each lane (epic/swimlane) is rendered
|
||||
- `<g id="task-template">` - Defines how each task item is rendered
|
||||
- `<g id="item-template">` - Defines how each task item is rendered
|
||||
3. **Main content area** with `{{MONTHS}}` and `{{LANES}}` placeholders
|
||||
4. **Optional styling** (gradients, filters, patterns, etc.)
|
||||
|
||||
@@ -37,11 +37,11 @@ A valid template-v2.svg file must contain:
|
||||
font-family="Arial" font-size="14" font-weight="bold" fill="#212121">{{LANE_NAME}}</text>
|
||||
</g>
|
||||
|
||||
<!-- Task template -->
|
||||
<g id="task-template" style="display:none">
|
||||
<circle cx="{{TASK_X}}" cy="{{TASK_Y}}" r="6" fill="#1976D2"/>
|
||||
<!-- Item template -->
|
||||
<g id="item-template" style="display:none">
|
||||
<circle cx="{{ITEM_X}}" cy="{{ITEM_Y}}" r="6" fill="#1976D2"/>
|
||||
<text x="{{TEXT_X}}" y="{{TEXT_Y}}"
|
||||
font-family="Arial" font-size="11" fill="#424242">{{TASK_ID}} {{TASK_TITLE}}</text>
|
||||
font-family="Arial" font-size="11" fill="#424242">{{ITEM_ID}} {{ITEM_TITLE}}</text>
|
||||
</g>
|
||||
</defs>
|
||||
|
||||
@@ -80,16 +80,38 @@ A valid template-v2.svg file must contain:
|
||||
| `{{LABEL_Y}}` | Y position for lane label | 140 |
|
||||
| `{{LANE_NAME}}` | Lane name text (XML-escaped) | "Development" |
|
||||
|
||||
### Task Template Placeholders
|
||||
### Item Template Placeholders
|
||||
|
||||
| Placeholder | Description | Example Value |
|
||||
|------------|-------------|---------------|
|
||||
| `{{TASK_X}}` | X position of task marker | 400 |
|
||||
| `{{TASK_Y}}` | Y position of task marker | 150 |
|
||||
| `{{TEXT_X}}` | X position for task text | 412 |
|
||||
| `{{TEXT_Y}}` | Y position for task text | 154 |
|
||||
| `{{TASK_ID}}` | Task ID (XML-escaped) | "T-123" |
|
||||
| `{{TASK_TITLE}}` | Task title (XML-escaped) | "Implement feature" |
|
||||
| `{{ITEM_X}}` | X position of item marker | 400 |
|
||||
| `{{ITEM_Y}}` | Y position of item marker | 150 |
|
||||
| `{{TEXT_X}}` | X position for item text | 412 |
|
||||
| `{{TEXT_Y}}` | Y position for item text | 154 |
|
||||
| `{{ITEM_ID}}` | Item ID (XML-escaped) | "T-123" |
|
||||
| `{{ITEM_TITLE}}` | Item title (XML-escaped) | "Implement feature" |
|
||||
|
||||
**Dynamic Data Placeholders:**
|
||||
|
||||
The generator automatically creates placeholders for **all properties** in your CSV data using the naming convention: `ITEM_{PROPERTY_UPPERCASE}`.
|
||||
|
||||
For example, if your `fieldMapping` includes:
|
||||
```json
|
||||
{
|
||||
"id": "ID",
|
||||
"title": "Title",
|
||||
"assignee": "Assignee",
|
||||
"priority": "Priority"
|
||||
}
|
||||
```
|
||||
|
||||
The following placeholders become available:
|
||||
- `{{ITEM_ID}}` - from the `id` field
|
||||
- `{{ITEM_TITLE}}` - from the `title` field
|
||||
- `{{ITEM_ASSIGNEE}}` - from the `assignee` field
|
||||
- `{{ITEM_PRIORITY}}` - from the `priority` field
|
||||
|
||||
**Note:** The `due` field is used for positioning and is not available as a placeholder (use `{{MONTH_LABEL}}` for date display).
|
||||
|
||||
### Global Placeholders
|
||||
|
||||
@@ -107,7 +129,7 @@ These appear in the main template body (not in template elements):
|
||||
1. Open template-v2.svg in Inkscape
|
||||
2. Locate template elements in the Layers panel (inside `<defs>`)
|
||||
3. Edit shapes, colors, fonts, etc. as needed
|
||||
4. **Important**: Keep `id="month-template"`, `id="lane-template"`, `id="task-template"` unchanged
|
||||
4. **Important**: Keep `id="month-template"`, `id="lane-template"`, `id="item-template"` unchanged
|
||||
5. **Important**: Keep `{{PLACEHOLDER}}` text exactly as is - these are replaced at runtime
|
||||
6. Save file (keep SVG format, avoid Inkscape-specific extensions)
|
||||
|
||||
@@ -190,8 +212,8 @@ Use SVG filters:
|
||||
</feMerge>
|
||||
</filter>
|
||||
|
||||
<g id="task-template" style="display:none">
|
||||
<circle cx="{{TASK_X}}" cy="{{TASK_Y}}" r="6" fill="#1976D2" filter="url(#dropShadow)"/>
|
||||
<g id="item-template" style="display:none">
|
||||
<circle cx="{{ITEM_X}}" cy="{{ITEM_Y}}" r="6" fill="#1976D2" filter="url(#dropShadow)"/>
|
||||
...
|
||||
</g>
|
||||
</defs>
|
||||
@@ -229,7 +251,7 @@ To change the overall layout, you would need to modify generator.js. Templates c
|
||||
- Ensure template has all three required elements in `<defs>`:
|
||||
- `<g id="month-template">`
|
||||
- `<g id="lane-template">`
|
||||
- `<g id="task-template">`
|
||||
- `<g id="item-template">`
|
||||
- Check that IDs are exactly as shown (case-sensitive)
|
||||
- Verify elements are inside `<defs>` section
|
||||
|
||||
|
||||
Reference in New Issue
Block a user