Despite CrudView being quite smart at guessing how to display your data and having great defaults, it is very often that you need to customize the look and feel of your Admin application.
Fields may be specified via the scaffold.fields
configuration key. By
default, this will contain a list of all columns associated with the Table being
in scope. To limit the fields used, simply specify an array of fields.
$action = $this->Crud->action();
$action->setConfig('scaffold.fields', ['title', 'description']);
You may also specify an options array. For forms, CrudView makes use of the
FormHelper::inputs()
method and will pass your array values as options when
generating the output.
$action = $this->Crud->action();
$action->setConfig('scaffold.fields', [
'title',
'thread_id' => [
'type' => 'text'
],
'featured' => [
'checked' => 'checked'
]
]);
If you wish to use the default automatic field population functionality but want
to specify settings for a few of the fields, you can use the
scaffold.field_settings
configuration key:
$action = $this->Crud->action();
$action->setConfig('scaffold.field_settings', [
'title' => [
// options here
]
]);
You may also use the scaffold.fields_blacklist
configuration key to remove
fields from the output if you are using the default automatic field population
functionality:
$action = $this->Crud->action();
$action->setConfig('scaffold.fields_blacklist', ['created', 'modified']);
Note
This functionality currently only applies to index
and view
pages.
The most immediate way of formatting a field is by passing a callable function
or object to the formatter
option. Callable functions or objects will
receive 5 arguments:
$name
The name of the field to be displayed
$value
The value of the field that should be outputted
$entity
The entity object from which the field was extracted
$options
An array of options passed to the CrudView helper when the field is being processed
$View
The view object in use during formatting
For example, imagine that when displaying the published_time
property, we
wanted to also display who approved the article:
$action = $this->Crud->action();
$action->setConfig('scaffold.fields', [
'title',
'published_time' => [
'formatter' => function ($name, $value, $entity) {
return $value->nice() . sprintf(' (Approved by %s)', $entity->approver->name);
}
],
]);
You may also specify formatters using the scaffold.field_settings
configuration key. This is useful if you want to display all fields but wish to
only configure the settings for one or two.
$action = $this->Crud->action();
$action->setConfig('scaffold.field_settings', [
'published_time' => [
'formatter' => function ($name, Time $value, Entity $entity) {
return $value->nice() . sprintf(' (Approved by %s)', $entity->approver->name);
}
],
]);
In some cases, it may be useful to access a helper within the callable. For instance, you might want to create a link:
$action = $this->Crud->action();
$action->setConfig('scaffold.fields', [
'title',
'external_id' => [
'formatter' => function ($name, $value, $entity, $options, $View) {
return $View->Html->link($name, sprintf('https://example.com/view/%d', $value));
}
],
]);
You can also keep your code DRY by configuring the CrudViewHelper
to use
a callable formatter based on column type. For .e.g.
// In controller action or preferably in beforeRender()
$this->viewBuilder()->setHelpers([
'CrudView' => [
'className' => 'CrudView.CrudView',
'fieldFormatters' => [
// Key can be any valid column type of table schema.
'datetime' => function ($name, $value, $entity, $options, $View) {
return $View->Time->nice($value);
},
'boolean' => function ($name, $value, $entity, $options, $View) {
return $value ? 'Yes' : 'No';
},
],
],
]);
Note
This functionality currently only applies to index
and view
pages.
Sometimes you want to execute more complex formatting logic, that may involve
the use of view helpers or outputting HTML. Since building HTML outside of the
view layer is not ideal, you can use the element
formatter for any of your
fields.
For example, consider this example where we want to link the published_time
to the same index action by passing some search arguments:
$action = $this->Crud->action();
$action->setConfig('scaffold.fields', [
'published_time' => [
'formatter' => 'element',
'element' => 'search/published_time',
'action' => 'index'
]
]);
We have instructed the formatter to use search/published_time
element. Then,
it is just a matter of creating the element file with the right content:
// templates/element/search/published_time.ctp
echo $this->Html->link($value->timeAgoInWords(), [
'action' => $options['action'],
'published_time' => $value->format('Y-m-d')
]);
After this, when displaying the published_time
field, there will the will be
a link similar to this one:
<a href="/articles?published_time=2015-06-23">4 days ago</a>
Element files will have available at least the following variables:
$value
: The value of the field
$field
: The name of the field it is intended to be rendered
$context
: The entity from which the value came from
$options
: The array of options associated to the field as passed in scaffold.fields
CrudView infers the name of the field by splitting the field so that it can be read by a human. Sometimes this is just not enough, or you may wish to show an entirely different header in a table or label in a form.
In our add()
and edit()
actions, you can specify the input label for
title for any of the fields by using the scaffold.fields
configuration
$action = $this->Crud->action();
$action->setConfig('scaffold.fields', [
'author_id' => ['label' => 'Author Name'],
// The rest of the fields to display here
]);
It’s easy to add an action to a controller that makes use of another CrudView action.
This does use the template provided by the edit action:
public function account() {
$this->Crud->mapAction('account', [
'className' => 'Crud.Edit',
'view' => 'edit',
]);
return $this->Crud->execute(null, $this->Auth->user('id'));
}
By default, it can be overwritten by providing a custom register.ctp
:
public function register() {
$this->Crud->mapAction('register', [
'className' => 'Crud.Add',
]);
return $this->Crud->execute();
}
All the CrudView templates are built from several elements that can be
overridden by creating them in your own templates/element
folder. The
following sections will list all the elements that can be overridden for each
type of action.
In general, if you want to override a template, it is a good idea to copy the
original implementation from
vendor/friendsofcake/crud-view/templates/element