Doc cleanup (spelling, line length, grammar)

This commit is contained in:
Will Rossiter 2013-06-02 13:38:10 +12:00
parent db85f3ca16
commit e1b1fce31f
2 changed files with 125 additions and 83 deletions

View File

@ -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.

View File

@ -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