mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
API: Add attributes argument for CMSMenuItem.
Currently help menu item is the only external link in the CMS and the ability for it to work is hardcoded in the template. This request makes the target attribute definable by CMSMenu::add_link(). Adds documentation for how to add a basic external link to the CMS.
This commit is contained in:
parent
e4ff3b8ec8
commit
2d0a354405
@ -1,16 +1,21 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* The object manages the main CMS menu. See {@link LeftAndMain::init()} for example usage.
|
* The object manages the main CMS menu. See {@link LeftAndMain::init()} for
|
||||||
|
* example usage.
|
||||||
*
|
*
|
||||||
* The menu will be automatically populated with menu items for subclasses of {@link LeftAndMain}.
|
* The menu will be automatically populated with menu items for subclasses of
|
||||||
* That is, for each class in the CMS that creates an administration panel, a CMS menu item will be created.
|
* {@link LeftAndMain}. That is, for each class in the CMS that creates an
|
||||||
* The default configuration will also include a 'help' link to the SilverStripe user documentation.
|
* administration panel, a CMS menu item will be created. The default
|
||||||
|
* configuration will also include a 'help' link to the SilverStripe user
|
||||||
|
* documentation.
|
||||||
*
|
*
|
||||||
* @package cms
|
* Additional CMSMenu items can be added through {@link LeftAndMainExtension::init()}
|
||||||
* @subpackage content
|
* extensions added to {@link LeftAndMain}.
|
||||||
|
*
|
||||||
|
* @package framework
|
||||||
|
* @subpackage admin
|
||||||
*/
|
*/
|
||||||
class CMSMenu extends Object implements IteratorAggregate, i18nEntityProvider
|
class CMSMenu extends Object implements IteratorAggregate, i18nEntityProvider {
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An array of changes to be made to the menu items, in the order that the changes should be
|
* An array of changes to be made to the menu items, in the order that the changes should be
|
||||||
@ -79,10 +84,12 @@ class CMSMenu extends Object implements IteratorAggregate, i18nEntityProvider
|
|||||||
* @param string $url The url of the link
|
* @param string $url The url of the link
|
||||||
* @param integer $priority The menu priority (sorting order) of the menu item. Higher priorities will be further
|
* @param integer $priority The menu priority (sorting order) of the menu item. Higher priorities will be further
|
||||||
* left.
|
* left.
|
||||||
|
* @param array $attributes an array of attributes to include on the link.
|
||||||
|
*
|
||||||
* @return boolean The result of the operation.
|
* @return boolean The result of the operation.
|
||||||
*/
|
*/
|
||||||
public static function add_link($code, $menuTitle, $url, $priority = -1) {
|
public static function add_link($code, $menuTitle, $url, $priority = -1, $attributes = null) {
|
||||||
return self::add_menu_item($code, $menuTitle, $url, null, $priority);
|
return self::add_menu_item($code, $menuTitle, $url, null, $priority, $attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -97,13 +104,17 @@ class CMSMenu extends Object implements IteratorAggregate, i18nEntityProvider
|
|||||||
* @param string $controllerClass The controller class for this menu, used to check permisssions.
|
* @param string $controllerClass The controller class for this menu, used to check permisssions.
|
||||||
* If blank, it's assumed that this is public, and always shown to users who
|
* If blank, it's assumed that this is public, and always shown to users who
|
||||||
* have the rights to access some other part of the admin area.
|
* have the rights to access some other part of the admin area.
|
||||||
|
* @param array $attributes an array of attributes to include on the link.
|
||||||
|
*
|
||||||
* @return boolean Success
|
* @return boolean Success
|
||||||
*/
|
*/
|
||||||
public static function add_menu_item($code, $menuTitle, $url, $controllerClass = null, $priority = -1) {
|
public static function add_menu_item($code, $menuTitle, $url, $controllerClass = null, $priority = -1, $attributes = null) {
|
||||||
// If a class is defined, then force the use of that as a code. This helps prevent menu item duplication
|
// If a class is defined, then force the use of that as a code. This helps prevent menu item duplication
|
||||||
if($controllerClass) $code = $controllerClass;
|
if($controllerClass) {
|
||||||
|
$code = $controllerClass;
|
||||||
|
}
|
||||||
|
|
||||||
return self::replace_menu_item($code, $menuTitle, $url, $controllerClass, $priority);
|
return self::replace_menu_item($code, $menuTitle, $url, $controllerClass, $priority, $attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -223,13 +234,21 @@ class CMSMenu extends Object implements IteratorAggregate, i18nEntityProvider
|
|||||||
* @param string $controllerClass The controller class for this menu, used to check permisssions.
|
* @param string $controllerClass The controller class for this menu, used to check permisssions.
|
||||||
* If blank, it's assumed that this is public, and always shown to users who
|
* If blank, it's assumed that this is public, and always shown to users who
|
||||||
* have the rights to access some other part of the admin area.
|
* have the rights to access some other part of the admin area.
|
||||||
|
* @param array $attributes an array of attributes to include on the link.
|
||||||
|
*
|
||||||
* @return boolean Success
|
* @return boolean Success
|
||||||
*/
|
*/
|
||||||
public static function replace_menu_item($code, $menuTitle, $url, $controllerClass = null, $priority = -1) {
|
public static function replace_menu_item($code, $menuTitle, $url, $controllerClass = null, $priority = -1, $attributes = null) {
|
||||||
|
$item = new CMSMenuItem($menuTitle, $url, $controllerClass, $priority);
|
||||||
|
|
||||||
|
if($attributes) {
|
||||||
|
$item->setAttributes($attributes);
|
||||||
|
}
|
||||||
|
|
||||||
self::$menu_item_changes[] = array(
|
self::$menu_item_changes[] = array(
|
||||||
'type' => 'add',
|
'type' => 'add',
|
||||||
'code' => $code,
|
'code' => $code,
|
||||||
'item' => new CMSMenuItem($menuTitle, $url, $controllerClass, $priority),
|
'item' => $item,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,18 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple CMS menu item
|
* A simple CMS menu item.
|
||||||
*
|
*
|
||||||
* @package cms
|
* Items can be added to the menu through custom {@link LeftAndMainExtension}
|
||||||
* @subpackage content
|
* classes and {@link CMSMenu}.
|
||||||
|
*
|
||||||
|
* @see CMSMenu
|
||||||
|
*
|
||||||
|
* @package framework
|
||||||
|
* @subpackage admin
|
||||||
*/
|
*/
|
||||||
class CMSMenuItem extends Object
|
class CMSMenuItem extends Object {
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* The (translated) menu title
|
* The (translated) menu title
|
||||||
* @var string $title
|
* @var string $title
|
||||||
@ -31,8 +37,17 @@ class CMSMenuItem extends Object
|
|||||||
*/
|
*/
|
||||||
public $priority;
|
public $priority;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attributes for the link. For instance, custom data attributes or standard
|
||||||
|
* HTML anchor properties.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $attributes = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new CMS Menu Item
|
* Create a new CMS Menu Item
|
||||||
|
*
|
||||||
* @param string $title
|
* @param string $title
|
||||||
* @param string $url
|
* @param string $url
|
||||||
* @param string $controller Controller class name
|
* @param string $controller Controller class name
|
||||||
@ -43,7 +58,41 @@ class CMSMenuItem extends Object
|
|||||||
$this->url = $url;
|
$this->url = $url;
|
||||||
$this->controller = $controller;
|
$this->controller = $controller;
|
||||||
$this->priority = $priority;
|
$this->priority = $priority;
|
||||||
|
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $attributes
|
||||||
|
*/
|
||||||
|
public function setAttributes($attributes) {
|
||||||
|
$this->attributes = $attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array
|
||||||
|
*
|
||||||
|
* @return HTML
|
||||||
|
*/
|
||||||
|
public function getAttributesHTML($attrs = null) {
|
||||||
|
$exclude = (is_string($attrs)) ? func_get_args() : null;
|
||||||
|
|
||||||
|
if(!$attrs || is_string($attrs)) {
|
||||||
|
$attrs = $this->attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove empty
|
||||||
|
$attrs = array_filter((array)$attrs, function($v) {
|
||||||
|
return ($v || $v === 0 || $v === '0');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create markkup
|
||||||
|
$parts = array();
|
||||||
|
|
||||||
|
foreach($attrs as $name => $value) {
|
||||||
|
$parts[] = ($value === true) ? "{$name}=\"{$name}\"" : "{$name}=\"" . Convert::raw2att($value) . "\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode(' ', $parts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,7 +219,10 @@ class LeftAndMain extends Controller implements PermissionProvider {
|
|||||||
'Help',
|
'Help',
|
||||||
_t('LeftAndMain.HELP', 'Help', 'Menu title'),
|
_t('LeftAndMain.HELP', 'Help', 'Menu title'),
|
||||||
$this->config()->help_link,
|
$this->config()->help_link,
|
||||||
-2
|
-2,
|
||||||
|
array(
|
||||||
|
'target' => '_blank'
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Allow customisation of the access check by a extension
|
// Allow customisation of the access check by a extension
|
||||||
@ -616,6 +619,7 @@ class LeftAndMain extends Controller implements PermissionProvider {
|
|||||||
if($menuItems) {
|
if($menuItems) {
|
||||||
foreach($menuItems as $code => $menuItem) {
|
foreach($menuItems as $code => $menuItem) {
|
||||||
// alternate permission checks (in addition to LeftAndMain->canView())
|
// alternate permission checks (in addition to LeftAndMain->canView())
|
||||||
|
|
||||||
if(
|
if(
|
||||||
isset($menuItem->controller)
|
isset($menuItem->controller)
|
||||||
&& $this->hasMethod('alternateMenuDisplayCheck')
|
&& $this->hasMethod('alternateMenuDisplayCheck')
|
||||||
@ -664,6 +668,7 @@ class LeftAndMain extends Controller implements PermissionProvider {
|
|||||||
|
|
||||||
$menu->push(new ArrayData(array(
|
$menu->push(new ArrayData(array(
|
||||||
"MenuItem" => $menuItem,
|
"MenuItem" => $menuItem,
|
||||||
|
"AttributesHTML" => $menuItem->getAttributesHTML(),
|
||||||
"Title" => Convert::raw2xml($title),
|
"Title" => Convert::raw2xml($title),
|
||||||
"Code" => DBField::create_field('Text', $code),
|
"Code" => DBField::create_field('Text', $code),
|
||||||
"Link" => $menuItem->url,
|
"Link" => $menuItem->url,
|
||||||
|
@ -230,6 +230,13 @@
|
|||||||
// Ignore external links, fallback to standard link behaviour
|
// Ignore external links, fallback to standard link behaviour
|
||||||
var isExternal = $.path.isExternal(this.attr('href'));
|
var isExternal = $.path.isExternal(this.attr('href'));
|
||||||
if(e.which > 1 || isExternal) return;
|
if(e.which > 1 || isExternal) return;
|
||||||
|
|
||||||
|
// if the developer has this to open in a new window, handle
|
||||||
|
// that
|
||||||
|
if(this.attr('target') == "_blank") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
var item = this.getMenuItem();
|
var item = this.getMenuItem();
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
<ul class="cms-menu-list">
|
<ul class="cms-menu-list">
|
||||||
<% loop $MainMenu %>
|
<% loop $MainMenu %>
|
||||||
<li class="$LinkingMode $FirstLast <% if $LinkingMode == 'link' %><% else %>opened<% end_if %>" id="Menu-$Code" title="$Title.ATT">
|
<li class="$LinkingMode $FirstLast <% if $LinkingMode == 'link' %><% else %>opened<% end_if %>" id="Menu-$Code" title="$Title.ATT">
|
||||||
<a href="$Link" <% if $Code == 'Help' %>target="_blank"<% end_if%>>
|
<a href="$Link" $AttributesHTML>
|
||||||
<span class="icon icon-16 icon-{$Code.LowerCase}"> </span>
|
<span class="icon icon-16 icon-{$Code.LowerCase}"> </span>
|
||||||
<span class="text">$Title</span>
|
<span class="text">$Title</span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @package cms
|
* @package framework
|
||||||
* @subpackage tests
|
* @subpackage tests
|
||||||
*/
|
*/
|
||||||
class CMSMenuTest extends SapphireTest implements TestOnly {
|
class CMSMenuTest extends SapphireTest implements TestOnly {
|
||||||
@ -35,7 +35,21 @@ class CMSMenuTest extends SapphireTest implements TestOnly {
|
|||||||
$this->assertNull($menuItem->controller, 'Link menu item has no controller class');
|
$this->assertNull($menuItem->controller, 'Link menu item has no controller class');
|
||||||
$this->assertEquals($menuItem->priority, -1, 'Link menu item has the correct priority');
|
$this->assertEquals($menuItem->priority, -1, 'Link menu item has the correct priority');
|
||||||
CMSMenu::clear_menu();
|
CMSMenu::clear_menu();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLinkWithExternalAttributes() {
|
||||||
|
CMSMenu::clear_menu();
|
||||||
|
|
||||||
|
CMSMenu::add_link('LinkCode', 'link title', 'http://www.example.com', -2, array(
|
||||||
|
'target' => '_blank'
|
||||||
|
));
|
||||||
|
|
||||||
|
$menuItems = CMSMenu::get_menu_items();
|
||||||
|
$menuItem = $menuItems['LinkCode'];
|
||||||
|
|
||||||
|
$this->assertEquals('target="_blank"', $menuItem->getAttributesHTML());
|
||||||
|
|
||||||
|
CMSMenu::clear_menu();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCmsClassDetection() {
|
public function testCmsClassDetection() {
|
||||||
@ -81,8 +95,15 @@ class CMSMenuTest extends SapphireTest implements TestOnly {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package framework
|
||||||
|
* @subpackage tests
|
||||||
|
*/
|
||||||
class CMSMenuTest_LeftAndMainController extends LeftAndMain implements TestOnly {
|
class CMSMenuTest_LeftAndMainController extends LeftAndMain implements TestOnly {
|
||||||
|
|
||||||
private static $url_segment = 'CMSMenuTest_LeftAndMainController';
|
private static $url_segment = 'CMSMenuTest_LeftAndMainController';
|
||||||
|
|
||||||
private static $menu_title = 'CMSMenuTest_LeftAndMainController';
|
private static $menu_title = 'CMSMenuTest_LeftAndMainController';
|
||||||
|
|
||||||
private static $menu_priority = 50;
|
private static $menu_priority = 50;
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,24 @@
|
|||||||
# How to customize the CMS Menu #
|
# How to customize the CMS Menu
|
||||||
|
|
||||||
## Defining a Custom Icon ##
|
## Adding a administration panel
|
||||||
|
|
||||||
Every time you add a new extension of the `api:LeftAndMain` class to the CMS, SilverStripe will automatically create a new menu-item for it, with a default title and icon.
|
Every time you add a new extension of the `[api:LeftAndMain]` class to the CMS,
|
||||||
We can easily change that behaviour by using the static `$menu_title` and `$menu_icon` statics to
|
SilverStripe will automatically create a new `[api:CMSMenuItem]` for it
|
||||||
|
|
||||||
|
The most popular extension of LeftAndMain is a `[api:ModelAdmin]` class, so
|
||||||
|
for a more detailed introduction to creating new `ModelAdmin` interfaces, read
|
||||||
|
the [ModelAdmin referencee](../reference/modeladmin).
|
||||||
|
|
||||||
|
In this document we'll take the `ProductAdmin` class used in the
|
||||||
|
[ModelAdmin referencee](../reference/modeladmin#setup) and so how we can change
|
||||||
|
the menu behaviour by using the static `$menu_title` and `$menu_icon` statics to
|
||||||
provide a custom title and icon.
|
provide a custom title and icon.
|
||||||
|
|
||||||
The most popular extension of LeftAndMain is the `api:ModelAdmin` class, so we'll use that for an example.
|
### Defining a Custom Icon
|
||||||
We'll take the `ProductAdmin` class used in the [ModelAdmin reference](../reference/modeladmin#setup).
|
|
||||||
|
|
||||||
First we'll need a custom icon. For this purpose SilverStripe uses 16x16 black-and-transparent PNG graphics.
|
First we'll need a custom icon. For this purpose SilverStripe uses 16x16
|
||||||
In this case we'll place the icon in `mysite/images`, but you are free to use any location.
|
black-and-transparent PNG graphics. In this case we'll place the icon in
|
||||||
|
`mysite/images`, but you are free to use any location.
|
||||||
|
|
||||||
:::php
|
:::php
|
||||||
class ProductAdmin extends ModelAdmin {
|
class ProductAdmin extends ModelAdmin {
|
||||||
@ -18,11 +26,11 @@ In this case we'll place the icon in `mysite/images`, but you are free to use an
|
|||||||
private static $menu_icon = 'mysite/images/product-icon.png';
|
private static $menu_icon = 'mysite/images/product-icon.png';
|
||||||
}
|
}
|
||||||
|
|
||||||
## Defining a Custom Title ##
|
### Defining a Custom Title
|
||||||
|
|
||||||
The title of menu entries is configured through the `$menu_title` static.
|
The title of menu entries is configured through the `$menu_title` static.
|
||||||
If its not defined, the CMS falls back to using the class name of the controller,
|
If its not defined, the CMS falls back to using the class name of the
|
||||||
removing the "Admin" bit at the end.
|
controller, removing the "Admin" bit at the end.
|
||||||
|
|
||||||
:::php
|
:::php
|
||||||
class ProductAdmin extends ModelAdmin {
|
class ProductAdmin extends ModelAdmin {
|
||||||
@ -30,9 +38,58 @@ removing the "Admin" bit at the end.
|
|||||||
private static $menu_title = 'My Custom Admin';
|
private static $menu_title = 'My Custom Admin';
|
||||||
}
|
}
|
||||||
|
|
||||||
In order to localize the menu title in different languages, use the `<classname>.MENUTITLE`
|
In order to localize the menu title in different languages, use the
|
||||||
entity name, which is automatically created when running the i18n text collection.
|
`<classname>.MENUTITLE` entity name, which is automatically created when running
|
||||||
For more information on language and translations, please refer to the [i18n](../reference/ii8n) docs.
|
the i18n text collection.
|
||||||
|
|
||||||
|
For more information on language and translations, please refer to the
|
||||||
|
[i18n](../reference/ii8n) docs.
|
||||||
|
|
||||||
|
## Adding an external link to the menu
|
||||||
|
|
||||||
|
On top of your administration windows, the menu can also have external links
|
||||||
|
(e.g to external reference). In this example, we're going to add a link to
|
||||||
|
Google to the menu.
|
||||||
|
|
||||||
|
First, we need to define a `[api:LeftAndMainExtension]` which will contain our
|
||||||
|
button configuration.
|
||||||
|
|
||||||
|
:::php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class CustomLeftAndMain extends LeftAndMainExtension {
|
||||||
|
|
||||||
|
public function init() {
|
||||||
|
// unique identifier for this item. Will have an ID of Menu-$ID
|
||||||
|
$id = 'LinkToGoogle';
|
||||||
|
|
||||||
|
// your 'nice' title
|
||||||
|
$title = 'Google';
|
||||||
|
|
||||||
|
// the link you want to item to go to
|
||||||
|
$link = 'http://google.com';
|
||||||
|
|
||||||
|
// priority controls the ordering of the link in the stack. The
|
||||||
|
// lower the number, the lower in the list
|
||||||
|
$priority = -2;
|
||||||
|
|
||||||
|
// Add your own attributes onto the link. In our case, we want to
|
||||||
|
// open the link in a new window (not the original)
|
||||||
|
$attributes = array(
|
||||||
|
'target' => '_blank'
|
||||||
|
);
|
||||||
|
|
||||||
|
CMSMenu::add_link($id, $title, $link, $priority, $attributes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
To have the link appear, make sure you add the extension to the `LeftAndMain`
|
||||||
|
class. For more information about configuring extensions see the
|
||||||
|
[DataExtension referencee](../reference/dataextension).
|
||||||
|
|
||||||
|
:::php
|
||||||
|
LeftAndMain::add_extension('CustomLeftAndMain')
|
||||||
|
|
||||||
|
|
||||||
## Related
|
## Related
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user