A Simple Guide to Every Feature in Zed CMS
Last Updated: 2024-12-26 | Version 3.2.0
Zed CMS is a modern, lightweight content management system built with PHP and React. It uses an event-driven architecture where features are added through "addons" instead of hardcoding everything into the core.
Think of it like LEGO blocks — the core is minimal, and you add what you need.
- Upload files to your server
- Visit
/install.phpin your browser - Enter your database details
- Login at
/admin/login
Email: admin@zed.local
Password: (set during install)
Your command center showing:
- Stats Cards — Pages, Posts, Users, Addons count
- Recent Activity — Last 5 edited items
- Quick Draft — Create posts instantly
- Health Checks — System status (uploads, PHP, SEO)
- 🌙 Dark Mode Toggle — Switch via header icon
| Feature | How It Works |
|---|---|
| Create | Click "New Content" or use Quick Draft |
| Edit | Click row or Edit button |
| Delete | Click delete icon (asks confirmation) |
| Batch Select | Checkbox on each row, "Select All" in header |
| Batch Delete | Delete multiple items at once |
| Filter | Use status tabs (All / Published / Draft) |
| Search | Type in search box |
| Pagination | 10 items per page |
A modern rich text editor powered by TipTap (ProseMirror-based):
- Paragraph, Heading, List — Basic text blocks
- Image — Upload or pick from media library with resize/align controls
- Quote, Code — Styled content blocks
- Slash Commands — Type
/to insert blocks - Bubble Toolbar — Select text for formatting options
- 🌙 Theme Sync — Editor matches admin dark/light mode
- HTML Storage — Content saved as clean HTML
- Upload — Drag-drop or click to upload
- Auto-Optimize — Converts to WebP, creates thumbnails
- Search — Instant filtering
- Copy URL — One-click clipboard copy
- Batch Select — NEW v2.5.0 Checkbox on each media card
- Batch Delete — NEW v2.5.0 Delete multiple files at once
Simple category management:
- Create: Enter name → auto-generates slug
- Delete: Click trash icon
- Protected: "Uncategorized" can't be deleted
Visual menu editor:
- Create Menu — Enter name
- Add Items — Click pages/posts to add
- Drag to Reorder — Move items up/down
- Nesting — Create dropdowns
- Auto-Save — Saves 2 seconds after changes
Full user CRUD with roles:
| Role | Access Level |
|---|---|
| Administrator | Everything |
| Editor | All content, no settings |
| Author | Own content only |
| Subscriber | No admin access |
Organized in tabs:
- General — Site title, tagline, homepage
- SEO — Meta description, search visibility
- System — Maintenance mode, debug mode
- Toggle addons on/off with switches
- Upload new addons (
.phpfiles) - System addons can't be disabled
- NEW v3.0.1: Addon menus auto-hide when disabled
- Preview installed themes
- Activate with one click
- Themes can have custom settings
| URL | What Shows |
|---|---|
/ |
Homepage (posts or static page) |
/blog |
Blog listing (if static homepage) |
/about |
Page with slug "about" |
/hello-world |
Post with slug "hello-world" |
Themes are in content/themes/. Each theme needs:
my-theme/
├── index.php ← Blog listing template
├── single.php ← Individual post/page
├── functions.php ← Theme setup (optional)
└── parts/
├── header.php
└── footer.php
<?= zed_menu('Main Menu') ?>
<?= zed_primary_menu() ?>Create a file in content/addons/:
<?php
// my_addon.php
use Core\Event;
// Run on every request
Event::on('route_request', function($request) {
if ($request['uri'] === '/hello') {
echo "Hello World!";
\Core\Router::setHandled();
}
});The easiest way to add admin pages:
// Register a menu with automatic routing
zed_register_admin_menu([
'id' => 'my_addon',
'title' => 'My Addon',
'icon' => 'settings',
'capability' => 'manage_options',
'position' => 55,
'badge' => '3',
'callback' => function() {
echo '<h1>My Addon Dashboard</h1>';
}
]);
// Register a submenu
zed_register_admin_submenu('my_addon', [
'id' => 'my_addon_settings',
'title' => 'Settings',
'callback' => fn() => echo '<h1>Settings</h1>'
]);Features:
- ✅ Automatic route registration (
/admin/my_addon) - ✅ Automatic permission checks
- ✅ Automatic admin layout wrapping
- ✅ Auto-hides when addon disabled
For custom routes and API endpoints:
// Basic route
zed_register_route([
'path' => '/admin/my-page',
'callback' => fn() => '<h1>My Page</h1>'
]);
// Pattern matching
zed_register_route([
'path' => '/admin/reports/{type}',
'callback' => function($request, $uri, $params) {
return "<h1>Report: {$params['type']}</h1>";
}
]);
// API endpoint (no layout)
zed_register_route([
'path' => '/admin/api/my-action',
'method' => 'POST',
'wrap_layout' => false,
'callback' => fn() => json_encode(['success' => true])
]);| Hook | When It Fires |
|---|---|
app_init |
After addons load |
app_ready |
System fully ready |
route_request |
Every HTTP request |
zed_head |
In theme <head> |
zed_admin_menu |
Building sidebar |
zed_register_shortcode('youtube', function($attrs, $content) {
return '<iframe src="https://youtube.com/embed/' . $attrs['id'] . '"></iframe>';
});
// Use: [youtube id="dQw4w9WgXcQ"]zed_register_ajax('my_action', function($data) {
return ['success' => true, 'message' => 'Done!'];
}, require_auth: true, method: 'POST');
// Endpoint: POST /api/ajax/my_actionzed_register_addon_settings('my_seo', [
'title' => 'SEO Settings',
'fields' => [
['id' => 'tracking_id', 'type' => 'text', 'label' => 'GA ID'],
['id' => 'enabled', 'type' => 'toggle', 'label' => 'Enable Tracking'],
]
]);
// Creates settings page at /admin/addon-settings/my_seozed_add_notice('Settings saved!', 'success');
zed_add_notice('Something went wrong', 'error');// In form:
<?= zed_nonce_field('my_action') ?>
// On submit:
zed_check_nonce('my_action'); // Dies if invalid// Cache API data for 1 hour
$data = zed_remember('api_data', function() {
return fetch_from_api();
}, 3600);ZedCMS/
├── index.php ← Entry point
├── config.php ← Database config
├── install.php ← Installer
├── cron.php ← Scheduled tasks
│
├── core/ ← Engine (don't modify)
│ ├── App.php ← Bootstrap
│ ├── Router.php ← Event-driven routing
│ ├── Event.php ← Hook system
│ ├── Database.php ← PDO wrapper
│ └── Auth.php ← Session & login
│
└── content/ ← Your stuff
├── addons/ ← Plugins
│ ├── admin/ ← Admin modules
│ └── frontend/ ← Theme helpers
├── themes/ ← Site themes
└── uploads/ ← Media files
Admin themes are located in content/themes/. To create a custom admin theme:
- Create a folder (e.g.,
content/themes/my-admin-theme) - Create
admin-layout.php(master layout) - Create view templates in
views/folder (optional overrides) - Set
admin_themeoption tomy-admin-themein database
Routes are theme-agnostic. Use AdminRenderer to render pages:
use AdminRenderer;
// Render a full page with layout
$content = AdminRenderer::renderPage('my-view', [
'foo' => 'bar'
], [
'page_title' => 'My Page'
]);
// Render just the view (no layout)
$html = AdminRenderer::render('my-view', ['foo' => 'bar']);When you request view my-view, the renderer looks in:
content/themes/{active_theme}/views/my-view.phpcontent/themes/{active_theme}/partials/my-view.php(legacy)content/themes/{active_theme}/my-view.php- Falls back to
admin-defaulttheme if not found
- Go to Settings
- Set "Homepage Mode" to "Static Page"
- Select a page from dropdown
- Save
Use the Metabox API:
zed_register_metabox('book_details', [
'title' => 'Book Details',
'post_types' => ['book'],
'fields' => [
['id' => 'isbn', 'type' => 'text', 'label' => 'ISBN'],
['id' => 'author', 'type' => 'text', 'label' => 'Author'],
]
]);// In theme's functions.php
zed_register_post_type('product', [
'label' => 'Products',
'singular' => 'Product',
'icon' => 'shopping_cart',
]);zed_mail([
'to' => 'user@example.com',
'subject' => 'Welcome!',
'body' => '<h1>Hello!</h1><p>Welcome aboard.</p>',
]);// In cron.php or addon:
zed_schedule_event('cleanup', 'daily', function() {
// Runs once per day
delete_old_records();
});Full comment moderation system:
| Feature | Description |
|---|---|
| Status Tabs | All, Pending, Approved, Spam, Trash |
| Moderation | Approve, mark spam, trash, delete permanently |
| Search | Find comments by content or author |
| Bulk Actions | Moderate multiple comments at once |
Theme Usage:
<?php if (zed_comments_open($post)): ?>
<h3><?= zed_comment_count($post['id']) ?> Comments</h3>
<?php zed_comments_list($post['id']); ?>
<?php zed_comment_form($post['id']); ?>
<?php endif; ?>Drag-and-drop widget management:
Built-in Widgets:
| Widget | Description |
|---|---|
| Recent Posts | Latest posts with dates |
| Categories | Category list with counts |
| Tags | Tag cloud |
| Search | Search form |
| Custom HTML | Raw HTML content |
| Social Links | Social media icons |
Register Sidebar in Theme:
// In functions.php
zed_register_sidebar('main-sidebar', [
'name' => 'Main Sidebar',
'description' => 'Appears on blog pages',
]);
// In template
<?php zed_dynamic_sidebar('main-sidebar'); ?>Frontend JavaScript library for dynamic content:
<script src="/addons/_system/assets/js/zed-frontend.js"></script>
<script>
// Infinite scroll
Zed.infiniteScroll({
container: '.posts-grid',
url: '/api?action=get_posts',
render: (post) => `<article><h2>${post.title}</h2></article>`,
});
// Live search
Zed.liveSearch({
input: '#search',
results: '#results',
url: '/api?action=search',
});
</script>Quick functions for common theme features:
| Function | Purpose |
|---|---|
zed_reading_progress() |
Animated reading progress bar |
zed_social_share($post) |
Social sharing buttons |
zed_author_box($post) |
Author bio with avatar |
zed_reading_time($post) |
"5 min read" estimate |
zed_breadcrumbs($items) |
Breadcrumb navigation |
zed_post_navigation($post) |
Previous/Next links |
zed_get_post_format($post) |
Post format (video, gallery, etc.) |
Example:
<!-- In single.php -->
<?php zed_reading_progress(['color' => '#6366f1']); ?>
<article>
<?php zed_breadcrumbs([['label' => 'Blog', 'url' => '/blog'], ['label' => $post['title']]]); ?>
<h1><?= $post['title'] ?></h1>
<span><?= zed_reading_time($post)['text'] ?></span>
<div class="content"><?= $post['content'] ?></div>
<?php zed_social_share($post, ['style' => 'buttons']); ?>
<?php zed_author_box($post); ?>
<?php zed_post_navigation($post); ?>
</article>| Table | Purpose |
|---|---|
zed_content |
Pages, posts, all content |
zed_users |
User accounts |
zed_categories |
Categories |
zed_menus |
Navigation menus |
zed_options |
Site settings |
zed_content_revisions |
Version history |
zed_comments |
Comments (v3.2.0) |
- Check the Knowledge Base in admin
- Review
ARCHITECTURE.mdfor technical details - Look at existing addons for examples
Zed CMS — Built for developers who want simplicity with power.