Merge branch 'master' of git://github.com/silverstripe/silverstripe-cms

This commit is contained in:
Stig Lindqvist 2012-03-07 11:14:34 +13:00
commit df859b7794
17 changed files with 413 additions and 93 deletions

View File

@ -31,17 +31,18 @@ class AssetAdmin extends LeftAndMain {
'savefile',
'deleteUnusedThumbnails' => 'ADMIN',
'SyncForm',
'filter',
);
/**
* Return fake-ID "root" if no ID is found (needed to upload files into the root-folder)
*/
public function currentPageID() {
if(isset($_REQUEST['ID']) && is_numeric($_REQUEST['ID'])) {
return $_REQUEST['ID'];
if($this->request->requestVar('ID')) {
return $this->request->requestVar('ID');
} elseif (is_numeric($this->urlParams['ID'])) {
return $this->urlParams['ID'];
} elseif(is_numeric(Session::get("{$this->class}.currentPage"))) {
} elseif(Session::get("{$this->class}.currentPage")) {
return Session::get("{$this->class}.currentPage");
} else {
return "root";
@ -58,7 +59,9 @@ class AssetAdmin extends LeftAndMain {
if(!file_exists(ASSETS_PATH)) Filesystem::makeFolder(ASSETS_PATH);
Requirements::javascript(CMS_DIR . "/javascript/AssetAdmin.js");
Requirements::css(CMS_DIR . "/css/AssetAdmin.css");
Requirements::javascript(CMS_DIR . '/javascript/CMSMain.GridField.js');
Requirements::add_i18n_javascript(CMS_DIR . '/javascript/lang', false, true);
Requirements::css(CMS_DIR . "/css/screen.css");
Requirements::customScript(<<<JS
_TREE_ICONS = {};
@ -73,12 +76,131 @@ JS
CMSBatchActionHandler::register('delete', 'AssetAdmin_DeleteBatchAction', 'Folder');
}
/**
* Returns the files and subfolders contained in the currently selected folder,
* defaulting to the root node. Doubles as search results, if any search parameters
* are set through {@link SearchForm()}.
*
* @return SS_List
*/
public function getList() {
$folder = $this->currentPage();
$context = $this->getSearchContext();
$params = $this->request->requestVar('q');
$list = $context->getResults($params);
// Always show folders at the top
$list->sort('(CASE WHEN "File"."ClassName" = \'Folder\' THEN 0 ELSE 1 END)');
// If a search is conducted, check for the "current folder" limitation.
// Otherwise limit by the current folder as denoted by the URL.
if(!$params || @$params['CurrentFolderOnly']) {
$list->filter('ParentID', $folder->ID);
}
// Category filter
if(isset($params['AppCategory'])) {
$exts = File::$app_categories[$params['AppCategory']];
$categorySQLs = array();
foreach($exts as $ext) $categorySQLs[] = '"File"."Name" LIKE \'%.' . $ext . '\'';
// TODO Use DataList->filterAny() once OR connectives are implemented properly
$list->where('(' . implode(' OR ', $categorySQLs) . ')');
}
return $list;
}
public function getEditForm($id = null, $fields = null) {
$form = parent::getEditForm($id, $fields);
$folder = ($id && is_numeric($id)) ? DataObject::get_by_id('Folder', $id, false) : $this->currentPage();
$fields = $form->Fields();
$fields->findOrMakeTab('Root.TreeView', _t('AssetAdmin.TreeView', 'Tree View'));
$fields->addFieldToTab('Root.TreeView',
$fields->push(new HiddenField('ID', false, $folder->ID));
// File listing
$gridFieldConfig = GridFieldConfig::create()->addComponents(
new GridFieldSortableHeader(),
new GridFieldDefaultColumns(),
new GridFieldPaginator(15),
new GridFieldAction_Edit(),
new GridFieldAction_Delete(),
new GridFieldPopupForms()
);
$gridField = new GridField('File','Files', $this->getList(), $gridFieldConfig);
$gridField->setDisplayFields(array(
'StripThumbnail' => '',
// 'Parent.FileName' => 'Folder',
'Title' => _t('File.Name'),
'Created' => _t('AssetAdmin.CREATED', 'Date'),
'Size' => _t('AssetAdmin.SIZE', 'Size'),
));
$gridField->setFieldCasting(array(
'Created' => 'Date->Nice'
));
$gridField->setAttribute(
'data-url-folder-template',
Controller::join_links($this->Link('show'), '%s')
);
if($folder->canCreate()) {
$uploadBtn = new LiteralField(
'UploadButton',
sprintf(
'<a class="ss-ui-button ss-ui-action-constructive cms-panel-link" data-target-panel=".cms-content" data-icon="drive-upload" href="%s">%s</a>',
Controller::join_links(singleton('CMSFileAddController')->Link(), '?ID=' . $folder->ID),
_t('Folder.UploadFilesButton', 'Upload')
)
);
} else {
$uploadBtn = null;
}
if(!$folder->hasMethod('canAddChildren') || ($folder->hasMethod('canAddChildren') && $folder->canAddChildren())) {
// TODO Will most likely be replaced by GridField logic
$addFolderBtn = new LiteralField(
'AddFolderButton',
sprintf(
'<a class="ss-ui-button ss-ui-action-constructive cms-panel-link cms-page-add-button" data-icon="add" href="%s">%s</a>',
Controller::join_links($this->Link('addfolder'), '?ParentID=' . $folder->ID),
_t('Folder.AddFolderButton', 'Add folder')
)
);
} else {
$addFolderBtn = '';
}
// Move existing fields to a "details" tab, unless they've already been tabbed out through extensions.
// Required to keep Folder->getCMSFields() simple and reuseable,
// without any dependencies into AssetAdmin (e.g. useful for "add folder" views).
if(!$fields->hasTabset()) {
$tabs = new TabSet('Root',
$tabList = new Tab('ListView', _t('AssetAdmin.ListView', 'List View')),
$tabTree = new Tab('TreeView', _t('AssetAdmin.TreeView', 'Tree View'))
);
if($fields->Count() && $folder->exists()) {
$tabs->push($tabDetails = new Tab('DetailsView', _t('AssetAdmin.DetailsView', 'Details')));
foreach($fields as $field) {
$fields->removeByName($field->Name());
$tabDetails->push($field);
}
}
$fields->push($tabs);
}
// List view
$fields->addFieldsToTab('Root.ListView', array(
$actionsComposite = Object::create('CompositeField',
Object::create('CompositeField',
$uploadBtn,
$addFolderBtn
)->addExtraClass('cms-actions-row')
)->addExtraClass('cms-content-toolbar field'),
$gridField
));
// Tree view
$fields->addFieldsToTab('Root.TreeView', array(
clone $actionsComposite,
// TODO Replace with lazy loading on client to avoid performance hit of rendering potentially unused views
new LiteralField(
'Tree',
@ -86,26 +208,119 @@ JS
'div',
array(
'class' => 'cms-tree',
'data-url' => $this->Link('getsubtree'),
'data-url-tree' => $this->Link('getsubtree'),
'data-url-savetreenode' => $this->Link('savetreenode')
),
$this->SiteTreeAsUL()
)
)
);
));
$fields->setForm($form);
$form->addExtraClass('cms-edit-form');
$form->setTemplate($this->getTemplatesWithSuffix('_EditForm'));
// TODO Can't merge $FormAttributes in template at the moment
$form->addExtraClass('center ss-tabset ' . $this->BaseCSSClasses());
if($form->Fields()->hasTabset()) $form->Fields()->findOrMakeTab('Root')->setTemplate('CMSTabSet');
$form->Fields()->findOrMakeTab('Root')->setTemplate('CMSTabSet');
$this->extend('updateEditForm', $form);
return $form;
}
public function addfolder($request) {
$obj = $this->customise(array(
'EditForm' => $this->AddForm()
));
if($this->isAjax()) {
// Rendering is handled by template, which will call EditForm() eventually
$content = $obj->renderWith($this->getTemplatesWithSuffix('_Content'));
} else {
$content = $obj->renderWith($this->getViewer('show'));
}
return $content;
}
public function getSearchContext() {
$context = singleton('File')->getDefaultSearchContext();
// Namespace fields, for easier detection if a search is present
foreach($context->getFields() as $field) $field->setName(sprintf('q[%s]', $field->getName()));
foreach($context->getFilters() as $filter) $filter->setFullName(sprintf('q[%s]', $filter->getFullName()));
// Customize fields
$appCategories = array(
'image' => _t('AssetAdmin.AppCategoryImage', 'Image'),
'audio' => _t('AssetAdmin.AppCategoryAudio', 'Audio'),
'mov' => _t('AssetAdmin.AppCategoryVideo', 'Video'),
'flash' => _t('AssetAdmin.AppCategoryFlash', 'Flash', PR_MEDIUM, 'The fileformat'),
'zip' => _t('AssetAdmin.AppCategoryArchive', 'Archive', PR_MEDIUM, 'A collection of files'),
);
$context->addField(
new DropdownField(
'q[AppCategory]',
_t('AssetAdmin.Filetype', 'File type'),
$appCategories,
null,
null,
' '
)
);
$context->addField(
new CheckboxField('q[CurrentFolderOnly]' ,_t('AssetAdmin.CurrentFolderOnly', 'Limit to current folder?'))
);
$context->getFields()->removeByName('q[Title]');
return $context;
}
/**
* Returns a form for filtering of files and assets gridfield.
* Result filtering takes place in {@link getList()}.
*
* @return Form
* @see AssetAdmin.js
*/
public function SearchForm() {
$folder = $this->currentPage();
$context = $this->getSearchContext();
$fields = $context->getSearchFields();
$actions = new FieldList(
Object::create('ResetFormAction', 'clear', _t('CMSMain_left.ss.CLEAR', 'Clear'))
->addExtraClass('ss-ui-action-minor'),
FormAction::create('doSearch', _t('CMSMain_left.ss.SEARCH', 'Search'))
);
$form = new Form($this, 'filter', $fields, $actions);
$form->setFormMethod('GET');
$form->setFormAction(Controller::join_links($this->Link('show'), $folder->ID ? $folder->ID : 'root'));
$form->addExtraClass('cms-search-form');
$form->loadDataFrom($this->request->getVars());
$form->disableSecurityToken();
// This have to match data-name attribute on the gridfield so that the javascript selectors work
$form->setAttribute('data-gridfield', 'File');
return $form;
}
public function AddForm() {
$form = parent::AddForm();
$form->Actions()->fieldByName('action_doAdd')->setTitle(_t('AssetAdmin.ActionAdd', 'Add folder'));
$folder = singleton('Folder');
$form->Actions()->fieldByName('action_doAdd')
->setTitle(_t('AssetAdmin.ActionAdd', 'Add folder'))
->setAttribute('data-icon', 'accept');
$fields = $folder->getCMSFields();
$fields->replaceField('Name', new TextField("Name", _t('File.Name')));
$fields->dataFieldByName('ParentID')->setValue($this->request->getVar('ParentID'));
$form->setFields($fields);
$form->addExtraClass('cms-edit-form');
$form->setTemplate($this->getTemplatesWithSuffix('_EditForm'));
$form->addExtraClass('center ' . $this->BaseCSSClasses());
return $form;
}
@ -133,7 +348,7 @@ JS
&& !$parentRecord->canAddChildren()
) return Security::permissionFailure($this);
}
$parent = (isset($data['ParentID']) && is_numeric($data['ParentID'])) ? (int)$data['ParentID'] : 0;
$name = (isset($data['Name'])) ? basename($data['Name']) : _t('AssetAdmin.NEWFOLDER',"NewFolder");
if(!isset($parentRecord) || !$parentRecord->ID) $parent = 0;
@ -149,7 +364,8 @@ JS
$record = new Folder();
$record->ParentID = $parent;
$record->Name = $record->Title = basename($filename);
// Ensure uniqueness
$i = 2;
$baseFilename = substr($record->Filename, 0, -1) . '-';
@ -164,10 +380,9 @@ JS
mkdir($record->FullPath);
chmod($record->FullPath, Filesystem::$file_create_mask);
// Used in TinyMCE inline folder creation
if(isset($data['returnID'])) {
return $record->ID;
} else if($this->isAjax()) {
if($this->isAjax()) {
$link = Controller::join_links($this->Link('show'), $record->ID);
$this->getResponse()->addHeader('X-ControllerURL', $link);
$form = $this->getEditForm($record->ID);
return $form->forTemplate();
} else {
@ -181,9 +396,10 @@ JS
public function currentPage() {
$id = $this->currentPageID();
if($id && is_numeric($id)) {
return DataObject::get_by_id('File', $id);
} else if($id == 'root') {
return singleton('File');
return DataObject::get_by_id('Folder', $id);
} else {
// ID is either '0' or 'root'
return singleton('Folder');
}
}
@ -318,6 +534,27 @@ JS
return array_diff($allThumbnails, $usedThumbnails);
}
/**
* @return ArrayList
*/
public function Breadcrumbs($unlinked = false) {
$items = parent::Breadcrumbs($unlinked);
// The root element should explicitly point to the root node
$items[0]->Link = Controller::join_links($this->Link('show'), 'root');
// If a search is in progress, don't show the path
if($this->request->requestVar('q')) {
$items = $items->getRange(0, 1);
$items->push(new ArrayData(array(
'Title' => _t('LeftAndMain.SearchResults', 'Search Results'),
'Link' => Controller::join_links($this->Link(), '?' . http_build_query(array('q' => $this->request->requestVar('q'))))
)));
}
return $items;
}
}
/**

View File

@ -24,19 +24,39 @@ class CMSFileAddController extends AssetAdmin {
Requirements::javascript(SAPPHIRE_DIR . '/javascript/AssetUploadField.js');
Requirements::css(SAPPHIRE_DIR . '/css/AssetUploadField.css');
$folder = $this->currentPage();
$uploadField = Object::create('UploadField', 'AssetUploadField', '');
$uploadField->setConfig('previewMaxWidth', 40);
$uploadField->setConfig('previewMaxHeight', 30);
$uploadField->addExtraClass('ss-assetuploadfield');
$uploadField->removeExtraClass('ss-uploadfield');
$uploadField->setTemplate('AssetUploadField');
if ($this->currentPage()->exists() && $this->currentPage()->getFilename()) {
$uploadField->setFolderName($this->currentPage()->getFilename());
if ($folder->exists() && $folder->getFilename()) {
// The Upload class expects a folder relative *within* assets/
$path = preg_replace('/^' . ASSETS_DIR . '\//', '', $folder->getFilename());
$uploadField->setFolderName($path);
}
$form = new Form($this, 'getEditForm', new FieldList($uploadField), new FieldList());
$form = new Form(
$this,
'getEditForm',
new FieldList($uploadField, new HiddenField('ID')),
new FieldList()
);
$form->addExtraClass('center cms-edit-form ' . $this->BaseCSSClasses());
$form->setTemplate($this->getTemplatesWithSuffix('_EditForm'));
$form->Fields()->push(
new LiteralField(
'BackLink',
sprintf(
'<a href="%s" class="backlink ss-ui-button cms-panel-link" data-icon="back">%s</a>',
Controller::join_links(singleton('AssetAdmin')->Link('show'), $folder ? $folder->ID : 0),
_t('AssetAdmin.BackToFolder', 'Back to folder')
)
)
);
$form->loadDataFrom($folder);
return $form;
}

View File

@ -58,7 +58,7 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
parent::init();
Requirements::css(CMS_DIR . '/css/CMSMain.css');
Requirements::css(CMS_DIR . '/css/screen.css');
Requirements::combine_files(
'cmsmain.js',

View File

@ -13,5 +13,14 @@ class CMSSettingsController extends CMSMain {
function PreviewLink() {
return false;
}
function Breadcrumbs() {
return new ArrayList(array(
new ArrayData(array(
'Title' => $this->SectionTitle(),
'Link' => false
))
));
}
}

View File

@ -26,7 +26,7 @@ class ReportAdmin extends LeftAndMain {
public function init() {
parent::init();
Requirements::css(CMS_DIR . '/css/ReportAdmin.css');
Requirements::css(CMS_DIR . '/css/screen.css');
// Set custom options for TinyMCE specific to ReportAdmin
HtmlEditorConfig::get('cms')->setOption('ContentCSS', project() . '/css/editor.css');

View File

@ -96,6 +96,21 @@ class VirtualPage extends Page {
function ContentSource() {
return $this->CopyContentFrom();
}
/**
* For VirtualPage, add a canonical link tag linking to the original page
* See TRAC #6828 & http://support.google.com/webmasters/bin/answer.py?hl=en&answer=139394
*
* @param boolean $includeTitle Show default <title>-tag, set to false for custom templating
* @return string The XHTML metatags
*/
public function MetaTags($includeTitle = true) {
$tags = parent::MetaTags($includeTitle);
if ($this->CopyContentFrom()->ID) {
$tags .= "<link rel=\"canonical\" href=\"{$this->CopyContentFrom()->Link()}\" />\n";
}
return $tags;
}
function allowedChildren() {
if($this->CopyContentFrom()) {

View File

@ -1,59 +0,0 @@
#ReportSelector_holder {
background-color: #EEE;
border-bottom: 1px #CCC solid;
margin: 0;
padding: 3px;
}
#right iframe.AWStatsReport {
width: 98%;
height: 85%;
}
.ReportAdmin h4 {
border-bottom: 1px #AAA solid;
margin-bottom: 0.5em;
}
.ReportAdmin .right form h4 {
font-size: 11px;
}
.ReportAdmin .filters {
overflow: auto;
}
.ReportAdmin .filters .field {
padding: 0;
}
.ReportAdmin .filters > .field {
float: left;
clear: none;
margin-right: 1em;
margin-bottom: .5em;
}
.ReportAdmin .right form .field label.left {
width: auto;
height: 15px;
}
.ReportAdmin .right form .field .middleColumn {
width: auto;
padding: 0;
}
.ReportAdmin .filters .field .middleColumn {
background: none;
}
.ReportAdmin .filters .field.checkbox {
margin-top: 18px;
padding: 0;
}
.ReportAdmin .filters .field.datetime .field.date,
.ReportAdmin .filters .field.datetime .field.time {
float: left;
}

17
css/screen.css Normal file
View File

@ -0,0 +1,17 @@
/** This file is the central collection of included modules, links to custom SCSS files, and any global SCSS variable definitions. DO NOT ADD stylesheet rules to this file directly! Note: By prefixing files with an underscore, they won't create individual CSS files. */
/** ----------------------------- Core Compass Libraries ------------------------------ */
/** ----------------------------- CMS Components ------------------------------ */
/** Style custom to the CMSMain admin interface. CMSMain extends the built in sapphire admin section styles. As much as possible we want to use those built in styles. If anything in this file can be implemented in a generic way then it should be include in the admin scss files. @package cms */
/** ------------------------------------------------------------------ Page History Section. ----------------------------------------------------------------- */
#cms-page-history-versions tr.loading { color: #999; }
#cms-page-history-versions tr.loading td:hover { cursor: none; }
#cms-page-history-versions td:hover { cursor: pointer; }
.CMSPageHistoryController ins { background-color: #DFD; padding: 2px; text-decoration: none; }
.CMSPageHistoryController del { background-color: #FDD; padding: 2px; color: #ff4444; }
.cms .AssetAdmin #Form_EditForm_File td { padding-top: 0; padding-bottom: 0; }
.cms .AssetAdmin #Form_EditForm_File td.col-StripThumbnail { padding: 0; width: 32px; height: 32px; display: block; }
.cms .AssetAdmin #Form_EditForm_File td.col-StripThumbnail img { width: 32px; height: 32px; }
.cms .AssetAdmin #Form_EditForm_File tr[data-class=Folder] td.col-StripThumbnail { background: transparent url(../../sapphire/admin/images/sprites-32x32/blue-folder-horizontal.png) no-repeat top left; }
.cms .AssetAdmin #Form_EditForm_File tr[data-class=File] td.col-StripThumbnail { background: transparent url(../../sapphire/admin/images/sprites-32x32/blue-document.png) no-repeat top left; }

View File

@ -23,7 +23,35 @@
});
$.entwine('ss', function($){
/**
* Load folder detail view via controller methods
* rather than built-in GridField view (which is only geared towards showing files).
*/
$('#Form_EditForm_File .ss-gridfield-item').entwine({
onclick: function(e) {
// Let actions do their own thing
if($(e.target).is('.action')) {
this._super(e);
return;
}
var grid = this.closest('.ss-gridfield');
if(this.data('class') == 'Folder') {
var url = grid.data('urlFolderTemplate').replace('%s', this.data('id'));
$('.cms-container').loadPanel(url);
return false;
}
}
});
$('.cms-edit-form :submit[name=action_delete]').entwine({
onclick: function(e) {
if(!confirm(ss.i18n._t('AssetAdmin.ConfirmDelete'))) return false;
else this._super(e);
}
});
/**
* Class: #Form_SyncForm
*/
@ -47,7 +75,7 @@
var currNode = $('.cms-tree')[0].firstSelected();
if(currNode) {
var url = $(currNode).find('a').attr('href');
$('.cms-content').loadForm(url);
$('.cms-content').loadForm(url);
}
$('.cms-tree')[0].setCustomURL('admin/assets/getsubtree');
$('.cms-tree')[0].reload({onSuccess: function() {

View File

@ -80,7 +80,6 @@
function() {
self.find(':submit').attr('disabled', false).removeClass('loading');
self.find('.checkboxAboveTree :checkbox').attr('disabled', 'true');
statusMessage('Filtered tree','good');
},
function() {
self.find(':submit').attr('disabled', false).removeClass('loading');

View File

@ -34,6 +34,7 @@ if(typeof(ss) == 'undefined' || typeof(ss.i18n) == 'undefined') {
'AssetTableField.MOVING': 'Moving %s file(s)',
'SecurityAdmin.BATCHACTIONSDELETECONFIRM': "Do you really want to delete %s groups?",
'CMSMAIN.AddSearchCriteria': 'Add Criteria',
'WidgetAreaEditor.TOOMANY': 'Sorry, you have reached the maximum number of widgets in this area'
'WidgetAreaEditor.TOOMANY': 'Sorry, you have reached the maximum number of widgets in this area',
'AssetAdmin.ConfirmDelete': 'Do you really want to delete this folder and all contained files?'
});
}

31
scss/_AssetAdmin.scss Normal file
View File

@ -0,0 +1,31 @@
.cms .AssetAdmin {
#Form_EditForm_File {
td {
// Taken care of by minimum image sizes
padding-top: 0;
padding-bottom: 0;
}
td.col-StripThumbnail {
padding: 0;
width: 32px;
height: 32px;
display: block;
img {
width: 32px;
height: 32px;
}
}
// TODO Figure out how to share sprites and SCSS rules between sapphire/admin/scss and cms/scss
tr[data-class=Folder] {
td.col-StripThumbnail {
background: transparent url(../../sapphire/admin/images/sprites-32x32/blue-folder-horizontal.png) no-repeat top left;
}
}
tr[data-class=File] {
td.col-StripThumbnail {
background: transparent url(../../sapphire/admin/images/sprites-32x32/blue-document.png) no-repeat top left;
}
}
}
}

22
scss/screen.scss Normal file
View File

@ -0,0 +1,22 @@
/**
* This file is the central collection of included modules, links to custom SCSS files,
* and any global SCSS variable definitions.
*
* DO NOT ADD stylesheet rules to this file directly!
*
* Note: By prefixing files with an underscore, they won't create individual CSS files.
*/
/** -----------------------------
* Core Compass Libraries
* ------------------------------ */
@import "compass/css3";
@import "compass/utilities/sprites/sprite-img";
@import "compass/utilities/general";
/** -----------------------------
* CMS Components
* ------------------------------ */
@import "CMSMain.scss";
@import "AssetAdmin.scss";
@import "ReportAdmin.scss";

View File

@ -1,7 +1,7 @@
<div class="cms-content-tools west cms-panel cms-panel-layout collapsed" id="cms-content-tools" data-expandOnClick="true" data-layout-type="border">
<div class="cms-panel-content center">
<h3 class="cms-panel-header"><% _t('FILTER', 'Filter') %></h3>
TODO
$SearchForm
</div>
<div class="cms-panel-content-collapsed">
<h3 class="cms-panel-header"><% _t('FILTER', 'Filter') %></h3>

View File

@ -9,13 +9,13 @@
<div class="cms-content-header-tabs">
<ul>
<li>
<a href="#cms-content-treeview"><% _t('CMSPagesController.TreeView', 'Tree View') %></a>
<a href="#cms-content-treeview" class="content-treeview"><% _t('CMSPagesController.TreeView', 'Tree View') %></a>
</li>
<li>
<a href="#cms-content-galleryview"><% _t('CMSPagesController.GalleryView', 'Gallery View') %></a>
<a href="#cms-content-galleryview" class="content-galleryview"><% _t('CMSPagesController.GalleryView', 'Gallery View') %></a>
</li>
<li>
<a href="#cms-content-listview"><% _t('CMSPagesController.ListView', 'List View') %></a>
<a href="#cms-content-listview" class="content-listview"><% _t('CMSPagesController.ListView', 'List View') %></a>
</li>
</ul>
</div>
@ -24,7 +24,7 @@
$Tools
<div class="cms-content-fields center ui-widget-content">
<div class="cms-content-fields center ui-widget-content cms-panel-padded">
<div id="cms-content-treeview">