| name | klytos-admin-notices |
| description | Guide for displaying admin notices in Klytos CMS. Use when showing success, error, warning, or info messages to admin users, implementing flash messages after form submissions, creating persistent warnings that survive page loads, adding conditional notices that auto-hide when conditions change, or handling notice dismissal via AJAX. Also trigger when working with the NoticeManager, transient notices, or the notice.before_render filter. |
Klytos Admin Notices API
When to Use This Skill
Use this reference when you need to display messages to admin users. Klytos provides two types of notices:
- Transient notices -- Flash messages shown once (e.g., "Settings saved", "Page deleted")
- Persistent notices -- Stored messages that survive across page loads until dismissed or a condition changes (e.g., "Indexing is disabled")
Key Rules
- Text-only: All notice messages are plain text. HTML is automatically stripped via
strip_tags().
- Type controls color: Pass one of
success, error, warning, info to control the visual style.
- Dismissible flag:
true shows an X button (AJAX dismiss for persistent). false means no close button.
- No inline handlers: Dismiss JS uses
addEventListener, never onclick.
- CSP nonce: The dismiss script is injected via the
admin.footer hook with the proper nonce.
1. Transient Notices (Flash Messages)
Shown once on the current page load. Survive a single POST-redirect-GET cycle via the session.
Function
klytos_add_notice( string $message, string $type = 'info', bool $dismissible = true ): void
Parameters
| Parameter | Type | Default | Description |
|---|
$message | string | -- | Plain text message (HTML stripped) |
$type | string | 'info' | 'success', 'error', 'warning', 'info' |
$dismissible | bool | true | Whether user can close with X button |
Examples
klytos_add_notice( __( 'settings.saved' ), 'success' );
klytos_add_notice( __( 'settings.save_failed' ), 'error', false );
klytos_add_notice( 'Plugin activated successfully.', 'info' );
klytos_add_notice( 'This action cannot be undone.', 'warning' );
Typical Usage in a Plugin
if ( $_SERVER['REQUEST_METHOD'] === 'POST' && klytos_verify_csrf() ) {
$result = save_my_settings( $_POST );
if ( $result ) {
klytos_add_notice( __( 'myplugin.settings_saved' ), 'success' );
} else {
klytos_add_notice( __( 'myplugin.settings_failed' ), 'error' );
}
header( 'Location: ' . $_SERVER['REQUEST_URI'] );
exit;
}
2. Persistent Notices
Stored in the notices collection. Survive across page loads and sessions. Can be dismissed per-user (via session) or removed programmatically.
Function
klytos_add_persistent_notice(
string $id,
string $message,
string $type = 'info',
bool $dismissible = true,
array $options = []
): array
Parameters
| Parameter | Type | Default | Description |
|---|
$id | string | -- | Unique identifier (slug format) |
$message | string | -- | Plain text message |
$type | string | 'info' | 'success', 'error', 'warning', 'info' |
$dismissible | bool | true | Whether user can close with X button |
$options | array | [] | Optional: context, condition_hook |
Options Array
| Key | Type | Default | Description |
|---|
context | string | '' | Only show on this admin page (e.g., 'dashboard', 'settings'). Empty = all pages. |
condition_hook | string | '' | Filter hook name. Notice only renders when the filter returns true. |
ads | bool | true | Whether the notice is advertising. true = advertising (default), false = system/non-advertising. |
The ads Field (Advertising vs System Notices)
Every persistent notice has an ads field that defaults to true. This means any notice not explicitly marked as ads => false is considered advertising.
ads => true (default): Advertising notice. Can be hidden globally via Settings > Notices.
ads => false: System/non-advertising notice. Always visible regardless of the ads toggle.
Users can disable advertising notices in Settings > Notices > Show advertising notices. When disabled, only ads => false notices are rendered. Transient/flash notices are always shown regardless of this setting.
klytos_add_persistent_notice( 'my-promo', 'Try our premium features!', 'info', true );
klytos_add_persistent_notice( 'config-warning', 'Missing API key.', 'warning', true, [
'ads' => false,
] );
The condition_hook Pattern
This is the key innovation. A persistent notice declares a filter hook name. At render time, the Notice API calls klytos_apply_filters( $condition_hook, true ). If it returns false, the notice is silently skipped -- no code needs to delete it.
klytos_add_persistent_notice( 'ssl-missing', 'Your site is not using HTTPS.', 'error', false, [
'condition_hook' => 'notice.condition.ssl_missing',
] );
klytos_add_filter( 'notice.condition.ssl_missing', function ( bool $show ): bool {
return ! isset( $_SERVER['HTTPS'] ) || $_SERVER['HTTPS'] !== 'on';
} );
Idempotent
klytos_add_persistent_notice() is idempotent by ID. Calling it multiple times with the same ID updates the existing notice instead of creating duplicates. Safe to call on every page load.
Examples
klytos_add_persistent_notice( 'welcome', 'Welcome to Klytos! Start by creating your first page.', 'info' );
klytos_add_persistent_notice( 'no-pages', 'No pages published yet.', 'warning', false, [
'context' => 'dashboard',
] );
klytos_add_persistent_notice( 'missing-email', 'Please configure your email settings.', 'warning', true, [
'context' => 'settings',
'condition_hook' => 'notice.condition.missing_email',
] );
klytos_add_filter( 'notice.condition.missing_email', function ( bool $show ): bool {
$config = klytos_app()->getSiteConfig()->get();
return empty( $config['email_from'] ?? '' );
} );
3. Dismissing Notices
Programmatically
klytos_dismiss_notice( string $id ): void
Dismisses a persistent notice for the current user session. The notice stays in storage but won't render for this user until the session expires.
Via AJAX (Automatic)
Dismissible notices render an X button. Clicking it:
- Fades out the notice element with a CSS transition.
- Sends a
POST to /admin/api/notices.php with action=dismiss and the notice id.
- The server stores the dismiss in the session.
No plugin code needed -- this is handled automatically.
4. Getting Notices
klytos_get_notices( string $currentPage = '' ): array
Returns all notices that should be rendered on the current page. Handles transient, session flash, and persistent notices. Filters by context, condition hooks, and dismiss state.
5. Manager Access (Advanced)
For advanced use cases, access the NoticeManager directly:
$manager = klytos_app()->getNoticeManager();
$manager->create( [
'id' => 'my-notice',
'message' => 'Custom notice text.',
'type' => 'warning',
'dismissible' => true,
'context' => 'dashboard',
'condition_hook' => 'notice.condition.my_custom',
'ads' => false, // System notice, always visible.
] );
$manager->delete( 'my-notice' );
$notices = $manager->list();
$manager->ensureSystemNotice( 'sys-check', [
'message' => 'System check warning.',
'type' => 'error',
'dismissible' => false,
] );
6. Hooks & Filters
Actions
| Hook | Fired When | Arguments |
|---|
notice.created | Persistent notice created | array $notice |
notice.dismissed | Notice dismissed | string $id |
notice.deleted | Persistent notice deleted | string $id |
notice.render.before | Before rendering notices | array $notices |
notice.render.after | After rendering notices | array $notices |
Filters
| Hook | Purpose | Arguments |
|---|
notice.transient.add | Modify transient notice before queuing | array $notice |
notice.before_render | Add/remove/reorder notices before render | array $notices, string $page |
notice.render_html | Customize per-notice HTML output | string $html, array $notice |
{condition_hook} | Control conditional persistent notices | bool $show |
Example: Add a notice from a plugin hook
klytos_add_filter( 'notice.before_render', function ( array $notices, string $page ): array {
if ( $page === 'settings' ) {
$notices[] = [
'id' => 'plugin-tip',
'message' => 'Tip: Configure your social media links below.',
'type' => 'info',
'dismissible' => true,
'persistent' => false,
];
}
return $notices;
} );
7. CSS Classes
Notices use the existing Klytos alert component classes:
| Class | Purpose |
|---|
.alert | Base alert styling |
.alert-success | Green (success tokens) |
.alert-error | Red (error tokens) |
.alert-warning | Amber (warning tokens) |
.alert-info | Blue (info tokens) |
.alert-dismissible | Flex layout with space for X btn |
.alert-close | The X dismiss button |
Colors come from --klytos-{type}-subtle (background), --klytos-{type}-text (text), defined in klytos-tokens.css.
8. AJAX Endpoint
URL: /admin/api/notices.php
| Method | Action | Parameters | Description |
|---|
GET | -- | ?page= | List renderable notices |
POST | dismiss | id | Dismiss a persistent notice |
POST | dismiss-all | -- | Dismiss all dismissible notices |
Requires authentication and CSRF token.
9. Settings > Notices Panel
The admin Settings page includes a Notices section where site owners can:
- Toggle advertising notices: Checkbox "Show advertising notices" (stored in
notices.show_ads site config). When unchecked, all notices with ads => true are hidden.
- View all active notices: Table showing every persistent notice with ID, type, message, and ADS/System badge.
- Dismiss All: Button to dismiss all dismissible persistent notices at once for the current session.
Site Config Key
$showAds = klytos_config( 'notices.show_ads' );
klytos_set_config( 'notices', ['show_ads' => false] );
Quick Reference
klytos_add_notice( 'Settings saved!', 'success' );
klytos_add_persistent_notice( 'my-warning', 'Check your config.', 'warning' );
klytos_add_persistent_notice( 'sys-check', 'System check required.', 'error', true, [
'ads' => false,
] );
klytos_add_persistent_notice( 'check-ssl', 'HTTPS not enabled.', 'error', false, [
'condition_hook' => 'notice.condition.no_ssl',
'ads' => false,
] );
klytos_add_filter( 'notice.condition.no_ssl', fn( bool $show ) => ! is_ssl() );
klytos_dismiss_notice( 'my-warning' );
klytos_app()->getNoticeManager()->delete( 'my-warning' );