Raven CMS Tags
This document explains Raven's Tag system for both panel users and developers/agents.
Maintenance note: keep this file updated whenever tag structure, tag routes, or Tag panel views change (private/tpl/panel/tag/*, tag controller/repository behavior, or tag public routing).
1) Panel Guide (Create And Edit Tags)
Where To Go
- Open panel sidebar:
Taxonomy->Tags.
Tag List (/tag)
What you can do:
New Tag(top and bottom action bars): opens create form.Manage Sets(top and bottom action bars): opens tag set management.Delete Selected(top and bottom action bars): deletes checked rows after confirmation.Searchfilter: filters rows byID,Title, orSlugas you type.All Setsoption in theSetfilter: clears the set-specific list filter and shows every tag.Setfilter: narrows the list to one tag set.- Row checkbox: marks a tag for bulk delete.
- Clickable table headers (
ID,Title,Slug,Pages): client-side sort. - Row
Editbutton (pencil icon): opens tag editor. - Row
Deletebutton (trash icon): deletes one tag after confirmation.
Columns shown:
IDTitleSlugSetPages(count of linked pages)Actions
Tag Sets (/tag/set)
What you can do:
New Tag Set: creates a reusable set for channel assignment.Editrow action: opens the set editor.Deleterow action: removes a non-stock set when no tags or explicit channel assignments still use it.- Stock
Default Tag Set1is always present, cannot be deleted, and is fully immutable.
Tag Editor (/tag/edit and /tag/edit/{id})
The editor provides short inline descriptions for the tag name, slug, set, description, and media controls.
Top and bottom action bars (same controls in both places):
Save TagBack to TagsDelete Tag(existing tags only)
Fields/options:
Name(required)Slug(required)Set(required, defaults toDefault Tag Set1)Description(optional)Cover Image(optional, single file)Preview Image(optional, single file)Icon Image(optional, single file)Remove current cover imagecheckbox (shown when a cover image exists)Remove current preview imagecheckbox (shown when a preview image exists)Remove current icon imagecheckbox (shown when an icon image exists)
Image behavior notes:
- Upload limits/extensions/variant sizes follow
media.*config (same as Page Editor image rules). - Tag media is stored under
public/uploads/tags/{id}/. - Only one cover image, one preview image, and one icon image can be attached at a time.
Delete behavior note:
- Deleting a tag removes its
page_tagslinks; pages remain intact.
2) Developer And Agent Internals
Key Files
- Panel views:
private/tpl/panel/tag/list.phpprivate/tpl/panel/tag/edit.php- Panel controller:
private/sys/Controller/Panel/TagListController.phpprivate/sys/Controller/Panel/TagEditController.php- Persistence:
private/sys/Repository/TagRead.php, private/sys/Repository/TagWrite.php
Panel Routes
Declared in private/sys/Router/Panel/TagRouter.php:
GET /tag-> listGET /tag/edit-> create formGET /tag/edit/{id}-> edit formPOST /tag/save-> create/updatePOST /tag/delete-> delete (single or bulk)GET /tag/set-> set listGET /tag/set/edit-> set create formGET /tag/set/edit/{id}-> set edit formPOST /tag/set/save-> set create/updatePOST /tag/set/delete-> set delete
All state-changing routes use CSRF validation.
Controller Flow
Split tag handlers:
tagList()- Owned by
TagListController. - Requires login + tag route
viewpermission. - Supports optional
?set={id}filtering and renders set-aware rows fromTagRead::listPage(...). tagEdit(?int $id)- Owned by
TagEditController. - Loads existing row when id is provided.
- Missing id row triggers flash error + redirect to
/tag. tagSave(array $post, array $files = [])- Owned by
TagEditController. - Validates CSRF.
- Sanitizes/normalizes
id,name,slug,set_id,descriptionviaInputSanitizer. - Requires non-empty
name, validslug, and valid set id. - Saves text fields via
TagWrite::save(...). - Processes optional
cover_imageandpreview_imageuploads (single-file each), optional remove flags, and writes image-path columns viaTagWrite::updateImageFiles(...). - Upload files/variants are stored under
public/uploads/tags/{id}/using configuredmedia.images.*rules. tagDelete(array $post)- Owned by
TagEditController. - Validates CSRF.
- Supports single delete (
id) and bulk delete (selected_ids[]). - Removes associated stored cover/preview image files for deleted tags.
- Reports deleted/failed counts for bulk operations.
tagSetList()(inTagListController),tagSetEdit(),tagSetSave(),tagSetDelete()(inTagEditController)- Manage file-backed tag sets under
private/dat/tag-set/. - Block deleting the stock
Default Tag Set, sets with assigned tags, or sets still explicitly assigned to channels.
Data Model And Repository Behavior
TagRead + TagWrite behavior:
listAll()returns tags with page counts viapage_tagsjoin.- Tag rows persist numeric
set_idmembership in the database for fast channel/page filtering. TagWrite::save(...)handles create/update in one method.TagWrite::updateImageFiles(...)persists cover/preview source + variant paths.TagWrite::deleteById(...)runs in a transaction:- deletes
page_tagsrows for that tag - deletes tag row
Storage detail:
- SQLite mode uses attached database aliases (
tags.tags,main.page_tags). - Non-SQLite mode uses configured table prefix.
- Tag set definitions live in
private/dat/tag-set/{id}_{slug}.phpand always include the stockDefault Tag Setas1_default.php.
Public Routing Touchpoints
- Tag listing routes resolve under
/{tag.prefix}/{tag_slug}/{page?}. - Public tag controller:
private/sys/Controller/Public/TagController.php. - If
tag.prefixis blank, tag routes are disabled. - Template priority:
tpl/tag/{tag_slug}.phpthentpl/tag/index.php.
Security/Validation Expectations
- Permission gate: tag route permissions (
view,create,edit,delete). - CSRF on POST actions.
- Sanitization via centralized
InputSanitizer. - Repository operations use prepared statements.
Update Discipline
When tag behavior changes, update this document in the same task. That includes list/editor UI controls, routes, save/delete behavior, relation cleanup, and public tag-route behavior.
UI Labels Reference
BasicNextPrevious