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,
],
'author' => [
'type' => 'string',
],
],
],
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 APIempty-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_', // _term_ is replaced by the user input
'list-key' => 'items',
'item-title' => 'name',
'item-value' => 'url',
'placeholder' => 'Start typing to search...',
'empty-text' => 'No items found.',
'multiple' => false,
'required' => true,
],
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',
// _term_ is replaced by the user input
'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,
],
A standard checkbox.
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',
],
A color picker, value will be a hex string like #FFFFFF
.
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,
],
A dropdown list with an associated text input.
api-type
: GQL
or REST
depending on the requested APIempty-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,
],
For selecting a date.
allowed
: List of dates in YYYY-MM-DD format to select fromlabel
: 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,
],
For selecting a generic file.
accept
: Accepted mime type, e.g. application/pdf
label
: 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.
label
: 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>',
],
For selecting an image file.
accept
: Accepted mime type, e.g. image/jpeg
label
: 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/webp
label
: 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.
item
: 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,
'item' => [
'name' => [
'type' => 'string',
'label' => 'Full name',
'min' => 3,
'max' => 100,
'placeholder' => 'Enter full name',
'class' => 'name-field',
],
'position' => [
'type' => 'string',
'label' => 'Position',
'min' => 2,
'max' => 50,
'placeholder' => 'Enter position',
'class' => 'position-field',
],
'image' => [
'type' => 'image',
'label' => 'Team Member Image',
'accept' => 'image/jpeg, image/png',
'required' => false,
],
'description' => [
'type' => 'text',
'label' => 'Description',
'placeholder' => 'Enter description',
],
],
],
For rich text formatting.
'description' => [
'type' => 'markdown',
'label' => 'Description',
],
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 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',
],
A radio button group.
label
: 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,
],
A range slider where start and end value can be selected.
label
: 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,
],
A dropdown list.
label
: 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,
],
A slider for a single value.
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,
],
A simple text field with no formatting options.
class
: CSS class to apply to the input 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',
],
A toggle switch.
label
: 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',
],
For creating a table with several rows and columns.
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,
],
For text input with limited formatting options (bold, italic, links).
label
: Title displayed in the admin backend for the field'body' => [
'type' => 'text',
'label' => 'Body',
],
For URL input.
allowed
: URI schemas allowed for URLs (default: "http" and "https")label
: 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,
],
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,
],