Upload
cmsmssjg
View
18.713
Download
2
Embed Size (px)
DESCRIPTION
How to add functionality to CMS Made Simple using Tags, User-Defined Tags, and Modules. Also includes some previews of how the module API will change with version 2.0
Citation preview
Extending CMS Made SimplePresented by
Jeff Bosch and Samuel Goldstein
Jeff Bosch
● Core Development Team member● B.S. in Computer Science● Started A & J Progamming in 2007 for
custom web programming and implementation
Samuel Goldstein
● Core Development Team member since 2004
● Principal at 1969 Communications
● Background● Programming since 1980, starting with TRS-80● Aerospace in the '90s● Dot-com roller coaster
● Hey! Buy my book!● CMS Made Simple Developer's Cookbook from Packt Publishing
OK, enough of that
● Why extend CMS Made Simple?● Add functionality● Make things easier for your clients● More money for you● Fame, fortune, glory
Ways to Extend CMSMS
● Core, core modules, and Smarty● User-Defined Tags● Tags (a.k.a. Plugins)● Modules
How do I decide on an approach?
● There is not always an “absolute best” approach
● Don't neglect non-technical considerations (e.g., your specific users)
● The following chart may also help
Approaches
Smarty Tag UDT Module
No installation required √ √
Multiple actions √* √
Create databases / preferences √* √
Act as Smarty modifier √
Help displayed in Admin area √ √
Admin panel √
Post on Developer's Forge, share via Module Manager
√
Localization/Translation √
Let's get started!
● Build a Google Site Map using Core and Core Modules● We'll use Menu Manager in a hidden page● We'll create a custom Menu Manager
template● And a mod_rewrite trick
Menu Manager Template
<?xml version="1.0" encoding="UTF-‐8"?><urlset xmlns="hRp://www.sitemaps.org/schemas/sitemap/0.9">{if $count > 0}{foreach from=$nodelist item=node} <url> <loc>{$node-‐>url|escape:'html'}</loc> <lastmod>{$node-‐>modified|date_format:'%Y-‐%m-‐%dT%T-‐08:00'}</lastmod> </url>{/foreach}{/if}</urlset>
Calling the Template
● Create page named “sitemap”● Set alias to “sitemap” too● Uncheck “Show in Menu”● Insert tag into your page content:{menu template='sitemap' show_all='1' collapse='0'}
<IfModule mod_rewrite.c>RewriteEngine on#Sub-‐dir e.g: /cmsmsRewriteBase /RewriteCond %{REQUEST_FILENAME} !-‐f [NC]RewriteCond %{REQUEST_FILENAME} !-‐d [NC]RewriteRule ^sitemap.xml$ index.php?page=sitemap&showtemplate=false [L]</IfModule>
Add an .htaccess file
Test it!
● Go to http://yoursite.com/sitemap.xml<?xml version="1.0" encoding="UTF-‐8"?><urlset xmlns="hRp://www.sitemaps.org/schemas/sitemap/0.9"> <url> <loc>hRp://cms_book.viajante/</loc> <lastmod>2009-‐05-‐13T10:12:18-‐08:00</lastmod> </url> <url> <loc>hRp://cms_book.viajante/index.php?page=how-‐cmsms-‐works</loc> <lastmod>2009-‐05-‐12T20:11:52-‐08:00</lastmod> </url> …</urlset>
OK, how about a Tag?
● Only tags can serve as Smarty modifiers● Here's a tag that vigorously defends our
intellectual property!● Appends a ® symbol to every instance of
“CMS Made Simple” in page content.
postfilter.registeredtrademarker.php
<?phpfuncQon smarty_cms_posPilter_registeredtrademarker($tpl_output, &$smarty){
global $gCms;$result = explode(':', $smarty-‐>_current_file);
if (count($result) > 0){
if ($result[0] == 'content'){$tpl_output = str_replace('CMS Made Simple','CMS Made Simple®', $tpl_output);}
}return $tpl_output;
}?>
Using the Filter
● Save your filter in the plugins directory● In the Admin, be sure to clear your
cache!● View your site.
You® filte®ed ®esults
OK, how about a UDT?
● UDTs can do all sorts of things:● Talk to the database● Talk to modules● Deal with events● Interact with Smarty
● Let's try a few of those things!
UDT “pagecounter”
global $gCms;
$db = $gCms-‐>GetDb();
$count = $db-‐>GetOne('select count(*) from '.cms_db_prefix().'content where acQve=1');
$smarty = $gCms-‐>GetSmarty();$smarty-‐>assign('page_count','Total pages: '.$count);
Then, add a content page
● Set the title and menu text● In the content, call the UDT with{pagecounter}
● And output the Smarty variable with{$page_count}
Viewing your page
Exercise I
● What approach would you use to implement each of the following?● Convert your page content into Pirate Speak● A form for users to submit movie reviews, with an
Admin panel allowing the site maintainer to approve or reject reviews for display
● Putting the title of the most-recently added page into a Smarty variable
Exercise I, cont.
● Display a special image file only on the site's home page
● Display the Admin account email address on a page (but obscured to prevent spammers from harvesting it)
● Display a poll, and show the results after the user votes
● Display links to all pages that are below the current page in the site hierarchy
Exercise II
● Create a UDT for changing site layout seasonally.● Set a variable which can be used to change
the stylesheet classes of the site.● For simplicity, call January-March “winter,”
April-June “spring,” July-September “summer,” and October-December “autumn.”
Exercise II, cont. UDTglobal $gCms;
$month = date('n'); // returns month as number between 1 and 12, inclusive$smarty = $gCms-‐>GetSmarty();
if ($month < 4)$season = 'winter';
else if ($month < 7)$season = 'spring';
else if ($month < 10)$season = 'summer';
else$season = 'autumn';
$smarty-‐>assign('season', $season);
Exercise II, cont. Template.{process_pagedata}<!DOCTYPE html PUBLIC "-‐//W3C//DTD XHTML 1.0 TransiQonal//EN" "hRp://www.w3.org/TR/xhtml1/DTD/xhtml1-‐transiQonal.dtd"><html xmlns="hRp://www.w3.org/1999/xhtml" xml:lang="en" ><head><Qtle>{sitename} -‐ {Qtle}</Qtle>{metadata}{cms_stylesheet}{season}</head><body><div id="header"><h1 class=”{$season}”>{sitename}</h1></div><div id="menu">{menu}</div><div id="content" class=”{$season}”> <h1>{Qtle}</h1> {content}</div></body></html>
Exercise II, cont. CSS
.winter {background-‐color: #bfc4ff;}
.spring {background-‐color: #bfffce;}
.summer {background-‐color: #fffabf;}
.autumn {background-‐color: #ffcabf;}
#header h1.summer {background: url(/uploads/images/beach.jpg);}
Hour IIHow's my timing?
Getting Started with Modules
● For the 1.x series, several ways to get started● From scratch● Skeleton module● Module Maker● MCFactory● etc
Skeleton Module
● Download from Forge or Module Manager
● Has simple functionality● install/upgrade● admin panel● database routines● form API calls
Skeleton Module, cont.
● Once you've installed, edit the files to adapt to your own purposes
● Well commented● Somewhat dated: last updated for CMS
MS 1.6.5● Still has correct structure, but may lack
more recent improvements and features
Structure of a 1.x module
● Modules extend the CMSModule class● Magic of OO:
● Automatically inherits a lot of functionality (e.g., Database and Form APIs, Smarty, Translation, etc)
● Most methods already inherit acceptable defaults
Minimal 1.x Module
● File lives in $CMS_ROOT/modules/module_name
● Filename is module_name.module.php● Module class must match file name● Need to implement 3 methods:
● GetName● DoAction● IsPluginModule
Minimal 1.x module, cont.
● GetName simply returns module name; must match class and filename
● IsPluginModule returns boolean.● DoAction is, unsurprisingly, where the
real action takes place
DoAction
● Called with a few parameters:● $action, “reason for calling.” Two built-in:
“default” and “defaultadmin”● $id, a prefix for use in forms● $params, a hash of parameters● $returnid, reference to the page containing
the tag
Other important methods
● Install, upgrade, uninstall. These methods called as expected, and allow for housekeeping
● SetParameters. Sets up parameter filtering, URL routes,
● Lang. Translates strings.
Minimal 1.x module, cont.
● For performance reasons, methods are split out into multiple files
● String translations are stored in external files
● Templates may be stored as files or in the database
Layout on filesystem
Enough Abstraction!
● We will create a basic module that demonstrates core APIs
● “Quotations Module” requirements:● Presents form to user, handles input safely● Displays random quotation to user● Allows admin to delete records
Step 1. Preparation
● Create directories● $CMS_ROOT/modules/Quotations● Quotations/templates● Quotations/lang
● Create base files:● Quotations.module.php● lang/en_US.php
Quotations.module.php<?phpclass QuotaQons extends CMSModule
{funcQon GetName()
{return 'QuotaQons';}
funcQon GetFriendlyName(){return $this-‐>Lang('friendlyname');}
funcQon IsPluginModule(){return true;}
funcQon GetVersion(){return '0.1';}
}?>
lang/en_US.php<?php$lang['friendlyname']='QuotaQon Module';?>
Database Schema
● We'll probably need● Unique ID● Quotation text● Quotation author● Submission date
method.install.php<?phpif (!isset($gCms)) exit;
$db = $this-‐>GetDb();$dict = NewDataDicQonary( $db );
$fields="quotaQon_id I KEY,quotaQon X,author C(80),submit_date DT
";
$sqlarray = $dict-‐>CreateTableSQL( cms_db_prefix()."module_quotaQons",$fields);$dict-‐>ExecuteSQLArray($sqlarray);
$db-‐>CreateSequence(cms_db_prefix()."module_quotaQon_seq");?>
Install it
Consider parameters
● Form will submit quotation and author● Viewing will require quotation_id● Module will also be a plugin module, so
we want to give it its own tag {quotation}● Let's create SetParameters method
SetParameters()funcQon SetParameters()
{$this-‐>RegisterModulePlugin();$this-‐>RestrictUnknownParams();$this-‐>CreateParameter('quotaQon_id','null',$this-‐>Lang('help_quotaQon_id'));$this-‐>SetParameterType('quotaQon_id', CLEAN_INT);$this-‐>CreateParameter('author','anonymous',$this-‐>Lang('help_author'));$this-‐>SetParameterType('author',CLEAN_STRING);$this-‐>CreateParameter('quotaQon','',$this-‐>Lang('help_quotaQon'));$this-‐>SetParameterType('quotaQon',CLEAN_STRING);$this-‐>CreateParameter('submit');$this-‐>SetParameterType('submit',CLEAN_STRING);}
funcQon GetHelp(){return $this-‐>Lang('help');}
Viewing Module Help
OK, let's get serious.
● Need to create the form● Need to handle the inputs● This will be the module's default action● Create action.default.php
action.default.php<?phpif (!isset($gCms)) exit;
$smarty-‐>assign('form_start',$this-‐>CreateFormStart($id, 'default', $returnid));
$smarty-‐>assign('input_author',$this-‐>CreateInputTextWithLabel($id, 'author',isset($params['author'])?$params['author']:'', 10, 80, '',$this-‐>Lang('Qtle_author')));
$smarty-‐>assign('Qtle_quotaQon',$this-‐>Lang('Qtle_quotaQon'));
$smarty-‐>assign('input_quotaQon',$this-‐>CreateTextArea(false, $id,isset($params['quotaQon'])?html_enQty_decode($params['quotaQon'],ENT_QUOTES):'',
'quotaQon'));
$smarty-‐>assign('submit',$this-‐>CreateInputSubmit($id, 'submit', $this-‐>Lang('submit')));
echo $this-‐>ProcessTemplate('user_form.tpl');?>
user_form.tpl<div class="quotaQon_form">
{$form_start}<div>{$input_author}</div><div>{$Qtle_quotaQon}<br />{$input_quotaQon}</div><div>{$submit}</div></form>
</div>
Add the tag to a page
View the page
Update our lang file
<?php$lang['friendlyname']='QuotaQon Module';
$lang['Qtle_author']='QuotaQon Author';$lang['Qtle_quotaQon']='QuotaQon';$lang['submit']='Submit';
$lang['help_quotaQon_id']='ID for a specific quotaQon';$lang['help_author']='QuotaQon author';$lang['help_quotaQon']='QuotaQon text';$lang['help']='This module is for the presentaQon of quotaQons.';?>
And check again
Input validation
if (isset($params['submit'])){if (empty($params['author']) || empty($params['quotaQon']))
{$smarty-‐>assign('message',$this-‐>Lang('error_empty_fields'));}
}
Added to top of action.default.php
Added to user_form.tpl
{if isset($message) && $message!=''}<div class="error">{$message}</div>{/if}
Try an empty submit
Store to databaseif (isset($params['submit']))
{if (empty($params['author']) || empty($params['quotaQon']))
{$smarty-‐>assign('message',$this-‐>Lang('error_empty_fi elds'));}
else{$db = $this-‐>GetDb();$quotaQon_id = $db-‐>GenID(cms_db_prefix(). 'module_quotaQon_seq');$res = $db-‐>Execute('insert into '.cms_db_prefi x().
'module_quotaQons (quotaQon_id,author,quotaQon,submiRed_date) values (?,?,?,NOW())',array($quotaQon_id,$params['author'],$params['quotaQon']));
if ($res === false){$smarty-‐>assign('message',$this-‐>Lang('db_error',$db-‐>ErrorMsg()));}
else{$smarty-‐>assign('message',$this-‐>Lang('added'));}
}}
Test it – add a quotation
action.display.php<?phpif (!isset($gCms)) exit;
$db=$this-‐>GetDb();$row = array();$res = $db-‐>Execute('select * from '.cms_db_prefix().
'module_quotaQons order by rand() limit 1');
if ($res && $row=$res-‐>FetchRow()){$smarty-‐>assign('quotaQon',$row);}
echo $this-‐>ProcessTemplate('display_quotaQon.tpl');?>
display_quotation.tpl<dl>
<dd>{$quotaQon.quotaQon}</dd><dt>{$quotaQon.author}</dt>
</dl>
Add the tag to page template
● Find a convenient spot● Add the tag:{QuotaQons acQon='display'}
Try it!
2.0 Module API2.0 Module Extensions:
Database:create_table($table, $fields)create_index($table, $name, $field)drop_table($table)
Preference: get($preference_name, $default_value = '')set($preference_name, $value)remove($preference_name = '')
Template: get_list($template_type = '')get($template_type, $template_name)get_from_file($template_name)set($template_type, $template_name, $content, $default = null)delete($template_type = '', $template_name = '')process_from_data( $data )process_from_database($template_type, $template_name = '', $id = '', $return_id = '',
$designaQon = '', $cache_id = '')process($template_name, $id = '', $return_id = '', $designaQon = '', $cache_id = '')
method.install.php<?phpif (!isset($gCms)) exit;
$this-‐>Database-‐>create_table('module_quotaQons', "quotaQon_id I KEY AUTO,language C(8),quotaQon X,author C(80),submiRer C(80),submit_date DT
");
$this-‐>Database-‐>create_index('module_quotaQons','Author', 'author');
$this-‐>Template-‐>set('summary', 'Default Template', $this-‐>Template-‐>get_from_file('orig_default_summary'));
$this-‐>Preference-‐>set('sort_by','author');
$this-‐>Permission-‐>create('Manage QuotaQons' );
?>
2.0 Module API2.0 Module Extensions (Group 2)
Permission:create($permission_name, $extra_attr = '', $hierarchical = false, $table = '')check($permission_name, $extra_attr = '', $hierarchical = false, $table = '')remove($permission_name, $extra_attr = '')
Form:form_start($params = array(), $check_keys = false)form_end input_text input_hidden input_checkbox input_submitinput_select input_options input_textarea
Redirect:module_url
Url:link content_linkreturn_link
action.default.php<?phpif (!isset($gCms)) exit;
$smarty-‐>assign('form_start',$this-‐>Form-‐>form_start(array('acQon'=>'default','return_id'=>$returnid)) );
$smarty-‐>assign('input_author',$this-‐>Form-‐>input_text(array('id'=>$id,'name'=> 'author','value'=>
isset($params['author'])?$params['author']:'', 'size'=>10,'maxlength=>80, 'lable'=>'Qtle_author')) );
$smarty-‐>assign('Qtle_quotaQon',$this-‐>Lang('Qtle_quotaQon'));
$smarty-‐>assign('submit',$this-‐>Form-‐>input_submit('name'=> 'submit', 'value'=>'submit')));
echo $this-‐>Template-‐>process_from_database('summary');?>
2.0 Smarty Tags{has_permission perm="Modify Templates"}{/has_permission}
{tabs}{tab_content name='users'}
{tab_header name='users'}{/tab_header}
{/tab_content}{/tabs}
{tr}users{/tr}
2.0 Module Smarty TagsBlocks:{mod_form}{/mod_form}{mod_formrow}{/mod_formrow}{mod_label}{/mod_label}{mod_select}{/mod_select}
FuncQons:{mod_checkbox}{mod_dropdown}{mod_helptext}{mod_hidden}{mod_lang}{mod_link}{mod_opQons}{mod_password}{mod_submit}{mod_template}{mod_textarea}{mod_textbox}{mod_validaQon_errors}
2.0 Module Form{mod_validaQon_errors for=$blog_post}
{mod_form acQon=$form_acQon}{mod_label name="blog_post[Qtle]"}Title{/mod_label}:<br />{mod_textbox name="blog_post[Qtle]" value=$blog_post-‐>Qtle size="40"}{mod_label name="blog_post[content]"}Post{/mod_label}:<br />{mod_textarea name="blog_post[content]" value=$blog_post-‐>content cols="40"
rows="10" wysiwyg=true}<legend>{tr}Categories{/tr}</legend>{foreach from=$categories item='one_category'}
{assign var=category_id value=$one_category-‐>id}{assign var=category_name value=$one_category-‐>name}{mod_checkbox name="blog_post[category][$category_id]"
selected=$blog_post-‐>in_category($category_id)} {$category_name}<br />{/foreach}
{mod_label name="blog_post[status]"}{tr}Status{/tr}{/mod_label}:<br />{mod_dropdown name="blog_post[status]" items=$cms_mapi_module-‐>get_statuses()
selected_value=$blog_post-‐>status}
2.0 Module Form (Part 2){mod_label name='post_date_Month'}{tr}Post Date{/tr}{/mod_label}:<br />{html_select_date prefix=$post_date_prefix Qme=$blog_post-‐>post_date-‐
>Qmestamp() start_year=2000 end_year=2020} {html_select_Qme prefix=$post_date_prefix Qme=$blog_post-‐>post_date-‐>Qmestamp()}
{mod_hidden name="blog_post[author_id]" value=$blog_post-‐>author_id}{mod_submit name="submitpost" value='Submit' translate=true} {if $blog_post-‐>id gt 0}
{mod_hidden name="blog_post_id" value=$blog_post-‐>id}{mod_submit name="cancelpost" value='Cancel' translate=true}
{/if}{mod_submit name="submitpublish" value='Publish' translate=true}
{/mod_form}
OK, let's add an admin panel
● First, we need to add a permission to control access
● This should be done in the installer● Steps:
● Change installer● Bump the module version number● Create the upgrade method
method.install.php<?phpif (!isset($gCms)) exit;$db = $this-‐>GetDb();$dict = NewDataDicQonary( $db );
$fields="quotaQon_id I KEY,language C(8),quotaQon X,author C(80),submiRer C(80),submit_date DT
";
$sqlarray = $dict-‐>CreateTableSQL( cms_db_prefix()."module_quotaQons",$fields);$dict-‐>ExecuteSQLArray($sqlarray);
$db-‐>CreateSequence(cms_db_prefix()."module_quotaQon_seq");$this-‐>CreatePermission('Manage QuotaQons', 'Manage QuotaQons');?>
method.upgrade.php<?phpif (!isset($gCms)) exit;
switch($old_version){case "0.1":
$this-‐>CreatePermission('Manage QuotaQons', 'Manage QuotaQons');}
$this-‐>Audit( 0, $this-‐>Lang('friendlyname'), $this-‐>Lang('upgraded',$this-‐>GetVersion()));?>
Added to lang file:
$lang['upgraded']='Upgraded to version %s';
Perform the upgrade
Now implement admin panel 1.x
● Add method to main module:
function HasAdmin(){return ($this->CheckPermission('Manage Quotations'));}
action.defaultadmin.php<?phpif (!isset($gCms)) exit;if (!$this-‐>CheckPermission('Manage QuotaQons')) exit;
$db=$this-‐>GetDb();$rows = array();$res = $db-‐>Execute('select * from '.cms_db_prefix().'module_quotaQons order by submit_date desc');while ($res && $row=$res-‐>FetchRow())
{$row['edit'] = $this-‐>CreateLink($id, 'admin_edit', '',
$this-‐>Lang('edit'), array('quotaQon_id'=>$row['quotaQon_id']));$row['delete'] = $this-‐>CreateLink($id, 'admin_delete', '',
$this-‐>Lang('delete'), array('quotaQon_id'=>$row['quotaQon_id']));array_push($rows,$row);}
$smarty-‐>assign('quotaQons',$rows);echo $this-‐>ProcessTemplate('admin_display_list.tpl');?>
admin_display_list.tpl{if isset($message) && $message!=''}<div class="pagewarning">{$message}</div>{/if}<table>{foreach from=$quotaQons item=q}
<tr><td>{$q.quotaQon_id}</td><td>{$q.quotaQon|truncate:80}</td><td>{$q.author}</td><td>{$q.edit}</td><td>{$q.delete}</td>
</tr>{/foreach}</table>
Admin View
action.admin_delete.php<?phpif (!isset($gCms)) exit;if (!$this-‐>CheckPermission('Manage QuotaQons')) exit;
if (isset($params['quotaQon_id'])){$db = $this-‐>GetDb();$res = $db-‐>Execute('delete from '.cms_db_prefix().
'module_quotaQons where quotaQon_id=?',array($params['quotaQon_id']));
$smarty-‐>assign('message',$this-‐>Lang('quotaQon_deleted'));}
echo $this-‐>DoAcQon('defaultadmin', $id, $params, $returnid);?>
Delete Quotation
Be kind to users
● Add some safety – modify default admin link to delete
● And add to language file$lang['really_delete']='Really delete this quotaQon by %s?';
$row['delete'] = $this-‐>CreateLink($id, 'admin_delete', '',$this-‐>Lang('delete'), array('quotaQon_id'=>$row['quotaQon_id']),$this-‐>Lang('really_delete',$row['author']));
That's better
Let admin edit quotations
● We can re-use the form template● Just need to create the admin-side logic● Note that the logic is not identical, since
we'll be updating the database rather than adding a new record
action.admin_edit.php<?phpif (!isset($gCms)) exit;if (!$this-‐>CheckPermission('Manage QuotaQ ons')) exit;$db = $this-‐>GetDb();
if (isset($params['submit'])){if (empty($params['author']) || empty($params['quotaQ on']))
{$smarty-‐>assign('message',$this-‐>Lang('error_empty_fi elds'));}
else{$res = $db-‐>Execute('update '.cms_db_prefi x().'module_quotaQons set author=?,quotaQon=? where quotaQon_id=?',
array($params['author'],$params['quotaQ on'],$params['quotaQon_id']));if ($res === false)
{$smarty-‐>assign('message',$this-‐>Lang('db_error',$db-‐>ErrorMsg()));}
else{$smarty-‐>assign('message',$this-‐>Lang('quotaQ on_edited'));}
return $this-‐>DoAcQon('defaultadmin', $id, $params, $returnid);}
}else
action.admin_edit.php, cont{$res = $db-‐>Execute('select * from '.cms_db_prefi x().'module_quotaQons where quotaQon_id=?',
array($params['quotaQon_id']));if ($res && $row=$res-‐>FetchRow())
{$params['author']=$row['author'];$params['quotaQon']=$row['quotaQon'];}
}$smarty-‐>assign('form_start',$this-‐>CreateFormStart($id, 'admin_edit', $returnid));
$smarty-‐>assign('input_author',$this-‐>CreateInputTextWithLabel($id, 'author',isset($params['author'])?$params['author']:'', 10, 80, '',$this-‐>Lang('Qtle_author')));
$smarty-‐>assign('Qtle_quotaQon',$this-‐>Lang('Qtle_quotaQon'));
$smarty-‐>assign('input_quotaQon',$this-‐>CreateTextArea(false, $id,isset($params['quotaQon'])?html_enQty_decode($params['quotaQon'],ENT_QUOTES):'', 'quotaQon'));
$smarty-‐>assign('submit',$this-‐>CreateInputHidden($id,'quotaQ on_id',$params['quotaQon_id']).$this-‐>CreateInputSubmit($id, 'submit', $this-‐>Lang('submit')));
echo $this-‐>ProcessTemplate('user_form.tpl');?>
Editing
And edited
action.defaultadmin.php 2.0if (!isset($gCms)) die("Can't call acQons directly!");
if ( !$this-‐>Permission-‐>check('Modify Site Preferences') )CmsResponse::redirect('index.php?'.CMS_SECURE_PARAM_NAME.'='.
$_SESSION[CMS_USER_KEY]);
if (isset($params['submitprefs']) ){
if( !CmsAcl::check_core_permission('Modify Site Preferences', $user) )die('permission denied');
$password_minlength = (int)coalesce_key($params,'password_minlength',6);$this-‐>Preference-‐>set('password_minlength',$password_minlength);
}$smarty-‐>assign('groups',cms_orm('CmsGroup')-‐>find_all());$smarty-‐>assign('users',cms_orm('CmsUser')-‐>find_all());
$smarty-‐>assign('acQve_tab_for_modules', coalesce_key($params,'selected_tab','users'));$smarty-‐>assign('form_acQon','defaultadmin');
echo $this-‐>Template-‐>process('defaultadmin.tpl',$id,$return_id);
defaultadmin.tpl 2.0{has_permission perm="Modify Templates"}
<div style="text-‐align: right; width: 80%;"><a href="listmodtemplates.php" Qtle="{tr}modify_templates{/tr}">{tr}modify_templates{/tr}</a></div><br/>{/has_permission}
{tabs}{has_permission perm='Modify Users'}
{tab_content name='users'}{tab_header name='users'}{tr}users{/tr}{/tab_header}{mod_template template='users_tab.tpl'}
{/tab_content}{/has_permission}
{has_permission perm='Modify Site Preferences'}{tab_content name='prefs'}
{tab_header name='prefs'}{tr}preferences{/tr}{/tab_header}{mod_template template='prefs_tab.tpl'}
{/tab_content}{/has_permission}
{/tabs}