mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Move CMS Howtos
This commit is contained in:
parent
fe62a2fa79
commit
e729131a63
@ -0,0 +1,333 @@
|
|||||||
|
title: ModelAdmin
|
||||||
|
summary: Create admin UI's for managing your data records.
|
||||||
|
|
||||||
|
# ModelAdmin
|
||||||
|
|
||||||
|
[api:ModelAdmin] provides a simple way to utilize the SilverStripe Admin UI with your own data models. It can create
|
||||||
|
searchables list and edit views of [api:DataObject] subclasses, and even provides import and export of your data.
|
||||||
|
|
||||||
|
It uses the framework's knowledge about the model to provide sensible defaults, allowing you to get started in a couple
|
||||||
|
of lines of code, while still providing a solid base for customization.
|
||||||
|
|
||||||
|
<div class="info" markdown="1">
|
||||||
|
The interface is mainly powered by the [api:GridField] class ([documentation](../forms/fields/gridfield)), which can
|
||||||
|
also be used in other areas of your application.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Let's assume we want to manage a simple product listing as a sample data model: A product can have a name, price, and
|
||||||
|
a category.
|
||||||
|
|
||||||
|
**mysite/code/Product.php**
|
||||||
|
|
||||||
|
:::php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Product extends DataObject {
|
||||||
|
|
||||||
|
private static $db = array(
|
||||||
|
'Name' => 'Varchar',
|
||||||
|
'ProductCode' => 'Varchar',
|
||||||
|
'Price' => 'Currency'
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $has_one = array(
|
||||||
|
'Category' => 'Category'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
**mysite/code/Category.php**
|
||||||
|
|
||||||
|
:::php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Category extends DataObject {
|
||||||
|
|
||||||
|
private static $db = array(
|
||||||
|
'Title' => 'Text'
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $has_many = array(
|
||||||
|
'Products' => 'Product'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
To create your own `ModelAdmin`, simply extend the base class, and edit the `$managed_models` property with the list of
|
||||||
|
DataObject's you want to scaffold an interface for. The class can manage multiple models in parallel, if required.
|
||||||
|
|
||||||
|
We'll name it `MyAdmin`, but the class name can be anything you want.
|
||||||
|
|
||||||
|
**mysite/code/MyAdmin.php**
|
||||||
|
|
||||||
|
:::php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class MyAdmin extends ModelAdmin {
|
||||||
|
|
||||||
|
private static $managed_models = array(
|
||||||
|
'Product',
|
||||||
|
'Category'
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $url_segment = 'products';
|
||||||
|
|
||||||
|
private static $menu_title = 'My Product Admin';
|
||||||
|
}
|
||||||
|
|
||||||
|
This will automatically add a new menu entry to the SilverStripe Admin UI entitled `My Product Admin` and logged in
|
||||||
|
users will be able to upload and manage `Product` and `Category` instances through http://yoursite.com/admin/products.
|
||||||
|
|
||||||
|
<div class="alert" markdown="1">
|
||||||
|
After defining these classes, make sure you have rebuilt your SilverStripe database and flushed your cache.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
## Permissions
|
||||||
|
|
||||||
|
Each new `ModelAdmin` subclass creates its' own [permission code](../security), for the example above this would be
|
||||||
|
`CMS_ACCESS_MyAdmin`. Users with access to the Admin UI will need to have this permission assigned through
|
||||||
|
`admin/security/` or have the `ADMIN` permission code in order to gain access to the controller.
|
||||||
|
|
||||||
|
<div class="notice" markdown="1">
|
||||||
|
For more information on the security and permission system see the [Security Documentation](../security)
|
||||||
|
</div>
|
||||||
|
|
||||||
|
The [api:DataObject] API has more granular permission control, which is enforced in [api:ModelAdmin] by default.
|
||||||
|
Available checks are `canEdit()`, `canCreate()`, `canView()` and `canDelete()`. Models check for administrator
|
||||||
|
permissions by default. For most cases, less restrictive checks make sense, e.g. checking for general CMS access rights.
|
||||||
|
|
||||||
|
**mysite/code/Category.php**
|
||||||
|
|
||||||
|
:::php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Category extends DataObject {
|
||||||
|
// ...
|
||||||
|
public function canView($member = null) {
|
||||||
|
return Permission::check('CMS_ACCESS_MyAdmin', 'any', $member);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canEdit($member = null) {
|
||||||
|
return Permission::check('CMS_ACCESS_MyAdmin', 'any', $member);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canDelete($member = null) {
|
||||||
|
return Permission::check('CMS_ACCESS_MyAdmin', 'any', $member);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canCreate($member = null) {
|
||||||
|
return Permission::check('CMS_ACCESS_MyAdmin', 'any', $member);
|
||||||
|
}
|
||||||
|
|
||||||
|
## Searching Records
|
||||||
|
|
||||||
|
[api:ModelAdmin] uses the [SearchContext](../search/searchcontext) class to provide a search form, as well as get the
|
||||||
|
searched results. Every [api:DataObject] can have its own context, based on the fields which should be searchable. The
|
||||||
|
class makes a guess at how those fields should be searched, e.g. showing a checkbox for any boolean fields in your
|
||||||
|
`$db` definition.
|
||||||
|
|
||||||
|
To remove, add or modify searchable fields, define a new `[api:DataObject::$searchable_fields]` static on your model
|
||||||
|
class (see [SearchContext](../search/searchcontext) docs for details).
|
||||||
|
|
||||||
|
**mysite/code/Product.php**
|
||||||
|
|
||||||
|
:::php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Product extends DataObject {
|
||||||
|
|
||||||
|
private static $searchable_fields = array(
|
||||||
|
'Name',
|
||||||
|
'ProductCode'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="hint" markdown="1">
|
||||||
|
[SearchContext](../search/searchcontext) documentation has more information on providing the search functionality.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
## Displaying Results
|
||||||
|
|
||||||
|
The results are shown in a tabular listing, powered by the [GridField](../forms/fields/gridfield), more specifically
|
||||||
|
the [api:GridFieldDataColumns] component. This component looks for a [api:DataObject::$summary_fields] static on your
|
||||||
|
model class, where you can add or remove columns. To change the title, use [api:DataObject::$field_labels].
|
||||||
|
|
||||||
|
**mysite/code/Page.php**
|
||||||
|
|
||||||
|
:::php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Product extends DataObject {
|
||||||
|
|
||||||
|
private static $field_labels = array(
|
||||||
|
'Price' => 'Cost' // renames the column to "Cost"
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $summary_fields = array(
|
||||||
|
'Name',
|
||||||
|
'Price'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
The results list are retrieved from [api:SearchContext->getResults], based on the parameters passed through the search
|
||||||
|
form. If no search parameters are given, the results will show every record. Results are a [api:DataList] instance, so
|
||||||
|
can be customized by additional SQL filters, joins.
|
||||||
|
|
||||||
|
For example, we might want to exclude all products without prices in our sample `MyAdmin` implementation.
|
||||||
|
|
||||||
|
**mysite/code/MyAdmin.php**
|
||||||
|
|
||||||
|
:::php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class MyAdmin extends ModelAdmin {
|
||||||
|
|
||||||
|
public function getList() {
|
||||||
|
$list = parent::getList();
|
||||||
|
|
||||||
|
// Always limit by model class, in case you're managing multiple
|
||||||
|
if($this->modelClass == 'Product') {
|
||||||
|
$list = $list->exclude('Price', '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
You can also customize the search behavior directly on your `ModelAdmin` instance. For example, we might want to have a
|
||||||
|
checkbox which limits search results to expensive products (over $100).
|
||||||
|
|
||||||
|
**mysite/code/MyAdmin.php**
|
||||||
|
|
||||||
|
:::php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class MyAdmin extends ModelAdmin {
|
||||||
|
|
||||||
|
public function getSearchContext() {
|
||||||
|
$context = parent::getSearchContext();
|
||||||
|
|
||||||
|
if($this->modelClass == 'Product') {
|
||||||
|
$context->getFields()->push(new CheckboxField('q[ExpensiveOnly]', 'Only expensive stuff'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getList() {
|
||||||
|
$list = parent::getList();
|
||||||
|
|
||||||
|
$params = $this->request->requestVar('q'); // use this to access search parameters
|
||||||
|
|
||||||
|
if($this->modelClass == 'Product' && isset($params['ExpensiveOnly']) && $params['ExpensiveOnly']) {
|
||||||
|
$list = $list->exclude('Price:LessThan', '100');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
To alter how the results are displayed (via `[api:GridField]`), you can also overload the `getEditForm()` method. For
|
||||||
|
example, to add a new component.
|
||||||
|
|
||||||
|
**mysite/code/MyAdmin.php**
|
||||||
|
|
||||||
|
:::php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class MyAdmin extends ModelAdmin {
|
||||||
|
|
||||||
|
private static $managed_models = array(
|
||||||
|
'Product',
|
||||||
|
'Category'
|
||||||
|
);
|
||||||
|
|
||||||
|
// ...
|
||||||
|
public function getEditForm($id = null, $fields = null) {
|
||||||
|
$form = parent::getEditForm($id, $fields);
|
||||||
|
|
||||||
|
// $gridFieldName is generated from the ModelClass, eg if the Class 'Product'
|
||||||
|
// is managed by this ModelAdmin, the GridField for it will also be named 'Product'
|
||||||
|
|
||||||
|
$gridFieldName = $this->sanitiseClassName($this->modelClass);
|
||||||
|
$gridField = $form->Fields()->fieldByName($gridFieldName);
|
||||||
|
|
||||||
|
// modify the list view.
|
||||||
|
$gridField->getConfig()->addComponent(new GridFieldFilterHeader());
|
||||||
|
|
||||||
|
return $form;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
The above example will add the component to all `GridField`s (of all managed models). Alternatively we can also add it
|
||||||
|
to only one specific `GridField`:
|
||||||
|
|
||||||
|
**mysite/code/MyAdmin.php**
|
||||||
|
|
||||||
|
:::php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class MyAdmin extends ModelAdmin {
|
||||||
|
|
||||||
|
private static $managed_models = array(
|
||||||
|
'Product',
|
||||||
|
'Category'
|
||||||
|
);
|
||||||
|
|
||||||
|
public function getEditForm($id = null, $fields = null) {
|
||||||
|
$form = parent::getEditForm($id, $fields);
|
||||||
|
|
||||||
|
$gridFieldName = 'Product';
|
||||||
|
$gridField = $form->Fields()->fieldByName($gridFieldName);
|
||||||
|
|
||||||
|
if ($gridField) {
|
||||||
|
$gridField->getConfig()->addComponent(new GridFieldFilterHeader());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $form;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## Data Import
|
||||||
|
|
||||||
|
The `ModelAdmin` class provides import of CSV files through the [api:CsvBulkLoader] API. which has support for column
|
||||||
|
mapping, updating existing records, and identifying relationships - so its a powerful tool to get your data into a
|
||||||
|
SilverStripe database.
|
||||||
|
|
||||||
|
By default, each model management interface allows uploading a CSV file with all columns auto detected. To override
|
||||||
|
with a more specific importer implementation, use the [api:ModelAdmin::$model_importers] static.
|
||||||
|
|
||||||
|
## Data Export
|
||||||
|
|
||||||
|
Export is available as a CSV format through a button at the end of a results list. You can also export search results.
|
||||||
|
This is handled through the [api:GridFieldExportButton] component.
|
||||||
|
|
||||||
|
To customize the exported columns, create a new method called `getExportFields` in your `ModelAdmin`:
|
||||||
|
|
||||||
|
:::php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class MyAdmin extends ModelAdmin {
|
||||||
|
// ...
|
||||||
|
|
||||||
|
public function getExportFields() {
|
||||||
|
return array(
|
||||||
|
'Name' => 'Name',
|
||||||
|
'ProductCode' => 'Product Code',
|
||||||
|
'Category.Title' => 'Category'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
* [GridField](../forms/fields/gridfield)
|
||||||
|
* [Permissions](../security/permissions)
|
||||||
|
* [SeachContext](../search/seachcontext)
|
||||||
|
|
||||||
|
## API Documentation
|
||||||
|
|
||||||
|
* [api:ModelAdmin]
|
||||||
|
* [api:LeftAndMain]
|
||||||
|
* [api:GridField]
|
||||||
|
* [api:DataList]
|
||||||
|
* [api:CsvBulkLoader]
|
@ -1,6 +1,6 @@
|
|||||||
# CMS layout
|
title: Admin Layout
|
||||||
|
|
||||||
## Overview
|
# CMS layout
|
||||||
|
|
||||||
The CMS markup is structured into "panels", which are the base units containing interface components (or other panels),
|
The CMS markup is structured into "panels", which are the base units containing interface components (or other panels),
|
||||||
as declared by the class `cms-panel`. Panels can be made collapsible, and get the ability to be resized and aligned with
|
as declared by the class `cms-panel`. Panels can be made collapsible, and get the ability to be resized and aligned with
|
@ -0,0 +1,28 @@
|
|||||||
|
title: WYSIWYG Styles
|
||||||
|
summary: Add custom CSS properties to the rich-text editor.
|
||||||
|
|
||||||
|
# WYSIWYG Styles
|
||||||
|
|
||||||
|
SilverStripe lets you customize the style of content in the CMS. This is done by setting up a CSS file called
|
||||||
|
`editor.css` in either your theme or in your `mysite` folder. This is set through
|
||||||
|
|
||||||
|
:::php
|
||||||
|
HtmlEditorConfig::get('cms')->setOption('ContentCSS', project() . '/css/editor.css');
|
||||||
|
|
||||||
|
Will load the `mysite/css/editor.css` file.
|
||||||
|
|
||||||
|
Any CSS classes within this file will be automatically added to the `WYSIWYG` editors 'style' dropdown. For instance, to
|
||||||
|
add the color 'red' as an option within the `WYSIWYG` add the following to the `editor.css`
|
||||||
|
|
||||||
|
:::css
|
||||||
|
.red {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="notice" markdown="1">
|
||||||
|
After you have defined the `editor.css` make sure you clear your SilverStripe cache for it to take effect.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
## API Documentation
|
||||||
|
|
||||||
|
* [api:HtmlEditorConfig]
|
@ -0,0 +1,22 @@
|
|||||||
|
## Extending existing ModelAdmin
|
||||||
|
|
||||||
|
Sometimes you'll work with ModelAdmins from other modules. To customize these interfaces, you can always subclass. But there's
|
||||||
|
also another tool at your disposal: The `[api:Extension]` API.
|
||||||
|
|
||||||
|
:::php
|
||||||
|
class MyAdminExtension extends Extension {
|
||||||
|
// ...
|
||||||
|
public function updateEditForm(&$form) {
|
||||||
|
$form->Fields()->push(/* ... */)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Now enable this extension through your `[config.yml](/topics/configuration)` file.
|
||||||
|
|
||||||
|
:::yml
|
||||||
|
MyAdmin:
|
||||||
|
extensions:
|
||||||
|
- MyAdminExtension
|
||||||
|
|
||||||
|
The following extension points are available: `updateEditForm()`, `updateSearchContext()`,
|
||||||
|
`updateSearchForm()`, `updateList()`, `updateImportForm`.
|
@ -0,0 +1,13 @@
|
|||||||
|
title: Customising the Admin Interface
|
||||||
|
summary: Extend the admin view to provide custom behavior or new features for CMS and admin users.
|
||||||
|
introduction: The Admin interface can be extended to provide additional functionality to users and custom interfaces for managing data.
|
||||||
|
|
||||||
|
The Admin interface is bundled within the SilverStripe Framework but is most commonly used in conjunction with the `CMS`
|
||||||
|
module. The main class for displaying the interface is a specialized [api:Controller] called [api:LeftAndMain], named
|
||||||
|
as it is designed around a left hand navigation and a main edit form.
|
||||||
|
|
||||||
|
[CHILDREN]
|
||||||
|
|
||||||
|
## How to's
|
||||||
|
|
||||||
|
[CHILDREN Folder="How_Tos"]
|
@ -1,106 +0,0 @@
|
|||||||
# Typography
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
SilverStripe lets you customise the style of content in the CMS.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
This is done by setting up a CSS file called (projectname)/css/typography.css.
|
|
||||||
|
|
||||||
You also need to create a file called (projectname)/css/editor.css with the following content:
|
|
||||||
|
|
||||||
:::css
|
|
||||||
/**
|
|
||||||
* This support file is used to style the WYSIWYG editor in the CMS
|
|
||||||
*/
|
|
||||||
|
|
||||||
@import "typography.css";
|
|
||||||
|
|
||||||
body.mceContentBody {
|
|
||||||
min-height: 200px;
|
|
||||||
font-size: 62.5%;
|
|
||||||
}
|
|
||||||
body.mceContentBody a.broken {
|
|
||||||
background-color: #FF7B71;
|
|
||||||
border: 1px red solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
In typography.css you can define styles of any of the tags that will get created by the editor:
|
|
||||||
|
|
||||||
* P, BLOCKQUOTE
|
|
||||||
* H1-6
|
|
||||||
* UL, OL, LI
|
|
||||||
* TABLE
|
|
||||||
* STRONG, EM, U
|
|
||||||
* A
|
|
||||||
|
|
||||||
It's important to realise that this CSS file is included directly into the CMS system, and if you aren't careful, you
|
|
||||||
can alter the styling of other parts of the interface. While this is novel, it can be dangerous and is probably not
|
|
||||||
what you're after.
|
|
||||||
|
|
||||||
The way around this is to limit all your styling selectors to elements inside something with `class="typography"`. The
|
|
||||||
other half of this is to put `class="typography"` onto any area in your template where you would like the styling to be
|
|
||||||
applied.
|
|
||||||
|
|
||||||
**WRONG**
|
|
||||||
|
|
||||||
:::css
|
|
||||||
CSS:
|
|
||||||
h1, h2 {
|
|
||||||
color: #F77;
|
|
||||||
}
|
|
||||||
|
|
||||||
Template:
|
|
||||||
<div>
|
|
||||||
$Content
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
**RIGHT**
|
|
||||||
|
|
||||||
:::css
|
|
||||||
CSS:
|
|
||||||
.typography h1, .typography h2 {
|
|
||||||
color: #F77;
|
|
||||||
}
|
|
||||||
|
|
||||||
Template:
|
|
||||||
<div class="typography">
|
|
||||||
$Content
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
If you would to include different styles for different sections of your site, you can use class names the same as the
|
|
||||||
name of the data fields. This example sets up different paragraph styles for 2 HTML editor fields called Content and
|
|
||||||
OtherContent:
|
|
||||||
|
|
||||||
:::css
|
|
||||||
.Content.typography p {
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.OtherContent.typography p {
|
|
||||||
font-size: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
### Removing the typography class
|
|
||||||
|
|
||||||
Sometimes, it's not enough to add a class, you also want to remove the typography class. You can use the
|
|
||||||
`[api:HTMLEditorField]` method setCSSClass.
|
|
||||||
|
|
||||||
This example sets another CSS class typographybis:
|
|
||||||
|
|
||||||
:::php
|
|
||||||
public function getCMSFields() {
|
|
||||||
...
|
|
||||||
$htmleditor = new HTMLEditorField("ContentBis", "Content Bis");
|
|
||||||
$htmleditor->setCSSClass('typographybis');
|
|
||||||
$fields->addFieldToTab("Root.Content", $htmleditor);
|
|
||||||
...
|
|
||||||
return $fields;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
**Note:** This functionality will be available in the version 2.0.2 of the CMS.
|
|
@ -1,301 +0,0 @@
|
|||||||
# ModelAdmin
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
|
|
||||||
Provides a simple way to utilize the SilverStripe CMS UI with your own data models,
|
|
||||||
and create searchable list and edit views of them, and even providing import and export of your data.
|
|
||||||
|
|
||||||
It uses the framework's knowledge about the model to provide sensible defaults,
|
|
||||||
allowing you to get started in a couple of lines of code,
|
|
||||||
while still providing a solid base for customization.
|
|
||||||
|
|
||||||
The interface is mainly powered by the [GridField](/reference/grid-field) class,
|
|
||||||
which can also be used in other CMS areas (e.g. to manage a relation on a `SiteTree`
|
|
||||||
record in the standard CMS interface).
|
|
||||||
|
|
||||||
## Setup
|
|
||||||
|
|
||||||
Let's assume we want to manage a simple product listing as a sample data model:
|
|
||||||
A product can have a name, price, and a category.
|
|
||||||
|
|
||||||
:::php
|
|
||||||
class Product extends DataObject {
|
|
||||||
private static $db = array('Name' => 'Varchar', 'ProductCode' => 'Varchar', 'Price' => 'Currency');
|
|
||||||
private static $has_one = array('Category' => 'Category');
|
|
||||||
}
|
|
||||||
class Category extends DataObject {
|
|
||||||
private static $db = array('Title' => 'Text');
|
|
||||||
private static $has_many = array('Products' => 'Product');
|
|
||||||
}
|
|
||||||
|
|
||||||
To create your own `ModelAdmin`, simply extend the base class,
|
|
||||||
and edit the `$managed_models` property with the list of
|
|
||||||
data objects you want to scaffold an interface for.
|
|
||||||
The class can manage multiple models in parallel, if required.
|
|
||||||
We'll name it `MyAdmin`, but the class name can be anything you want.
|
|
||||||
|
|
||||||
:::php
|
|
||||||
class MyAdmin extends ModelAdmin {
|
|
||||||
private static $managed_models = array('Product','Category'); // Can manage multiple models
|
|
||||||
private static $url_segment = 'products'; // Linked as /admin/products/
|
|
||||||
private static $menu_title = 'My Product Admin';
|
|
||||||
}
|
|
||||||
|
|
||||||
This will automatically add a new menu entry to the CMS, and you're ready to go!
|
|
||||||
Try opening http://localhost/admin/products/?flush=all.
|
|
||||||
|
|
||||||
## Permissions
|
|
||||||
|
|
||||||
Each new `ModelAdmin` subclass creates its own [permission code](/reference/permission),
|
|
||||||
for the example above this would be `CMS_ACCESS_MyAdmin`. Users with access to the CMS
|
|
||||||
need to have this permission assigned through `admin/security/` in order to gain
|
|
||||||
access to the controller (unless they're admins).
|
|
||||||
|
|
||||||
The `DataObject` API has more granular permission control, which is enforced in ModelAdmin by default.
|
|
||||||
Available checks are `canEdit()`, `canCreate()`, `canView()` and `canDelete()`.
|
|
||||||
Models check for administrator permissions by default. For most cases,
|
|
||||||
less restrictive checks make sense, e.g. checking for general CMS access rights.
|
|
||||||
|
|
||||||
:::php
|
|
||||||
class Category extends DataObject {
|
|
||||||
// ...
|
|
||||||
public function canView($member = null) {
|
|
||||||
return Permission::check('CMS_ACCESS_CMSMain', 'any', $member);
|
|
||||||
}
|
|
||||||
public function canEdit($member = null) {
|
|
||||||
return Permission::check('CMS_ACCESS_CMSMain', 'any', $member);
|
|
||||||
}
|
|
||||||
public function canDelete($member = null) {
|
|
||||||
return Permission::check('CMS_ACCESS_CMSMain', 'any', $member);
|
|
||||||
}
|
|
||||||
public function canCreate($member = null) {
|
|
||||||
return Permission::check('CMS_ACCESS_CMSMain', 'any', $member);
|
|
||||||
}
|
|
||||||
|
|
||||||
## Search Fields
|
|
||||||
|
|
||||||
ModelAdmin uses the [SearchContext](/reference/searchcontext) class to provide
|
|
||||||
a search form, as well as get the searched results. Every DataObject can have its own context,
|
|
||||||
based on the fields which should be searchable. The class makes a guess at how those fields
|
|
||||||
should be searched, e.g. showing a checkbox for any boolean fields in your `$db` definition.
|
|
||||||
|
|
||||||
To remove, add or modify searchable fields, define a new `[api:DataObject::$searchable_fields]`
|
|
||||||
static on your model class (see [SearchContext](/reference/searchcontext) docs for details).
|
|
||||||
|
|
||||||
:::php
|
|
||||||
class Product extends DataObject {
|
|
||||||
// ...
|
|
||||||
private static $searchable_fields = array(
|
|
||||||
'Name',
|
|
||||||
'ProductCode'
|
|
||||||
// leaves out the 'Price' field, removing it from the search
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
For a more sophisticated customization, for example configuring the form fields
|
|
||||||
for the search form, override `DataObject->getCustomSearchContext()` on your model class.
|
|
||||||
|
|
||||||
## Result Columns
|
|
||||||
|
|
||||||
The results are shown in a tabular listing, powered by the [GridField](/reference/grid-field),
|
|
||||||
more specifically the `[api:GridFieldDataColumns]` component.
|
|
||||||
It looks for a `[api:DataObject::$summary_fields]` static on your model class,
|
|
||||||
where you can add or remove columns. To change the title, use `[api:DataObject::$field_labels]`.
|
|
||||||
|
|
||||||
:::php
|
|
||||||
class Product extends DataObject {
|
|
||||||
// ...
|
|
||||||
private static $field_labels = array(
|
|
||||||
'Price' => 'Cost' // renames the column to "Cost"
|
|
||||||
);
|
|
||||||
private static $summary_fields = array(
|
|
||||||
'Name',
|
|
||||||
'Price',
|
|
||||||
// leaves out the 'ProductCode' field, removing the column
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
## Results Customization
|
|
||||||
|
|
||||||
The results are retrieved from `[api:SearchContext->getResults()]`,
|
|
||||||
based on the parameters passed through the search form.
|
|
||||||
If no search parameters are given, the results will show every record.
|
|
||||||
Results are a `[api:DataList]` instance, so can be customized by additional
|
|
||||||
SQL filters, joins, etc (see [datamodel](/topics/datamodel) for more info).
|
|
||||||
|
|
||||||
For example, we might want to exclude all products without prices in our sample `MyAdmin` implementation.
|
|
||||||
|
|
||||||
:::php
|
|
||||||
class MyAdmin extends ModelAdmin {
|
|
||||||
// ...
|
|
||||||
public function getList() {
|
|
||||||
$list = parent::getList();
|
|
||||||
// Always limit by model class, in case you're managing multiple
|
|
||||||
if($this->modelClass == 'Product') {
|
|
||||||
$list = $list->exclude('Price', '0');
|
|
||||||
}
|
|
||||||
return $list;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
You can also customize the search behaviour directly on your `ModelAdmin` instance.
|
|
||||||
For example, we might want to have a checkbox which limits search results to expensive products (over $100).
|
|
||||||
|
|
||||||
:::php
|
|
||||||
class MyAdmin extends ModelAdmin {
|
|
||||||
// ...
|
|
||||||
public function getSearchContext() {
|
|
||||||
$context = parent::getSearchContext();
|
|
||||||
if($this->modelClass == 'Product') {
|
|
||||||
$context->getFields()->push(new CheckboxField('q[ExpensiveOnly]', 'Only expensive stuff'));
|
|
||||||
}
|
|
||||||
return $context;
|
|
||||||
}
|
|
||||||
public function getList() {
|
|
||||||
$list = parent::getList();
|
|
||||||
$params = $this->request->requestVar('q'); // use this to access search parameters
|
|
||||||
if($this->modelClass == 'Product' && isset($params['ExpensiveOnly']) && $params['ExpensiveOnly']) {
|
|
||||||
$list = $list->exclude('Price:LessThan', '100');
|
|
||||||
}
|
|
||||||
return $list;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
### GridField Customization
|
|
||||||
|
|
||||||
To alter how the results are displayed (via `[api:GridField]`), you can also overload the `getEditForm()` method. For example, to add a new component.
|
|
||||||
|
|
||||||
:::php
|
|
||||||
class MyAdmin extends ModelAdmin {
|
|
||||||
private static $managed_models = array('Product','Category');
|
|
||||||
// ...
|
|
||||||
public function getEditForm($id = null, $fields = null) {
|
|
||||||
$form = parent::getEditForm($id, $fields);
|
|
||||||
// $gridFieldName is generated from the ModelClass, eg if the Class 'Product'
|
|
||||||
// is managed by this ModelAdmin, the GridField for it will also be named 'Product'
|
|
||||||
$gridFieldName = $this->sanitiseClassName($this->modelClass);
|
|
||||||
$gridField = $form->Fields()->fieldByName($gridFieldName);
|
|
||||||
$gridField->getConfig()->addComponent(new GridFieldFilterHeader());
|
|
||||||
return $form;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
The above example will add the component to all `GridField`s (of all managed models). Alternatively we can also add it to only one specific `GridField`:
|
|
||||||
|
|
||||||
:::php
|
|
||||||
class MyAdmin extends ModelAdmin {
|
|
||||||
private static $managed_models = array('Product','Category');
|
|
||||||
// ...
|
|
||||||
public function getEditForm($id = null, $fields = null) {
|
|
||||||
$form = parent::getEditForm($id, $fields);
|
|
||||||
$gridFieldName = 'Product';
|
|
||||||
$gridField = $form->Fields()->fieldByName($gridFieldName);
|
|
||||||
if ($gridField) {
|
|
||||||
$gridField->getConfig()->addComponent(new GridFieldFilterHeader());
|
|
||||||
}
|
|
||||||
return $form;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
## Managing Relationships
|
|
||||||
|
|
||||||
Has-one relationships are simply implemented as a `[api:DropdownField]` by default.
|
|
||||||
Consider replacing it with a more powerful interface in case you have many records
|
|
||||||
(through customizing `[api:DataObject->getCMSFields]`).
|
|
||||||
|
|
||||||
Has-many and many-many relationships are usually handled via the [GridField](/reference/grid-field) class,
|
|
||||||
more specifically the `[api:GridFieldAddExistingAutocompleter]` and `[api:GridFieldRelationDelete]` components.
|
|
||||||
They provide a list/detail interface within a single record edited in your ModelAdmin.
|
|
||||||
The [GridField](/reference/grid-field) docs also explain how to manage
|
|
||||||
extra relation fields on join tables through its detail forms.
|
|
||||||
The autocompleter can also search attributes on relations,
|
|
||||||
based on the search fields defined through `[api:DataObject::searchableFields()]`.
|
|
||||||
|
|
||||||
## Permissions
|
|
||||||
|
|
||||||
`ModelAdmin` respects the permissions set on the model, through methods on your `DataObject` implementations:
|
|
||||||
`canView()`, `canEdit()`, `canDelete()`, and `canCreate`.
|
|
||||||
|
|
||||||
In terms of access control to the interface itself, every `ModelAdmin` subclass
|
|
||||||
creates its own "[permission code](/reference/permissions)", which can be assigned
|
|
||||||
to groups through the `admin/security` management interface. To further limit
|
|
||||||
permission, either override checks in `ModelAdmin->init()`, or define
|
|
||||||
more permission codes through the `ModelAdmin::$required_permission_codes` static.
|
|
||||||
|
|
||||||
## Data Import
|
|
||||||
|
|
||||||
The `ModelAdmin` class provides import of CSV files through the `[api:CsvBulkLoader]` API.
|
|
||||||
which has support for column mapping, updating existing records,
|
|
||||||
and identifying relationships - so its a powerful tool to get your data into a SilverStripe database.
|
|
||||||
|
|
||||||
By default, each model management interface allows uploading a CSV file
|
|
||||||
with all columns autodetected. To override with a more specific importer implementation,
|
|
||||||
use the `[api:ModelAdmin::$model_importers] static.
|
|
||||||
|
|
||||||
## Data Export
|
|
||||||
|
|
||||||
Export is also available, although at the moment only to the CSV format,
|
|
||||||
through a button at the end of a results list. You can also export search results.
|
|
||||||
It is handled through the `[api:GridFieldExportButton]` component.
|
|
||||||
|
|
||||||
To customize the exported columns, create a new method called `getExportFields` in your `ModelAdmin`:
|
|
||||||
|
|
||||||
:::php
|
|
||||||
class MyAdmin extends ModelAdmin {
|
|
||||||
// ...
|
|
||||||
public function getExportFields() {
|
|
||||||
return array(
|
|
||||||
'Name' => 'Name',
|
|
||||||
'ProductCode' => 'Product Code',
|
|
||||||
'Category.Title' => 'Category'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Dot syntax support allows you to select a field on a related `has_one` object.
|
|
||||||
|
|
||||||
## Extending existing ModelAdmins
|
|
||||||
|
|
||||||
Sometimes you'll work with ModelAdmins from other modules, e.g. the product management
|
|
||||||
of an ecommerce module. To customize this, you can always subclass. But there's
|
|
||||||
also another tool at your disposal: The `[api:Extension]` API.
|
|
||||||
|
|
||||||
:::php
|
|
||||||
class MyAdminExtension extends Extension {
|
|
||||||
// ...
|
|
||||||
public function updateEditForm(&$form) {
|
|
||||||
$form->Fields()->push(/* ... */)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Now enable this extension through your `[config.yml](/topics/configuration)` file.
|
|
||||||
|
|
||||||
:::yml
|
|
||||||
MyAdmin:
|
|
||||||
extensions:
|
|
||||||
- MyAdminExtension
|
|
||||||
|
|
||||||
The following extension points are available: `updateEditForm()`, `updateSearchContext()`,
|
|
||||||
`updateSearchForm()`, `updateList()`, `updateImportForm`.
|
|
||||||
|
|
||||||
## Customizing the interface
|
|
||||||
|
|
||||||
Interfaces like `ModelAdmin` can be customized in many ways:
|
|
||||||
|
|
||||||
* JavaScript behaviour (e.g. overwritten jQuery.entwine rules)
|
|
||||||
* CSS styles
|
|
||||||
* HTML markup through templates
|
|
||||||
|
|
||||||
In general, use your `ModelAdmin->init()` method to add additional requirements
|
|
||||||
through the [Requirements](/reference/requirements) API.
|
|
||||||
For an introduction how to customize the CMS templates, see our [CMS Architecture Guide](/reference/cms-architecture).
|
|
||||||
|
|
||||||
## Related
|
|
||||||
|
|
||||||
* [GridField](../reference/grid-field): The UI component powering ModelAdmin
|
|
||||||
* [Tutorial 5: Dataobject Relationship Management](../tutorials/5-dataobject-relationship-management)
|
|
||||||
* `[api:SearchContext]`
|
|
||||||
* [genericviews Module](http://silverstripe.org/generic-views-module)
|
|
||||||
* [Presentation about ModelAdmin at SupperHappyDevHouse Wellington](http://www.slideshare.net/chillu/modeladmin-in-silverstripe-23)
|
|
||||||
* [Reference: CMS Architecture](../reference/cms-architecture)
|
|
||||||
* [Howto: Extend the CMS Interface](../howto/extend-cms-interface)
|
|
@ -1,7 +0,0 @@
|
|||||||
summary: Extend the admin view to provide custom behavior or new features for CMS users.
|
|
||||||
|
|
||||||
[CHILDREN]
|
|
||||||
|
|
||||||
## How-to
|
|
||||||
|
|
||||||
[CHILDREN How_To]
|
|
Loading…
Reference in New Issue
Block a user