Investigate: Dynamic Template Categories from TEMPLATE_CATEGORIES File
IMPLEMENTATION RULES: Before implementing this plan, read and follow:
- WORKFLOW.md - The implementation process
- PLANS.md - Plan structure and best practices
Status: Completedā
Completed: 2026-04-02
Goal: Replace hardcoded template categories in dev-template.sh and dev-template-ai.sh with dynamic categories read from the TEMPLATE_CATEGORIES file provided by the dev-templates repo.
Priority: High
Last Updated: 2026-04-01
Related:
helpers-no/dev-templatesāwebsite/docs/ai-developer/plans/backlog/INVESTIGATE-dct-template-metadata-update.mdā the dev-templates side investigation documenting all metadata changes- The
TEMPLATE_CATEGORIESfile is now available intemplates/TEMPLATE_CATEGORIESandai-templates/TEMPLATE_CATEGORIES(auto-synced by CI fromscripts/lib/TEMPLATE_CATEGORIES)
Problemā
Both dev-template.sh and dev-template-ai.sh have hardcoded categories:
dev-template.sh (lines ~120-180):
declare -g -A CATEGORY_WEB_SERVER
declare -g -A CATEGORY_WEB_APP
declare -g -A CATEGORY_OTHER
case "$INFO_CATEGORY" in
WEB_SERVER)
CATEGORY_WEB_SERVER["$(basename "$dir")"]=$idx
;;
WEB_APP)
CATEGORY_WEB_APP["$(basename "$dir")"]=$idx
;;
*)
CATEGORY_OTHER["$(basename "$dir")"]=$idx
;;
esac
dev-template-ai.sh has the same pattern with CATEGORY_WORKFLOW and CATEGORY_OTHER.
The category WEB_SERVER has been renamed to BASIC_WEB_SERVER in dev-templates. Templates now use this new value. The hardcoded WEB_SERVER) case match will fail and all web server templates will show under "Other".
Solution: Source TEMPLATE_CATEGORIESā
The dev-templates repo now provides a TEMPLATE_CATEGORIES file in both templates/ and ai-templates/. This file is available after sparse-checkout ā no extra download needed.
File location after downloadā
$TEMPLATE_REPO_DIR/templates/TEMPLATE_CATEGORIES
$TEMPLATE_REPO_DIR/ai-templates/TEMPLATE_CATEGORIES
File formatā
DCT-style CATEGORY_TABLE ā pipe-delimited, can be sourced as bash:
# Format: ORDER|ID|NAME|DESCRIPTION|TAGS|LOGO|EMOJI
readonly TEMPLATE_CATEGORY_TABLE="
0|BASIC_WEB_SERVER|Basic Web Server Templates|Minimal web server templates...|webserver backend...|webserver-logo.svg|š
1|WEB_APP|Web Application Templates|Frontend web application...|webapp frontend...|webapp-logo.svg|š±
2|WORKFLOW|Workflow Templates|AI-assisted development...|ai workflow...|workflow-logo.svg|š¤
"
How to use itā
- Source the file:
source "$TEMPLATE_REPO_DIR/templates/TEMPLATE_CATEGORIES" - Parse
TEMPLATE_CATEGORY_TABLEto build dynamic category grouping - Use the emoji field for menu display
- Use the name field for dialog headers
- No more hardcoded case statements ā any new category added to dev-templates automatically works
Suggested implementationā
Move the category parsing to lib/template-common.sh since both dev-template.sh and dev-template-ai.sh need it. Create a function like:
build_category_groups() {
# Parse TEMPLATE_CATEGORY_TABLE and create associative arrays dynamically
# For each category: CATEGORY_<ID> associative array
# Store category metadata (name, emoji) for menu rendering
}
Additional findings from gap analysisā
1. show_template_menu() dialog legend is hardcodedā
Line 204 in dev-template.sh:
"Choose a template (ESC to cancel):\n\nš=Web Server š±=Web App š¦=Other"
This legend must be generated dynamically from category emojis and names in TEMPLATE_CATEGORY_TABLE.
2. scan_templates() is duplicated and should become one shared functionā
Both scripts have nearly identical scan_templates() functions. The only difference is the subdirectory path. With dynamic categories, the category grouping code becomes identical too. Move to lib/template-common.sh as a function that takes the subdirectory as parameter:
scan_templates() {
local templates_subdir="$1" # "templates" or "ai-templates"
# ... rest is identical
}
This eliminates ~80 lines of duplication.
3. TEMPLATE_CATEGORIES is available after sparse-checkoutā
The file is at $TEMPLATE_REPO_DIR/templates/TEMPLATE_CATEGORIES (or ai-templates/TEMPLATE_CATEGORIES). Source it in scan_templates() before the scan loop ā no special download needed.
4. Match dev-setup.sh category menu patternā
dev-setup.sh has a two-level menu: first pick a category, then pick a tool within that category. The template menu currently shows all templates in a flat list grouped by emoji prefix.
dev-setup.sh pattern (from show_category_menu() at line 2050):
- Iterates category IDs in defined order (
get_all_category_ids) - Skips empty categories (
CATEGORY_COUNTS) - Shows category name and count as help text
- Returns selected category key
- Then shows items within that category
Decision: Two-level menu, same as dev-setup.sh's "Browse & Install Tools":
- Category menu ā shows categories with template count (e.g., "Basic Web Server Templates (6 templates)")
- Template menu ā shows templates within selected category
This matches the existing dev-setup UX. The user already knows this pattern from "Browse & Install Tools" ā category ā tool. Templates follow the same flow: "Create project from template" ā category ā template.
Functions needed (following dev-setup.sh pattern):
show_template_category_menu()ā likeshow_category_menu()in dev-setup.shshow_templates_in_category()ā likeshow_tools_in_category()in dev-setup.sh- Loop: category menu ā template list ā details ā confirm (back to category if cancelled)
5. Replace show_template_menu() with two-level menu in shared libraryā
The current flat show_template_menu() is replaced by two functions in lib/template-common.sh:
show_template_category_menu() {
local title="$1" # "Project Templates" or "AI Workflow Templates"
# Show categories with template count, skip empty categories
# Returns selected category ID
}
show_templates_in_category() {
local category_id="$1"
local title="$2"
# Show templates filtered by category
# Show template details on selection
# Returns to category menu if cancelled
}
The main selection loop in both scripts becomes:
while true; do
category=$(show_template_category_menu "Project Templates")
show_templates_in_category "$category" "Project Templates"
done
6. select_template() must move to shared library and handle both pathsā
Both scripts have nearly identical select_template() functions. With two-level menu, the interactive path changes but direct selection stays the same. This becomes one shared function:
select_template() {
local param_name="$1"
local templates_subdir="$2"
local title="$3"
if [ -n "$param_name" ]; then
# Direct selection: find by name, error with list if not found
else
# Interactive: two-level menu (category ā template ā details ā confirm)
fi
# Sets globals: TEMPLATE_INDEX, SELECTED_TEMPLATE, TEMPLATE_PATH
}
Critical: The function must set TEMPLATE_INDEX as a global ā the calling script needs it to access TEMPLATE_TOOLS_LIST[$TEMPLATE_INDEX], TEMPLATE_README_LIST[$TEMPLATE_INDEX], etc.
It should also set TEMPLATE_PATH since both scripts build the same path: $TEMPLATE_REPO_DIR/$subdir/$SELECTED_TEMPLATE.
7. ESC/back navigation flowā
The full navigation must handle ESC at every level:
outer loop:
category menu ā ESC exits script (clean up temp dir)
inner loop:
template list in category ā ESC goes back to category menu
template details dialog ā "No" goes back to template list
template details dialog ā "Yes" breaks out of both loops
8. verify_template() stays script-specificā
dev-template.sh checks for manifests/deployment.yaml. dev-template-ai.sh checks for template/ subdirectory. These are different validation rules and must stay in each script ā they do NOT move to the shared library.
9. Single-category noteā
When there's only 1 category with templates (e.g., dev-template-ai currently has only WORKFLOW), the category menu shows just one option. This is consistent with dev-setup.sh behavior ā no special handling needed. The user still picks the category, then the template.
Tasksā
Shared library (lib/template-common.sh)ā
- Source
TEMPLATE_CATEGORIESinscan_templates()from$TEMPLATE_REPO_DIR/$subdir/TEMPLATE_CATEGORIES - Move
scan_templates()to shared library ā takes subdirectory as parameter - Parse
TEMPLATE_CATEGORY_TABLEdynamically ā build category arrays, emoji/name lookup, template counts per category - Create
show_template_category_menu()ā show categories with counts, skip empty, ESC exits - Create
show_templates_in_category()ā show templates in selected category, details dialog, ESC goes back to categories - Move
select_template()to shared library ā handles both direct (by name) and interactive (two-level menu) -
select_template()sets globals:TEMPLATE_INDEX,SELECTED_TEMPLATE,TEMPLATE_PATH - Implement full ESC/back navigation: category ā templates ā details ā confirm
Both scriptsā
- Remove hardcoded category arrays, case statements, flat menu, and duplicated functions
- Both scripts reduce to: set title + subdirectory, call shared
select_template() -
verify_template()stays in each script (different validation rules)
Testingā
- Test with current dev-templates categories (BASIC_WEB_SERVER, WEB_APP, WORKFLOW)
- Test that new categories added to dev-templates automatically appear in category menu
- Test direct selection by name still works (bypasses menu entirely)
- Test ESC at category level exits cleanly
- Test ESC at template level goes back to categories
- Test "No" at details goes back to template list
- Test single-category scenario (dev-template-ai with only WORKFLOW)