Entry 3.0.0
SailCMS comes with models to help structure your page contents. The models for the content are the EntryType
, EntryLayout
, EntrySeo
and Entry
. There is also the EntryVersion
model for versionning and the EntryPublication
for publishing your entries.
Entry Type
The entry type is used to regroup the entries into the same type and in the same way, to define the tables in the databases. Thereby, the entries of a blog type would be located in the blogs
table of the database.
An entry type is formed with a title
, a handle
, an url_prefix
and a entry_layout_id
. The handle
is used to get the instance or to get the related Entry model.
This is the list of reserved words that are not allowed to create an Entry Type:
const RESERVED_WORDS_FOR_HANDLE = [
'entry',
'entries',
'entry_type',
'entry_types',
'entry_layout',
'entry_layouts',
'user',
'users',
'category',
'categories',
'asset',
'assets',
'config',
'configs',
'log',
'logs',
'tfa_data',
'role',
'roles',
'email',
'emails',
'csrf'
];
WARNING
Once the handle is set it can't be changed.
The url_prefix
field is a LocaleField, an object that looks like this:
{
"fr": "Bonjour le monde!",
"en": "Hello World!",
"es": "Hola Mundo!"
}
In this specific case, that object contains all versions of url prefix:
{
"fr": "produits",
"en": "product",
"es": "productos"
}
This is used to build every entry's url. It's related to the type, using the base url for that type (if any) and also use its parent url as the base (if any). Something like this:
Base is /blog
content would be /blog/the-title-of-your-article
Parent is article hello-world,
content would be /blog/hello-world/update-to-the-breaking-story
At any point, if you change the base url or the parent's url, your content's url will be updated accordingly.
You can also assign an entry layout to an entry type by passing its id.
Changing the default Entry Type
By default, SailCMS comes with an entry type named Page
. If you want to change the default entry type, you can change it in the general.php
config files. The default handle cannot be changed.
In your configuration file, look for the defaultType
section.
...
'entry' => [
'defaultType' => [
'title' => 'Page',
'urlPrefix' => [
'en' => '',
'fr' => ''
]
'entryLayoutId' => null
]
]
...
Utilities
Here is a list of utility notes to help you work with entry types.
Get Entry Model By Handle
To get the appropriate model for your Entry type, you must hint SailCMS as to what you want. For example if you simply instantiate the Entry
model, like this
$model = new Entry();
SailCMS will return the default type, Page
. But if you know what type of content you want, you can use the convenience method:
$model = EntryType::getEntryModelByHandle('your_type');
CRUD Methods
The createOne
, updateByHandle
and hardDelete
methods are all write protected with the Sail ACL system.
INFO
When you delete an entry type, an EntryException could be raised if there are existing related entries.
The getAll
, findAll
, getDefaultType
and getEntryModelByHandle
public static methods are all read protected as well as the getEntryModel
, getById
and getByHandle
public methods.
However, the getAll
, getDefaultType
and getEntryModelByHandle
methods have a special parameter to enable the read protection in case it is required. It's called api
and is a boolean.
The group of permission for the entry type is entrytype
.
Entry Layout
an Entry Layout is a structure that sets and validates the content set in the entries that are using it.
It has titles
, authors
, dates
, is_trashed
and schema
properties.
The titles
property is the title of the layout that is used to display the name of it in the admin panel.
authors
and dates
are set automatically when you create/update/delete an entry layout.
The is_trashed
property is an indicator if the layout has been deleted. This of course is a soft delete. A hard delete would remove it from the database forever.
The schema
property is a representation of the available fields and their configurations for the specific layout.
INFO
To have a better understanding of the schema field components, check the Fields page.
Utilities
Here is a list of utility notes to help you work with entry layouts.
Generate Layout Schema
The generateLayoutSchema
static method is the best way to generate the schema for an entry layout. You simply pass a list of base field instances with a key to reuse it in the entry content.
$textField = new TextField((object)[
'fr' => 'Titre',
'en' => 'Title'
], [
['required' => true,],
]);
$schema = EntryLayout::generateLayoutSchema(new Collection([
'title' => $textField
]));
This method is the basis of all create/update of layouts. Once this is executed, you can create or update a layout
$layout = new EntryLayout();
$textField = new TextField((object)[
'fr' => 'Titre',
'en' => 'Title'
], [
['required' => true,],
]);
$schema = EntryLayout::generateLayoutSchema(new Collection([
'title' => $textField
]));
$layout->create((object)[
'fr' => 'nom du layout',
'en' => 'name of layout'
], $schema);
This will create a new Layout with the given schema.
Update schema config
When you have queried your entry layout, you can use the updateSchemaConfig
to update the settings of a field. You just need to pass a fieldKey
, the setting to update, a fieldIndex
and if you want the labels of the field in the admin panel.
$entryLayout->updateSchemaConfig('title', [
'max_length' => 255,
'min_length' => 10
], 0, new LocaleField([
'fr' => 'Titre de section',
'en' => 'Section title'
]));
Update schema key
Like the updateSchemaConfig
, this public method is really useful to modify the schema. But now, it's to modify a key in the schema and it only needs the key
and a newKey
.
// title will become subtitle
$entryLayout->updateSchemaKey('title', 'subtitle');
All entries that use this layout will be updated accordingly.
CRUD methods
The create
, updateById
, updateSchemaKey
and delete
methods are all write protected with the Sail ACL system. On the other-hand, the getAll
and one
public methods are read protected.
Entry
An entry is used to store data for a piece of content in your application. We do not refer your content to pages because SailCMS can be used to create things like one-off pages like contact or pages, blog articles, product pages or any other type of content your application needs. It can handle anything that has content or media.
All entries have a locale
. site_id
and alternates
properties to localized them. In the alternate field, contains the alternate entry ids for the same content, this way, you can easily refer to the alternate content, with something like a language switcher, without having to do any more work.
It's possible to structure your entries with the parent
attribute. This field takes an EntryParent
, that needs a type_handle
and parent_id
attribute.
So, you can organize all your entries in your site regardless of the type.
An entry has a trashed
status. That means that when it's true, this is what we call soft delete
. The content is trashed to the cms and will not respond to user accessing the url. But in reality, the content still exists in case you ever change your mind.
For content fields, they have title
, template
, slug
, categories
and content
properties.
If the slug is set to null
, Sail will generate one out of the title. There is also a validation performed on the slug to make sure that there is no duplicates. If there is ever a duplicate, we will increment a value and add it to the end of the slug. For example, if my-page
already exists, Sail will set my-page-2
.
The categories
is a list of ids that is used to filter the list of entries.
The content
is linked to the Entry Layout with a key and a simple object with a handle
, type
and the content
:
- The
handle
is related to the Model Field and helps to validate the content as well as thetype
value. - The
type
is issued from an enum named "StoringType".
enum StoringType: string
{
case INTEGER = 'integer';
case FLOAT = 'float';
case STRING = 'string';
case BOOLEAN = 'boolean';
case ARRAY = 'array';
}
- Finally, the
content
could be parsed accordingly to thetype
.
The two last attributes - authors
and dates
- are automatically sets when creating/updating/deleting an entry. These attributes are useful to retrieve information about the entry's editing history. It will tell you who created it, when he created it, when it was changed or deleted, etc.
Utilities
Here is a list of utility notes to help you work with entries.
Homepage usage
The homepage is automatically stored in the configs table when you are creating, updating or deleting an entry. To retrieve the homepage you should use Entry::getHomepage()
with your site id and your locale. In the create
and updateById
methods, if the isHomepage
, locale
or siteid
fields are changed the homepage settings will be updated accordingly.
Using a middleware
It is possible to hook the entry model with a middleware to intervene before the save, update and delete methods.
class TestMiddleware implements AppMiddleware
{
public function type(): MiddlewareType
{
return MiddlewareType::ENTRY;
}
public function process(Data $data): Data
{
switch ($data->event)
{
case Entry::BeforeCreate:
if ($data->data['title']) {
$data->data['title'] .= '-middleware-create';
}
break;
case Entry::BeforeUpdate:
if ($data->data['title']) {
$data->data['title'] .= '-middleware-update';
}
break;
default:
break;
}
return $data;
}
}
So, all data send in the create and update method can be updated before the actual operation.
Post save, update and delete events
To hook itself the after the entry save, events way has been chosen. There are three constant in the entry model, to get entry events:
public const EVENT_DELETE = 'event_delete_entry';
public const EVENT_CREATE = 'event_create_entry';
public const EVENT_UPDATE = 'event_update_entry';
To register an event in a container is simple as this:
public function events(): void
{
Event::register(Entry::EVENT_CREATE, self::class, 'entryPostCreate');
...
Then, the entry is accessible like that:
public function entryPostCreate($event, $data) {
/**
* @var Entry $entry;
*/
$entry = $data['entry'];
print_r($entry->url);
}
CRUD Methods
The create
, updateById
and delete
methods are all write protected with the Sail ACL system.
As mentioned before, the homepage setting is updated each time the isHomepage
flag is provided in the update as well as if you delete an entry with the isHomepage
set to true.
The one
, getCount
, all
and countEntries
public methods are not read protected because the entries are the public content of the application.
These getter methods will only search on the Entry Type that is joined to the Entry constructor, not on all types.
The findByUrl
and findByCategoryId
static methods are also public and opposite to the getter methods, this will search in all entry types.
Entry Version
The versioning system use this model to store the entry at creation and on each update. Then, it's possible to apply any version except the current version.
There is no possibility to update an entry version for obvious reasons and when an entry is deleted, all related versions are deleted.
Utilities
Here is a list of utility notes to help you work with entry versions.
Get methods
The getById
, getVersionsByEntryId
and getLastVersionByEntryId
are all read protected with the Sail ACL system.
Apply a version
The applyVersion
method is written protected with the Sail ACL system. By only passing the entry version id, the related entry will be updated with the new version.
WARNING
If the entry version id is the same as the last version, there will be an Exception because we forbid to apply the current version.
Entry Publication
When your entry is ready for the public, you need to publish it. This is where entry publications come in. Obviously, a publication has a dates.published
date and can have an dates.expired
date.
There is only one entry publication per entry, so when we create a new publication, all others publications are deleted. And it's why there is no update possible on entry publication.
Utilities
Here is a list of utility notes to help you work with entry publications.
CRUD methods
The create
method, which is called by the entry model via the publish
method, is written protected with the Sail ACL system.
The deleteAllByEntryId
method, which is called among others process by the unpublish
method, is also written protected.