Content model
VerdinCore models editorial entities explicitly. Authentication and framework tables are documented separately in the database reference.
Relationship map
erDiagram
USER o|--o{ POST : authors
USER o|--o{ PAGE : authors
USER o|--o{ MEDIA : uploads
PAGE o|--o{ PAGE : contains
POST }o--o{ TOPIC : classified_as
TOPIC_GROUP ||--o{ TOPIC : contains
POST }o--o| MEDIA : featured_image
PAGE }o--o| MEDIA : featured_image
BLOCK_GROUP ||--o{ BLOCK : contains
BLOCK ||--o{ BLOCK_ELEMENT : contains
BLOCK_ELEMENT }o--o| MEDIA : image_valueShared content fields
Posts and pages share the main publishing fields:
Field group | Purpose |
|---|---|
Identity | Numeric ID, title, unique slug |
Authorship | Optional user reference |
Body | Sanitized HTML content and optional excerpt |
Lifecycle | Status, publication time, created time, updated time, deleted time |
Audience |
|
Presentation | Featured image, featured flag, review flag |
Reading data | Word count and estimated reading time |
Activity | View count and last-viewed time |
Valid content states are draft, scheduled, published, and archived. Trash is represented by a soft-delete timestamp rather than a fifth status.
Posts
Posts are date-oriented content. In addition to the shared fields, a post can be:
unlisted, which removes it from indexes and discovery surfaces;
marked as video content;
assigned to any number of topics;
republished, which moves its publication time to the current time.
The application can calculate related posts from shared topics and can automatically select featured public posts from an eligible cohort.
Pages
Pages form a hierarchy through parent_id. The full parent chain produces the public URL and breadcrumbs.
The model rejects direct self-parenting and longer parent cycles. Public resolution also verifies that every requested URL segment exactly matches the stored hierarchy and that the whole path is visible to the current audience.
Page-specific fields include:
sort_orderfor sibling and navigation ordering;is_aboutfor about/profile structured data;is_contactfor contact-page structured data.
Topics and topic groups
A topic belongs to one topic group. Posts and topics have a many-to-many relationship through post_topics.
This supports two archive levels:
/topic/<slug>for one topic;/topic-group/<slug>for every post assigned to a topic in that group.
Navigation and sitemap queries include only groups and topics that lead to eligible published content.
Blocks and block groups
A block group collects blocks. Each block has a globally unique handle, and each element has a handle unique within its block.
Supported element types are:
Type | Stored value |
|---|---|
| Plain text |
| Sanitized compact HTML |
| Validated URL or path |
| Media reference plus related value data |
Templates can request one element using a block.element path or load a complete group as structured objects. Handles are the stable contract between content and presentation.
Media
The media table stores metadata, not image bytes. A record includes the generated filename, original filename, collection, uploader, alt text, caption, and timestamps.
Collections define editorial purpose and processing rules:
featured_post;featured_page;content;blocks.
Featured and content collections generate variants. Block images remain in their accepted original format. See the media guide for sizes and file behavior.
Publishing lifecycle
stateDiagram-v2
[*] --> Draft
Draft --> Published: publish now
Draft --> Scheduled: choose UTC time
Scheduled --> Published: cron reaches due time
Scheduled --> Draft: cancel schedule
Published --> Archived: archive
Archived --> Published: publish again
Draft --> Trash: soft delete
Scheduled --> Trash: soft delete
Published --> Trash: soft delete
Archived --> Trash: soft delete
Trash --> Draft: restore prior draft
Trash --> Scheduled: restore prior schedule
Trash --> Published: restore prior publication
Trash --> Archived: restore prior archive
Trash --> [*]: delete permanentlyRestoring a deleted post or page clears only its soft-delete timestamp. Its previous status and other content fields remain unchanged. A scheduled item must have a valid UTC publication time before the scheduler can publish it.
Operational entities
Additional tables store:
Shield users, identities, groups, permissions, tokens, and login records;
daily visitor records and summarized statistics;
cron run status and per-task results;
synchronized public GitHub repository metadata;
framework settings and migration state.