mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-01 05:39:10 +02:00
Doc cleanup (spelling, line length, grammar)
This commit is contained in:
parent
db85f3ca16
commit
e1b1fce31f
@ -2,28 +2,31 @@
|
|||||||
|
|
||||||
## Introduction ##
|
## Introduction ##
|
||||||
|
|
||||||
The CMS interface works just like any other part of your website: It consists of PHP controllers,
|
The CMS interface works just like any other part of your website: It consists of
|
||||||
templates, CSS stylesheets and JavaScript. Because it uses the same base elements,
|
PHP controllers, templates, CSS stylesheets and JavaScript. Because it uses the
|
||||||
it is relatively easy to extend.
|
same base elements, it is relatively easy to extend.
|
||||||
As an example, we're going to add a permanent "bookmarks" bar to popular pages at the bottom of the CMS.
|
|
||||||
A page can be bookmarked by a CMS author through a simple checkbox.
|
As an example, we're going to add a permanent "bookmarks" bar to popular pages
|
||||||
|
at the bottom of the CMS. A page can be bookmarked by a CMS author through a
|
||||||
|
simple checkbox.
|
||||||
|
|
||||||
For a deeper introduction to the inner workings of the CMS, please refer to our
|
For a deeper introduction to the inner workings of the CMS, please refer to our
|
||||||
guide on [CMS Architecture](../reference/cms-architecture).
|
guide on [CMS Architecture](../reference/cms-architecture).
|
||||||
|
|
||||||
## Overload a CMS template ##
|
## Overload a CMS template ##
|
||||||
|
|
||||||
If you place a template with an identical name into your application template directory
|
If you place a template with an identical name into your application template
|
||||||
(usually `mysite/templates/`), it'll take priority over the built-in one.
|
directory (usually `mysite/templates/`), it'll take priority over the built-in
|
||||||
|
one.
|
||||||
|
|
||||||
CMS templates are inherited based on their controllers, similar to subclasses of
|
CMS templates are inherited based on their controllers, similar to subclasses of
|
||||||
the common `Page` object (a new PHP class `MyPage` will look for a `MyPage.ss` template).
|
the common `Page` object (a new PHP class `MyPage` will look for a `MyPage.ss` template).
|
||||||
We can use this to create a different base template with `LeftAndMain.ss`
|
We can use this to create a different base template with `LeftAndMain.ss`
|
||||||
(which corresponds to the `LeftAndMain` PHP controller class).
|
(which corresponds to the `LeftAndMain` PHP controller class).
|
||||||
|
|
||||||
Copy the template markup of the base implementation at `framework/admin/templates/LeftAndMain.ss` into
|
Copy the template markup of the base implementation at `framework/admin/templates/LeftAndMain.ss`
|
||||||
`mysite/templates/LeftAndMain.ss`. It will automatically be picked up by the CMS logic. Add a new section after the
|
into `mysite/templates/LeftAndMain.ss`. It will automatically be picked up by
|
||||||
`$Content` tag:
|
the CMS logic. Add a new section after the `$Content` tag:
|
||||||
|
|
||||||
:::ss
|
:::ss
|
||||||
...
|
...
|
||||||
@ -39,21 +42,24 @@ Copy the template markup of the base implementation at `framework/admin/template
|
|||||||
</div>
|
</div>
|
||||||
...
|
...
|
||||||
|
|
||||||
Refresh the CMS interface with `admin/?flush=all`, and you should see the new bottom bar with some hardcoded links.
|
Refresh the CMS interface with `admin/?flush=all`, and you should see the new
|
||||||
We'll make these dynamic further down.
|
bottom bar with some hardcoded links. We'll make these dynamic further down.
|
||||||
|
|
||||||
You might have noticed that we didn't write any JavaScript to add our layout manager.
|
You might have noticed that we didn't write any JavaScript to add our layout
|
||||||
The important piece of information is the `south` class in our new `<div>` structure,
|
manager. The important piece of information is the `south` class in our new
|
||||||
plus the height value in our CSS. It instructs the existing parent layout how to render the element.
|
`<div>` structure, plus the height value in our CSS. It instructs the existing
|
||||||
This layout manager ([jLayout](http://www.bramstein.com/projects/jlayout/))
|
parent layout how to render the element. This layout manager
|
||||||
allows us to build complex layouts with minimal JavaScript configuration.
|
([jLayout](http://www.bramstein.com/projects/jlayout/)) allows us to build
|
||||||
|
complex layouts with minimal JavaScript configuration.
|
||||||
|
|
||||||
See [layout reference](../reference/layout) for more specific information on CMS layouting.
|
See [layout reference](../reference/layout) for more specific information on
|
||||||
|
CMS layouting.
|
||||||
|
|
||||||
## Include custom CSS in the CMS
|
## Include custom CSS in the CMS
|
||||||
|
|
||||||
In order to show the links in one line, we'll add some CSS, and get it to load with the CMS interface.
|
In order to show the links in one line, we'll add some CSS, and get it to load
|
||||||
Paste the following content into a new file called `mysite/css/BookmarkedPages.css`:
|
with the CMS interface. Paste the following content into a new file called
|
||||||
|
`mysite/css/BookmarkedPages.css`:
|
||||||
|
|
||||||
:::css
|
:::css
|
||||||
.cms-bottom-bar {height: 20px; padding: 5px; background: #C6D7DF;}
|
.cms-bottom-bar {height: 20px; padding: 5px; background: #C6D7DF;}
|
||||||
@ -71,14 +77,19 @@ Load the new CSS file into the CMS, by setting the `LeftAndMain.extra_requiremen
|
|||||||
|
|
||||||
## Create a "bookmark" flag on pages ##
|
## Create a "bookmark" flag on pages ##
|
||||||
|
|
||||||
Now we'll define which pages are actually bookmarked, a flag that is stored in the database.
|
Now we'll define which pages are actually bookmarked, a flag that is stored in
|
||||||
For this we need to decorate the page record with a `DataExtension`.
|
the database. For this we need to decorate the page record with a
|
||||||
Create a new file called `mysite/code/BookmarkedPageExtension.php` and insert the following code.
|
`DataExtension`. Create a new file called `mysite/code/BookmarkedPageExtension.php`
|
||||||
|
and insert the following code.
|
||||||
|
|
||||||
:::php
|
:::php
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
class BookmarkedPageExtension extends DataExtension {
|
class BookmarkedPageExtension extends DataExtension {
|
||||||
private static $db = array('IsBookmarked' => 'Boolean');
|
|
||||||
|
private static $db = array(
|
||||||
|
'IsBookmarked' => 'Boolean'
|
||||||
|
);
|
||||||
|
|
||||||
public function updateCMSFields(FieldList $fields) {
|
public function updateCMSFields(FieldList $fields) {
|
||||||
$fields->addFieldToTab('Root.Main',
|
$fields->addFieldToTab('Root.Main',
|
||||||
@ -100,14 +111,17 @@ Refresh the CMS, open a page for editing and you should see the new checkbox.
|
|||||||
## Retrieve the list of bookmarks from the database
|
## Retrieve the list of bookmarks from the database
|
||||||
|
|
||||||
One piece in the puzzle is still missing: How do we get the list of bookmarked
|
One piece in the puzzle is still missing: How do we get the list of bookmarked
|
||||||
pages from the datbase into the template we've already created (with hardcoded links)?
|
pages from the database into the template we've already created (with hardcoded
|
||||||
Again, we extend a core class: The main CMS controller called `LeftAndMain`.
|
links)? Again, we extend a core class: The main CMS controller called
|
||||||
|
`LeftAndMain`.
|
||||||
|
|
||||||
Add the following code to a new file `mysite/code/BookmarkedLeftAndMainExtension.php`;
|
Add the following code to a new file `mysite/code/BookmarkedLeftAndMainExtension.php`;
|
||||||
|
|
||||||
:::php
|
:::php
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
class BookmarkedPagesLeftAndMainExtension extends LeftAndMainExtension {
|
class BookmarkedPagesLeftAndMainExtension extends LeftAndMainExtension {
|
||||||
|
|
||||||
public function BookmarkedPages() {
|
public function BookmarkedPages() {
|
||||||
return Page::get()->filter("IsBookmarked", 1);
|
return Page::get()->filter("IsBookmarked", 1);
|
||||||
}
|
}
|
||||||
@ -133,39 +147,51 @@ and replace it with the following:
|
|||||||
|
|
||||||
## Extending the CMS actions
|
## Extending the CMS actions
|
||||||
|
|
||||||
CMS actions follow a principle similar to the CMS fields: they are built in the backend with the help of `FormFields`
|
CMS actions follow a principle similar to the CMS fields: they are built in the
|
||||||
and `FormActions`, and the frontend is responsible for applying a consistent styling.
|
backend with the help of `FormFields` and `FormActions`, and the frontend is
|
||||||
|
responsible for applying a consistent styling.
|
||||||
|
|
||||||
The following conventions apply:
|
The following conventions apply:
|
||||||
|
|
||||||
* New actions can be added by redefining `getCMSActions`, or adding an extension with `updateCMSActions`.
|
* New actions can be added by redefining `getCMSActions`, or adding an extension
|
||||||
* It is required the actions are contained in a `FieldSet` (`getCMSActions` returns this already).
|
with `updateCMSActions`.
|
||||||
* Standalone buttons are created by adding a top-level `FormAction` (no such button is added by default).
|
* It is required the actions are contained in a `FieldSet` (`getCMSActions`
|
||||||
* Button groups are created by adding a top-level `CompositeField` with `FormActions` in it.
|
returns this already).
|
||||||
|
* Standalone buttons are created by adding a top-level `FormAction` (no such
|
||||||
|
button is added by default).
|
||||||
|
* Button groups are created by adding a top-level `CompositeField` with
|
||||||
|
`FormActions` in it.
|
||||||
* A `MajorActions` button group is already provided as a default.
|
* A `MajorActions` button group is already provided as a default.
|
||||||
* Drop ups with additional actions that appear as links are created via a `TabSet` and `Tabs` with `FormActions` inside.
|
* Drop ups with additional actions that appear as links are created via a
|
||||||
* A `ActionMenus.MoreOptions` tab is already provided as a default and contains some minor actions.
|
`TabSet` and `Tabs` with `FormActions` inside.
|
||||||
* You can override the actions completely by providing your own `getAllCMSFields`.
|
* A `ActionMenus.MoreOptions` tab is already provided as a default and contains
|
||||||
|
some minor actions.
|
||||||
|
* You can override the actions completely by providing your own
|
||||||
|
`getAllCMSFields`.
|
||||||
|
|
||||||
Let's walk through a couple of examples of adding new CMS actions in `getCMSActions`.
|
Let's walk through a couple of examples of adding new CMS actions in `getCMSActions`.
|
||||||
|
|
||||||
First of all we can add a regular standalone button anywhere in the set. Here we are inserting it in the front of all
|
First of all we can add a regular standalone button anywhere in the set. Here
|
||||||
other actions. We could also add a button group (`CompositeField`) in a similar fashion.
|
we are inserting it in the front of all other actions. We could also add a
|
||||||
|
button group (`CompositeField`) in a similar fashion.
|
||||||
|
|
||||||
:::php
|
:::php
|
||||||
$fields->unshift(FormAction::create('normal', 'Normal button'));
|
$fields->unshift(FormAction::create('normal', 'Normal button'));
|
||||||
|
|
||||||
We can affect the existing button group by manipulating the `CompositeField` already present in the `FieldList`.
|
We can affect the existing button group by manipulating the `CompositeField`
|
||||||
|
already present in the `FieldList`.
|
||||||
|
|
||||||
:::php
|
:::php
|
||||||
$fields->fieldByName('MajorActions')->push(FormAction::create('grouped', 'New group button'));
|
$fields->fieldByName('MajorActions')->push(FormAction::create('grouped', 'New group button'));
|
||||||
|
|
||||||
Another option is adding actions into the drop-up - best place for placing infrequently used minor actions.
|
Another option is adding actions into the drop-up - best place for placing
|
||||||
|
infrequently used minor actions.
|
||||||
|
|
||||||
:::php
|
:::php
|
||||||
$fields->addFieldToTab('ActionMenus.MoreOptions', FormAction::create('minor', 'Minor action'));
|
$fields->addFieldToTab('ActionMenus.MoreOptions', FormAction::create('minor', 'Minor action'));
|
||||||
|
|
||||||
We can also easily create new drop-up menus by defining new tabs within the `TabSet`.
|
We can also easily create new drop-up menus by defining new tabs within the
|
||||||
|
`TabSet`.
|
||||||
|
|
||||||
:::php
|
:::php
|
||||||
$fields->addFieldToTab('ActionMenus.MyDropUp', FormAction::create('minor', 'Minor action in a new drop-up'));
|
$fields->addFieldToTab('ActionMenus.MyDropUp', FormAction::create('minor', 'Minor action in a new drop-up'));
|
||||||
@ -174,15 +200,18 @@ We can also easily create new drop-up menus by defining new tabs within the `Tab
|
|||||||
Empty tabs will be automatically removed from the `FieldList` to prevent clutter.
|
Empty tabs will be automatically removed from the `FieldList` to prevent clutter.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
New actions will need associated controller handlers to work. You can use a `LeftAndMainExtension` to provide one. Refer
|
New actions will need associated controller handlers to work. You can use a
|
||||||
to [Controller documentation](../topics/controller) for instructions on setting up handlers.
|
`LeftAndMainExtension` to provide one. Refer to [Controller documentation](../topics/controller)
|
||||||
|
for instructions on setting up handlers.
|
||||||
|
|
||||||
To make the actions more user-friendly you can also use alternating buttons as detailed in the [CMS Alternating
|
To make the actions more user-friendly you can also use alternating buttons as
|
||||||
Button](../reference/cms-alternating-button) how-to.
|
detailed in the [CMS Alternating Button](../reference/cms-alternating-button)
|
||||||
|
how-to.
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
In a few lines of code, we've customized the look and feel of the CMS.
|
In a few lines of code, we've customized the look and feel of the CMS.
|
||||||
|
|
||||||
While this example is only scratching the surface, it includes most building
|
While this example is only scratching the surface, it includes most building
|
||||||
blocks and concepts for more complex extensions as well.
|
blocks and concepts for more complex extensions as well.
|
||||||
|
|
||||||
|
@ -2,31 +2,37 @@
|
|||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
With the addition of side-by-side editing, the preview has the ability to appear within the CMS window when editing
|
With the addition of side-by-side editing, the preview has the ability to appear
|
||||||
content in the _Pages_ section of the CMS. The site is rendered into an iframe. It will update itself whenever the
|
within the CMS window when editing content in the _Pages_ section of the CMS.
|
||||||
content is saved, and relevant pages will be loaded for editing when the user navigates around in the preview.
|
The site is rendered into an iframe. It will update itself whenever the content
|
||||||
|
is saved, and relevant pages will be loaded for editing when the user navigates
|
||||||
|
around in the preview.
|
||||||
|
|
||||||
The root element for preview is `.cms-preview` which maintains the internal states neccessary for rendering within the
|
The root element for preview is `.cms-preview` which maintains the internal
|
||||||
entwine properties. It provides function calls for transitioning between these states and has the ability to update the
|
states necessary for rendering within the entwine properties. It provides
|
||||||
appearance of the option selectors.
|
function calls for transitioning between these states and has the ability to
|
||||||
|
update the appearance of the option selectors.
|
||||||
|
|
||||||
In terms of backend support, it relies on `SilverStripeNavigator` to be rendered into the `.cms-edit-form`.
|
In terms of backend support, it relies on `SilverStripeNavigator` to be rendered
|
||||||
_LeftAndMain_ will automatically take care of generating it as long as the `*_SilverStripeNavigator` template is found -
|
into the `.cms-edit-form`. _LeftAndMain_ will automatically take care of
|
||||||
first segment has to match current _LeftAndMain_-derived class (e.g. `LeftAndMain_SilverStripeNavigator`).
|
generating it as long as the `*_SilverStripeNavigator` template is found -
|
||||||
|
first segment has to match current _LeftAndMain_-derived class (e.g.
|
||||||
|
`LeftAndMain_SilverStripeNavigator`).
|
||||||
|
|
||||||
We use `ss.preview` entwine namespace for all preview-related entwines.
|
We use `ss.preview` entwine namespace for all preview-related entwines.
|
||||||
|
|
||||||
<div class="notice" markdown='1'>
|
<div class="notice" markdown='1'>
|
||||||
Caveat: `SilverStripeNavigator` and `CMSPreviewable` interface currently only support SiteTree objects that are
|
Caveat: `SilverStripeNavigator` and `CMSPreviewable` interface currently only
|
||||||
_Versioned_. They are not general enough for using on any other DataObject. That pretty much limits the extendability
|
support SiteTree objects that are _Versioned_. They are not general enough for
|
||||||
of the feature.
|
using on any other DataObject. That pretty much limits the extendability of the
|
||||||
|
feature.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Configuration and Defaults
|
## Configuration and Defaults
|
||||||
|
|
||||||
Like most of the CMS, the preview UI is powered by
|
Like most of the CMS, the preview UI is powered by
|
||||||
[jQuery entwine](https://github.com/hafriedlander/jquery.entwine).
|
[jQuery entwine](https://github.com/hafriedlander/jquery.entwine). This means
|
||||||
This means its defaults are configured through JavaScript, by setting entwine properties.
|
its defaults are configured through JavaScript, by setting entwine properties.
|
||||||
In order to achieve this, create a new file `mysite/javascript/MyLeftAndMain.Preview.js`.
|
In order to achieve this, create a new file `mysite/javascript/MyLeftAndMain.Preview.js`.
|
||||||
|
|
||||||
In the following example we configure three aspects:
|
In the following example we configure three aspects:
|
||||||
@ -78,30 +84,33 @@ To understand how layouts are handled in the CMS UI, have a look at the
|
|||||||
|
|
||||||
## Enabling preview
|
## Enabling preview
|
||||||
|
|
||||||
The frontend decides on the preview being enabled or disabled based on the presnce of the `.cms-previewable` class. If
|
The frontend decides on the preview being enabled or disabled based on the
|
||||||
this class is not found the preview will remain hidden, and the layout will stay in the _content_ mode.
|
presence of the `.cms-previewable` class. If this class is not found the preview
|
||||||
|
will remain hidden, and the layout will stay in the _content_ mode.
|
||||||
|
|
||||||
If the class is found, frontend looks for the `SilverStripeNavigator` structure and moves it to the
|
If the class is found, frontend looks for the `SilverStripeNavigator` structure
|
||||||
`.cms-preview-control` panel at the bottom of the preview. This structure supplies preview options such as state
|
and moves it to the `.cms-preview-control` panel at the bottom of the preview.
|
||||||
selector.
|
This structure supplies preview options such as state selector.
|
||||||
|
|
||||||
If the navigator is not found, the preview appears in the GUI, but is shown as "blocked" - i.e. displaying the "preview
|
If the navigator is not found, the preview appears in the GUI, but is shown as
|
||||||
unavailable" overlay.
|
"blocked" - i.e. displaying the "preview unavailable" overlay.
|
||||||
|
|
||||||
The preview can be affected by calling `enablePreview` and `disablePreview`. You can check if the preview is active by
|
The preview can be affected by calling `enablePreview` and `disablePreview`. You
|
||||||
inspecting the `IsPreviewEnabled` entwine property.
|
can check if the preview is active by inspecting the `IsPreviewEnabled` entwine
|
||||||
|
property.
|
||||||
|
|
||||||
## Preview states
|
## Preview states
|
||||||
|
|
||||||
States are the site stages: _live_, _stage_ etc. Preview states are picked up from the `SilverStripeNavigator`.
|
States are the site stages: _live_, _stage_ etc. Preview states are picked up
|
||||||
You can invoke the state change by calling:
|
from the `SilverStripeNavigator`. You can invoke the state change by calling:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
$('.cms-preview').entwine('.ss.preview').changeState('StageLink');
|
$('.cms-preview').entwine('.ss.preview').changeState('StageLink');
|
||||||
```
|
```
|
||||||
|
|
||||||
Note the state names come from `SilverStripeNavigatorItems` class names - thus the _Link_ in their names. This call will
|
Note the state names come from `SilverStripeNavigatorItems` class names - thus
|
||||||
also redraw the state selector to fit with the internal state. See `AllowedStates` in `.cms-preview` entwine for the
|
the _Link_ in their names. This call will also redraw the state selector to fit
|
||||||
|
with the internal state. See `AllowedStates` in `.cms-preview` entwine for the
|
||||||
list of supported states.
|
list of supported states.
|
||||||
|
|
||||||
You can get the current state by calling:
|
You can get the current state by calling:
|
||||||
@ -112,16 +121,18 @@ You can get the current state by calling:
|
|||||||
|
|
||||||
## Preview sizes
|
## Preview sizes
|
||||||
|
|
||||||
This selector defines how the preview iframe is rendered, and try to emulate different device sizes. The options are
|
This selector defines how the preview iframe is rendered, and try to emulate
|
||||||
hardcoded. The option names map directly to CSS classes applied to the `.cms-preview` and are as follows:
|
different device sizes. The options are hardcoded. The option names map directly
|
||||||
|
to CSS classes applied to the `.cms-preview` and are as follows:
|
||||||
|
|
||||||
* _auto_: responsive layout
|
* _auto_: responsive layout
|
||||||
* _desktop_
|
* _desktop_
|
||||||
* _tablet_
|
* _tablet_
|
||||||
* _mobile_
|
* _mobile_
|
||||||
|
|
||||||
You can switch between different types of display sizes programmatically, which has the benefit of redrawing the
|
You can switch between different types of display sizes programmatically, which
|
||||||
related selector and maintaining a consistent internal state:
|
has the benefit of redrawing the related selector and maintaining a consistent
|
||||||
|
internal state:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
$('.cms-preview').entwine('.ss.preview').changeSize('auto');
|
$('.cms-preview').entwine('.ss.preview').changeSize('auto');
|
||||||
@ -135,25 +146,27 @@ You can find out current size by calling:
|
|||||||
|
|
||||||
## Preview modes
|
## Preview modes
|
||||||
|
|
||||||
Preview modes map to the modes supported by the _threeColumnCompressor_ layout algorithm, see
|
Preview modes map to the modes supported by the _threeColumnCompressor_ layout
|
||||||
[layout reference](../reference/layout) for more details. You can change modes by calling:
|
algorithm, see [layout reference](../reference/layout) for more details. You
|
||||||
|
can change modes by calling:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
$('.cms-preview').entwine('.ss.preview').changeMode('preview');
|
$('.cms-preview').entwine('.ss.preview').changeMode('preview');
|
||||||
```
|
```
|
||||||
|
|
||||||
Currently active mode is stored on the `.cms-container` along with related internal states of the layout. You can reach
|
Currently active mode is stored on the `.cms-container` along with related
|
||||||
it by calling:
|
internal states of the layout. You can reach it by calling:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
$('.cms-container').entwine('.ss').getLayoutOptions().mode;
|
$('.cms-container').entwine('.ss').getLayoutOptions().mode;
|
||||||
```
|
```
|
||||||
|
|
||||||
<div class="notice" markdown='1'>
|
<div class="notice" markdown='1'>
|
||||||
Caveat: the `.preview-mode-selector` appears twice, once in the preview and second time in the CMS actions area as
|
Caveat: the `.preview-mode-selector` appears twice, once in the preview and
|
||||||
`#preview-mode-dropdown-in-cms`. This is done because the user should still have access to the mode selector even if
|
second time in the CMS actions area as `#preview-mode-dropdown-in-cms`. This is
|
||||||
preview is not visible. Currently CMS Actions are a separate area to the preview option selectors, even if they try
|
done because the user should still have access to the mode selector even if
|
||||||
to appear as one horizontal bar.
|
preview is not visible. Currently CMS Actions are a separate area to the preview
|
||||||
|
option selectors, even if they try to appear as one horizontal bar.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Preview API
|
## Preview API
|
||||||
|
Loading…
Reference in New Issue
Block a user