Contents Plugin
A content management plugin that enables developers to create and manage websites, news sections, and blogs. This plugin provides a flexible and extensible way to handle different types of content with support for various content sources and user permissions.
Features
- Multiple content types support:
- Database content (
db) - File-based content (
file) - PHP dynamic pages (
php) - Plugin-based content (
plugin) - Built-in search functionality
- Pagination support
- Tag management system
- User role-based access control
- SEO metadata management
- Breadcrumb support
- Template customization
- Content categorization by sections
Installation
- Place the plugin in your project's
Plugins/Contentsdirectory - Configure the base path for content files (optional)
Configuration
Default Content Path
By default, the plugin looks for content files in:
[PROJECT_ROOT]/static/contents/
Custom Content Path
To override the default content path, define the following constant in your application:
define('PLUGIN_CONTENTS_BASE_PATH', '/your/custom/path/to/contents/')
Usage
Content Types
- Database Content (
db) - Store content directly in the database
-
Supports HTML content with automatic escaping
-
File Content (
file) - Serve content from static files
- Files should be placed in the configured content directory
-
Supports HTML files
-
PHP Dynamic Pages (
php) - Create dynamic content using PHP
- Supports custom templates and logic
-
Files should be placed in the configured content directory
-
Plugin Content (
plugin) - Integrate with other plugins
- Custom plugin methods can be called to generate content
Template Integration
The plugin provides several template blocks for easy integration:
fetchLatest()- Display latest content itemsgetTagsByIdents()- Retrieve active tags for specific idents in custom page logicfetchTagsBlock()- Display content tagsfetchSearchBlock()- Add search functionalityfetchContents()- Display content itemsfetchPaginationBlock()- Add pagination controls
URL Structure
Content pages are accessible via the following URL pattern:
/content/{content_identifier}/
Management Interface
The plugin includes a management interface accessible at:
/manage/contents/
For tag management:
/manage/contents/tags/
Tag rows support status = active|disabled.
activetags are available to public helpers such asgetTagsByIdents(),fetchTagsBlock(),fetchTagContentsBlock(), andgetTagByIdent().disabledtags remain editable in the admin DGS but are hidden from public tag helpers and tag-filtered frontend listings.
Admin Panel Setup Notes
- The management DGS for
contentsandcontents_tagsdepends on thecontents_managepermission section from the plugin install SQL. - The URLs above also require matching rows in
festi_section_actions,festi_sections_user_types_permission, and the admin menu tree. - If a project database was initialized from an older or partial dump and
those rows are missing, both the admin panel and
festi-dgs-execcan fail with a permission error even for an admin token.
CLI Usage
Run festi-dgs-exec from the project root inside Docker and pass an admin
access_token.
Replace [YOUR_CONTAINER] with your application container or Docker Compose
service name.
List existing tags:
docker compose exec -T [YOUR_CONTAINER] sh -lc '
cd /var/www/html/src/site &&
./vendor/bin/festi-dgs-exec \
--plugin Contents \
--dgs contents_tags \
--action list \
--path /var/www/html/src/site \
--access-token <admin-token>
'
Create a tag:
docker compose exec -T [YOUR_CONTAINER] sh -lc '
cd /var/www/html/src/site &&
./vendor/bin/festi-dgs-exec \
--plugin Contents \
--dgs contents_tags \
--action insert \
--values "{\"caption\":\"Blog\",\"ident\":\"blog\",\"url\":\"blog\",\"status\":\"active\"}" \
--path /var/www/html/src/site \
--access-token <admin-token>
'
Create a database article linked to a tag:
docker compose exec -T [YOUR_CONTAINER] sh -lc '
cd /var/www/html/src/site &&
./vendor/bin/festi-dgs-exec \
--plugin Contents \
--dgs contents \
--action insert \
--values "{\"caption\":\"CLI Test Blog Article 01\",\"url\":\"/cli-test-blog-article-01/\",\"type\":\"db\",\"description\":\"Short excerpt\",\"content\":\"<p>Article body</p>\",\"meta_title\":\"CLI Test Blog Article 01\",\"meta_description\":\"Short excerpt\",\"m2m_contents2contents_tags\":[<tag-id>]}" \
--path /var/www/html/src/site \
--access-token <admin-token>
'
Notes:
contents_tagsnow has a requiredstatusfield. Useactivefor visible frontend tags ordisabledto keep a tag hidden from public helpers.- The tag relation does not use the DGS field name
tagsin the CLI payload. It uses the request key formatm2m_<linkTable>, which for this plugin ism2m_contents2contents_tags. - For multiple tags, pass a JSON array of tag ids, for example
"m2m_contents2contents_tags":[3,4]. - CLI inserts can set only the fields exposed in
tblDefs/contents.xml.
Sitemap URL Management via CLI
List existing sitemap URLs:
docker compose exec -T [YOUR_CONTAINER] sh -lc '
cd /var/www/html/src/site &&
./vendor/bin/festi-dgs-exec \
--plugin Contents \
--dgs sitemap_urls \
--action list \
--path /var/www/html/src/site \
--access-token <admin-token>
'
Add a custom URL:
docker compose exec -T [YOUR_CONTAINER] sh -lc '
cd /var/www/html/src/site &&
./vendor/bin/festi-dgs-exec \
--plugin Contents \
--dgs sitemap_urls \
--action insert \
--values "{\"url\":\"/en/about/\",\"changefreq\":\"monthly\",\"priority\":\"0.8\",\"status\":\"active\"}" \
--path /var/www/html/src/site \
--access-token <admin-token>
'
Update an existing URL (replace <id> with the row id from the list output):
docker compose exec -T [YOUR_CONTAINER] sh -lc '
cd /var/www/html/src/site &&
./vendor/bin/festi-dgs-exec \
--plugin Contents \
--dgs sitemap_urls \
--action edit \
--id <id> \
--values "{\"changefreq\":\"weekly\",\"priority\":\"0.9\"}" \
--path /var/www/html/src/site \
--access-token <admin-token>
'
Remove a URL:
docker compose exec -T [YOUR_CONTAINER] sh -lc '
cd /var/www/html/src/site &&
./vendor/bin/festi-dgs-exec \
--plugin Contents \
--dgs sitemap_urls \
--action remove \
--id <id> \
--path /var/www/html/src/site \
--access-token <admin-token>
'
Notes:
changefreqaccepted values:always,hourly,daily,weekly,monthly,yearly,never.priorityis a decimal from0.0to1.0(step0.1). Default is0.5.lastmodis optional. Format:YYYY-MM-DD.statusmust beactiveordisabled. Onlyactiverows appear insitemap.xml.- The web UI is available at
/manage/sitemap/.
Upgrade Existing Installs
Use the new plugin update SQL that matches your database engine:
install/update.pgsql.sqlinstall/update.mysql.sqlinstall/update.mssql.sql
These scripts add contents_tags.status, backfill existing rows to active,
and keep fresh installs aligned with the updated DGS schema.
Admin Panel Workflow
- Open
/manage/contents/tags/and create the tag first. - Open
/manage/contents/and create a new page. - For a blog article, choose
Source Type = Database. - Fill
Caption,Url,Description,Content, SEO fields, andTags. - Save the page and verify it opens by its
Url.
Security
- Content is automatically escaped to prevent XSS attacks
- User role-based access control for content visibility
- Secure handling of file paths and content