To create new content elements, you need to define them within the schemas array in the ./config/cms.php file.
Table of Contents:
To create new content elements, you need to define them within the schemas array in the ./config/cms.php file.
Table of Contents:
Adding a new content element called "Quote" with a text field for the quote and a string field for the author, you would add the following to the content array of the schemas configuration:
'quote' => [
'group' => 'content',
'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M6,17H3V3H6V17M8,5H19A2,2 0 0,1 21,7V17A2,2 0 0,1 19,19H8V5Z" /></svg>',
'fields' => [
'text' => [
'type' => 'text',
'label' => 'Quote',
'min' => 1,
'default' => 'This is a default quote.',
],
'author' => [
'type' => 'string',
'default' => 'Default Author',
],
],
],
This defines a quote element in the content group with a speech bubble icon. It has two fields: text (a required text field) and author (a string field).
Each element definition consists of a key (the element's type) and an array containing the element's configuration. This configuration includes:
group: Specifies the group this element belongs to (e.g., 'basic', 'media', 'content', 'forms'). This helps organize elements in the CMS interface.icon: An SVG string used as an icon for the element in the CMS interface. Make sure, the icon contains fill="currentColor" to be dark mode compatible.fields: An associative array defining the fields that make up the content element. The key of each item in the fields array is the name of the field, and the value is an array that describes the field's properties.Note: Use field names like title, text and file if possible and appropriate. Then, the values of these fields are used in the new content element when its type is changed by the editor in the admin backend.
Each field definition requires a type, which determines the type of input the user will see in the CMS. Here's a summary of the available field types, along with configuration examples:
For selecting an audio file.
accept: Accepted mime type, e.g. audio/*label: Title displayed in the admin backend for the fieldrequired: True/false value if a file must be selected'audio_file' => [
'type' => 'audio',
'label' => 'Select Audio',
'accept' => 'audio/*',
'required' => true,
],
For text input with autocomplete suggestions.
api-type: GQL or REST depending on the requested APIdefault: Initial default value of the fieldempty-text: Text shown if no items are returned by the APIitem-title: Key to the attribute containing the item title; can be a path separated by slashes (/)item-value: Key of the attribute containing the item value; can be a path separated by slashes (/)label: Title displayed in the admin backend for the fieldlist-key: Path to the list of items with names separated by a slash (/)multiple: True/false value if selecting multiple items is allowedoptions: Initial list of option to select fromplaceholder: Text shown in the empty autocomplete fieldquery: GraphQL query to fetch suggestions (api-type: GQL)required: True/false value if an item must be selectedurl: JSON API URL to fetch suggestions from (api-type: REST)REST API example:
{
"items": [
{"name": "Aimeos", "url": "https://github.com/aimeos"},
{"name": "Laravel", "url": "https://github.com/laravel"}
],
"total": 2
}
For a REST API returning JSON content like outlined above, use this configuration:
'autocomplete_field' => [
'type' => 'autocomplete',
'api-type' => 'REST',
'label' => 'Search Items',
'url' => '/api/repos?filter=_term_',
'list-key' => 'items',
'item-title' => 'name',
'item-value' => 'url',
'placeholder' => 'Start typing to search...',
'empty-text' => 'No items found.',
'multiple' => false,
'required' => true,
'default' => ['label' => 'Aimeos', 'value' => 'https://github.com/aimeos'],
],
GraphQL API example:
{
"data": {
"pages": {
"data": [
{
"id": "1",
"title": "Home page",
"latest": {
"data": "..."
}
},
{
"id": "2",
"title": "Products | Pagible",
"latest": {
"data": "..."
}
}
}
}
}
}
For a GraphQL API returning content like outlined above, use this configuration:
'autocomplete_field' => [
'type' => 'autocomplete',
'api-type' => 'GQL',
'label' => 'Search Items',
'url' => '/graphql',
'query' => 'query {
pages(filter: {title: _term_}) {
data {
id
title
latest {
data
}
}
}
}',
'list-key' => 'pages/data',
'item-title' => 'title',
'item-value' => 'id',
'placeholder' => 'Start typing to search...',
'empty-text' => 'No items found.',
'multiple' => false,
'required' => true,
'default' => ['label' => 'Home page', 'value' => '1'],
],
A standard checkbox.
default: Initial default value of the field (true/false)label: Title displayed in the admin backend for the fieldoff: Value if uncheckedon: Value if checked'agree_terms' => [
'type' => 'checkbox',
'label' => 'I agree to the terms and conditions',
'on' => 'yes',
'off' => 'no',
'default' => 'no',
],
A color picker, value will be a hex string like #FFFFFF.
default: Initial default value of the field (hex color)label: Title displayed in the admin backend for the fieldrequired: True/false value if a color must be selected'background_color' => [
'type' => 'color',
'label' => 'Background Color',
'required' => false,
'default' => '#FF0000',
],
A dropdown list with an associated text input.
api-type: GQL or REST depending on the requested APIdefault: Initial default value of the fieldempty-text: Text shown if no items are returned by the APIitem-title: Key of the attribute containing the item title; can be a path separated by a slash (/)item-value: Key of the attribute containing the item value; can be a path separated by a slash (/)label: Title displayed in the admin backend for the fieldlist-key: Path to the list of items with names separated by a slash (/)multiple: True/false value if selecting multiple items is allowedoptions: Initial list of option to select fromplaceholder: Text shown in the empty combobox fieldquery: GraphQL query to fetch suggestions (api-type: GQL)required: True/false value if an item must be selectedurl: JSON API URL to fetch suggestions from (api-type: REST)'category' => [
'type' => 'combobox',
'label' => 'Category',
'options' => [
['label' => 'Technology', 'value' => 'tech'],
['label' => 'Design', 'value' => 'design'],
],
'placeholder' => 'Select or type a category',
'required' => true,
'default' => ['label' => 'Technology', 'value' => 'tech'],
],
For selecting a date.
allowed: List of dates in YYYY-MM-DD format to select fromdefault: Initial default value of the field in YYYY-MM-DD formatlabel: Title displayed in the admin backend for the fieldmax: Maximum allowed date in YYYY-MM-DD formatmin: Minimum allowed date in YYYY-MM-DD formatmultiple: True/false value if selecting multiple dates is allowedplaceholder: Text shown in the empty date fieldrequired: True/false value if a date must be selected'event_date' => [
'type' => 'date',
'label' => 'Event Date',
'min' => '2024-01-01',
'max' => '2024-12-31',
'required' => true,
'default' => '2024-06-15',
],
For selecting a generic file.
accept: Accepted mime type, e.g. application/pdflabel: Title displayed in the admin backend for the fieldrequired: True/false value if a file must be selected'document' => [
'type' => 'file',
'label' => 'Upload Document',
'accept' => 'application/pdf',
'required' => false,
],
A hidden field that's not visible in the UI, useful for passing data e.g. to actions.
'action' => [
'type' => 'hidden',
'value' => '\Aimeos\Cms\Actions\Blog',
],
For HTML input.
default: Initial default value of the fieldlabel: Title displayed in the admin backend for the fieldplaceholder: Text shown in the empty text field'custom_html' => [
'type' => 'html',
'label' => 'Custom HTML',
'placeholder' => '<p>Enter your HTML content here...</p>',
'default' => '<p>Default HTML content</p>',
],
For selecting an image file.
accept: Accepted mime type, e.g. image/jpeglabel: Title displayed in the admin backend for the fieldrequired: True/false value if an image must be selected'profile_image' => [
'type' => 'image',
'label' => 'Profile Image',
'accept' => 'image/jpeg, image/png',
'required' => true,
],
For selecting multiple images in a specific order.
accept: Accepted mime type, e.g. image/webplabel: Title displayed in the admin backend for the fieldmax: Maximum number of images allowedmin: Minimum number of images required'gallery_images' => [
'type' => 'images',
'label' => 'Gallery Images',
'accept' => 'image/webp, image/jpeg',
'min' => 2,
'max' => 5,
],
For creating a list of structured items.
default: Initial default value of the fielditem: Associative array (key is the data name) defining the item that can contain these settings:
type: One of the available field types (required)label: Title displayed in the admin backend for the fieldmax: Maximum number of characters/items allowedmin: Minimum number of characters/items requiredplaceholder: Text shown in the empty text fieldlabel: Title displayed in the admin backend for the fieldmax: Maximum number of items allowedmin: Minimum number of items required'team_members' => [
'type' => 'items',
'label' => 'Team Members',
'min' => 1,
'max' => 3,
'default' => ['name' => 'John Doe', 'position' => 'CEO', 'description' => 'The manager'],
'item' => [
'name' => [
'type' => 'string',
'label' => 'Full name',
'min' => 3,
'max' => 100,
'placeholder' => 'Enter full name',
'class' => 'name-field',
'default' => 'John Doe',
],
'position' => [
'type' => 'string',
'label' => 'Position',
'min' => 2,
'max' => 50,
'placeholder' => 'Enter position',
'class' => 'position-field',
'default' => 'Software Engineer',
],
'image' => [
'type' => 'image',
'label' => 'Team Member Image',
'accept' => 'image/jpeg, image/png',
'required' => false,
],
'description' => [
'type' => 'text',
'label' => 'Description',
'placeholder' => 'Enter description',
'default' => 'A dedicated team member.',
],
],
],
For rich text formatting.
default: Initial default value of the fieldlabel: Title displayed in the admin backend for the fieldmax: Maximum number of characters allowed in the input fieldmin: Minimum number of characters required in the input field'description' => [
'type' => 'markdown',
'label' => 'Description',
'default' => 'Default **markdown** content.',
],
For numeric input.
default: Value used by defaultlabel: Title displayed in the admin backend for the fieldmax: Maximum number allowedmin: Minimum number requiredplaceholder: Text shown in the empty number fieldrequired: True/false value if a valid number is requiredstep: Allowed steps when incrementing/decrementing, e.g. "10", "1", "0.1", "0.01" or any number in between'quantity' => [
'type' => 'number',
'label' => 'Quantity',
'min' => 1,
'max' => 100,
'default' => 1,
'required' => true,
],
For plain text input without formatting.
class: CSS class to apply to the input fielddefault: Initial default value of the fieldlabel: Title displayed in the admin backend for the fieldmax: Maximum number of characters allowed in the input fieldmin: Minimum number of characters required in the input fieldplaceholder: Text shown in the empty text field'username' => [
'type' => 'plaintext',
'label' => 'Username',
'min' => 3,
'max' => 50,
'placeholder' => 'Enter your username',
'class' => 'username-field',
'default' => 'defaultuser',
],
A radio button group.
default: Initial default value of the fieldlabel: Title displayed in the admin backend for the fieldoptions: List of associative arrays with "label" and "value" keysrequired: True/false value if a selected option is required'plan' => [
'type' => 'radio',
'label' => 'Choose your plan',
'options' => [
['label' => 'Basic', 'value' => 'basic'],
['label' => 'Pro', 'value' => 'pro'],
['label' => 'Enterprise', 'value' => 'enterprise'],
],
'required' => true,
'default' => 'basic',
],
A range slider where start and end value can be selected.
default: Initial default value of the fieldlabel: Title displayed in the admin backend for the fieldmax: Maximum number allowedmin: Minimum number requiredstep: Steps available when changing the range slider, e.g. "10", "1", "0.1", "0.01" or any number in between'price_range' => [
'type' => 'range',
'label' => 'Price Range',
'min' => 0,
'max' => 1000,
'step' => 10,
'default' => [100, 500],
],
A dropdown list.
default: Initial default value of the fieldlabel: Title displayed in the admin backend for the fieldmultiple: True/false value if selecting multiple items is allowedoptions: List of associative arrays with "label" and "value" keysplaceholder: Text shown in the empty select fieldrequired: True/false value if a selected option is required'category' => [
'type' => 'select',
'label' => 'Category',
'options' => [
['label' => 'Technology', 'value' => 'tech'],
['label' => 'Design', 'value' => 'design'],
['label' => 'Marketing', 'value' => 'marketing'],
],
'placeholder' => 'Select a category',
'required' => true,
'default' => 'tech',
],
A slider for a single value.
default: Initial default value of the field between min and max value (including)label: Title displayed in the admin backend for the fieldmax: Maximum number allowedmin: Minimum number requiredstep: Steps available when changing the slider, e.g. "10", "1", "0.1", "0.01" or any number in between'discount' => [
'type' => 'slider',
'label' => 'Discount',
'min' => 0,
'max' => 50,
'step' => 1,
'default' => 10,
],
A simple text field with no formatting options.
class: CSS class to apply to the input fielddefault: Initial default value of the fieldlabel: Title displayed in the admin backend for the fieldmax: Maximum number of characters allowed in the input fieldmin: Minimum number of characters required in the input fieldplaceholder: Text shown in the empty text field'title' => [
'type' => 'string',
'label' => 'Title',
'min' => 5,
'max' => 100,
'placeholder' => 'Enter title',
'class' => 'title-field',
'default' => 'Default Title Example',
],
A toggle switch.
default: Initial default value of the fieldlabel: Title displayed in the admin backend for the fieldoff: Value if uncheckedon: Value if checked'is_active' => [
'type' => 'switch',
'label' => 'Active',
'on' => 'true',
'off' => 'false',
'default' => 'true',
],
For creating a table with several rows and columns.
default: Initial default value of the field (two dimensional array)label: Title displayed in the admin backend for the fieldmin: Minimum number of columns requiredplaceholder: Text shown in the empty text fieldrequired: True/false value if table data is required'pricing_table' => [
'type' => 'table',
'label' => 'Pricing Table',
'min' => 2,
'required' => true,
'default' => [['Header 1', 'Header 2'], ['Row 1 Col 1', 'Row 1 Col 2']],
],
For text input with limited formatting options (bold, italic, links).
default: Initial default value of the fieldlabel: Title displayed in the admin backend for the field'body' => [
'type' => 'text',
'label' => 'Body',
'default' => 'This is some default body text.',
],
For URL input.
allowed: URI schemas allowed for URLs (default: "http" and "https")default: Initial default value of the fieldlabel: Title displayed in the admin backend for the fieldplaceholder: Text shown in the empty text fieldrequired: True/false value if URL is required'website' => [
'type' => 'url',
'label' => 'Website URL',
'placeholder' => 'Enter website URL',
'required' => false,
'default' => 'https://www.example.com',
],
For selecting a video file.
accept: Accepted mime type, e.g. "video/mp4"label: Title displayed in the admin backend for the fieldrequired: True/false value if a file must be selected'promo_video' => [
'type' => 'video',
'label' => 'Promotional Video',
'accept' => 'video/mp4, video/webm',
'required' => true,
],