ENHANCEMENT CMS panels restructured to use two new types of "tools" templates, fetched through LeftAndMain->Tools() and LeftAndMain->EditFormTools(). Requires less overloading of template markup.

This commit is contained in:
Ingo Schommer 2012-02-15 13:39:45 +01:00
parent 92d513857c
commit a1e9c0f41e
8 changed files with 133 additions and 76 deletions

View File

@ -476,9 +476,11 @@ class LeftAndMain extends Controller {
* Return a list of appropriate templates for this class, with the given suffix
*/
protected function getTemplatesWithSuffix($suffix) {
$templates = array();
$classes = array_reverse(ClassInfo::ancestry($this->class));
foreach($classes as $class) {
$templates[] = $class . $suffix;
$template = $class . $suffix;
if(SSViewer::hasTemplate($template)) $templates[] = $template;
if($class == 'LeftAndMain') break;
}
return $templates;
@ -1017,6 +1019,46 @@ class LeftAndMain extends Controller {
public function EditorToolbar() {
return Object::create('HtmlEditorField_Toolbar', $this, "EditorToolbar");
}
/**
* Renders a panel containing tools which apply to all displayed
* "content" (mostly through {@link EditForm()}), for example a tree navigation or a filter panel.
* Auto-detects applicable templates by naming convention: "<controller classname>_Tools.ss",
* and takes the most specific template (see {@link getTemplatesWithSuffix()}).
* To explicitly disable the panel in the subclass, simply create a more specific, empty template.
*
* @return String HTML
*/
public function Tools() {
$templates = $this->getTemplatesWithSuffix('_Tools');
if($templates) {
$viewer = new SSViewer($templates);
return $viewer->process($this);
} else {
return false;
}
}
/**
* Renders a panel containing tools which apply to the currently displayed edit form.
* The main difference to {@link Tools()} is that the panel is displayed within
* the element structure of the form panel (rendered through {@link EditForm}).
* This means the panel will be loaded alongside new forms, and refreshed upon save,
* which can mean a performance hit, depending on how complex your panel logic gets.
* Any form fields contained in the returned markup will also be submitted with the main form,
* which might be desired depending on the implementation details.
*
* @return String HTML
*/
public function EditFormTools() {
$templates = $this->getTemplatesWithSuffix('_EditFormTools');
if($templates) {
$viewer = new SSViewer($templates);
return $viewer->process($this);
} else {
return false;
}
}
/**
* Batch Actions Handler

View File

@ -37,7 +37,13 @@
var url = $(node).find('a:first').attr('href');
if(url && url != '#') {
if($(node).find('a:first').is(':internal')) url = $('base').attr('href') + url;
$('.cms-container').loadPanel(url);
// Reload only edit form if it exists (side-by-side view of tree and edit view), otherwise reload whole panel
if(self.find('.cms-edit-form').length) {
url += '?cms-view-form=1';
$('.cms-container').loadPanel(url, null, {selector: '.cms-edit-form'});
} else {
$('.cms-container').loadPanel(url);
}
} else {
self.removeForm();
}

View File

@ -95,8 +95,13 @@
redraw: function() {
// Move from inner to outer layouts. Some of the elements might not exist.
// Not all edit forms are layouted, so qualify by their data value.
this.find('.cms-edit-form[data-layout]').redraw();
this.find('.cms-preview').redraw();
// Only redraw preview if its visible
var preview = this.find('.cms-preview');
if(preview.is(':visible')) preview.redraw();
// Only redraw the content area if its not the same as the edit form
var contentEl = this.find('.cms-content');
if(!contentEl.is('.cms-edit-form')) contentEl.redraw();

View File

@ -1 +1,7 @@
$EditForm
<div class="cms-content center" data-layout="{type: 'border'}" style="display: inline-block;">
$Tools
$EditForm
</div>

View File

@ -23,44 +23,40 @@
<!-- <div class="cms-content-search">...</div> -->
</div>
</div>
<% if Tools %>
<div class="cms-content-tools west cms-panel cms-panel-layout collapsed" id="cms-content-tools" data-expandOnClick="true" data-layout="{type: 'border'}">
$Tools
</div>
<% end_if %>
<div class="center cms-panel-layout" id="center-container-here" data-layout="{type: 'border'}">
<div class="cms-content-fields center">
<% if Message %>
<p id="{$FormName}_error" class="message $MessageType">$Message</p>
<% else %>
<p id="{$FormName}_error" class="message $MessageType" style="display: none"></p>
<% end_if %>
<fieldset>
<% if Legend %><legend>$Legend</legend><% end_if %>
<% control Fields %>
$FieldHolder
<% end_control %>
<div class="clear"><!-- --></div>
</fieldset>
</div>
<% control Controller %>
$EditFormTools
<% end_control %>
<div class="cms-content-fields center">
<% if Message %>
<p id="{$FormName}_error" class="message $MessageType">$Message</p>
<% else %>
<p id="{$FormName}_error" class="message $MessageType" style="display: none"></p>
<% end_if %>
<div class="cms-content-actions south">
<% if Actions %>
<div class="Actions">
<% control Actions %>
$Field
<% end_control %>
<% if CurrentPage.PreviewLink %>
<a href="$CurrentPage.PreviewLink" class="cms-preview-toggle-link ss-ui-button">
<% _t('LeftAndMain.PreviewButton', 'Preview') %> &raquo;
</a>
<% end_if %>
</div>
<fieldset>
<% if Legend %><legend>$Legend</legend><% end_if %>
<% control Fields %>
$FieldHolder
<% end_control %>
<div class="clear"><!-- --></div>
</fieldset>
</div>
<div class="cms-content-actions south">
<% if Actions %>
<div class="Actions">
<% control Actions %>
$Field
<% end_control %>
<% if CurrentPage.PreviewLink %>
<a href="$CurrentPage.PreviewLink" class="cms-preview-toggle-link ss-ui-button">
<% _t('LeftAndMain.PreviewButton', 'Preview') %> &raquo;
</a>
<% end_if %>
</div>
<% end_if %>
</div>
<% if IncludeFormTag %>
</form>

View File

@ -6,39 +6,7 @@
</div>
</div>
<div class="cms-content-tools west cms-panel cms-panel-layout" data-expandOnClick="true" data-layout="{type: 'border'}">
<div class="cms-panel-content center">
<h3 class="cms-panel-header"><% _t('Filter', 'Filter') %></h3>
<div id="SearchForm_holder" class="leftbottom ss-tabset">
<% if SearchClassSelector = tabs %>
<ul>
<% control ModelForms %>
<li class="$FirstLast"><a id="tab-ModelAdmin_$Title.HTMLATT" href="#{$Form.Name}_$ClassName">$Title</a></li>
<% end_control %>
</ul>
<% end_if %>
<% if SearchClassSelector = dropdown %>
<div id="ModelClassSelector" class="ui-widget-container">
Search for:
<select>
<% control ModelForms %>
<option value="{$Form.Name}_$ClassName">$Title</option>
<% end_control %>
</select>
</div>
<% end_if %>
<% control ModelForms %>
<div class="tab" id="{$Form.Name}_$ClassName">
$Content
</div>
<% end_control %>
</div>
</div>
</div>
$Tools
<div class="cms-content-fields center ui-widget-content">
$EditForm

View File

@ -0,0 +1,33 @@
<div class="cms-content-tools west cms-panel cms-panel-layout" data-expandOnClick="true" data-layout="{type: 'border'}">
<div class="cms-panel-content center">
<h3 class="cms-panel-header"><% _t('Filter', 'Filter') %></h3>
<div id="SearchForm_holder" class="leftbottom ss-tabset">
<% if SearchClassSelector = tabs %>
<ul>
<% control ModelForms %>
<li class="$FirstLast"><a id="tab-ModelAdmin_$Title.HTMLATT" href="#{$Form.Name}_$ClassName">$Title</a></li>
<% end_control %>
</ul>
<% end_if %>
<% if SearchClassSelector = dropdown %>
<div id="ModelClassSelector" class="ui-widget-container">
Search for:
<select>
<% control ModelForms %>
<option value="{$Form.Name}_$ClassName">$Title</option>
<% end_control %>
</select>
</div>
<% end_if %>
<% control ModelForms %>
<div class="tab" id="{$Form.Name}_$ClassName">
$Content
</div>
<% end_control %>
</div>
</div>
</div>

View File

@ -74,11 +74,12 @@ This requires manual assignment of the template to your form instance, see `[api
Often its useful to have a "tools" panel in between the menu and your content,
usually occupied by a search form or navigational helper.
In this case, you can either overload the template as described above,
or use the special `$Tools` placeholder on `LeftAndMain->getEditForm()`.
See `CMSPageEditController->getEditForm()` for sample usage.
As the base template is aware of this placeholder, it saves you from
overloading a complex template.
In this case, you can either overload the full base template as described above.
To avoid duplicating all this template code, you can also use the special `[api:LeftAndMain->Tools()]` and
`[api:LeftAndMain->EditFormTools()]` methods available in `LeftAndMain`.
These placeholders are populated by auto-detected templates,
with the naming convention of "<controller classname>_Tools.ss" and "<controller classname>_EditFormTools.ss".
So to add or "subclass" a tools panel, simply create this file and it's automatically picked up.
## Layout and Panels