sfDynamicCMSPlugin
0.1.0beta
for sf 1.0 and Propel
MIT
This plugin is not exactly a CMS, it is more a CMF (Content Management Framework).
This plugin allows you to add a Dynamic Content Management System (CMS) to your Symfony project with the following features:
- Manage different versions of a website (different applications or cultures)
- For each version :
- create and manage a tree structure for navigations (breadcrumb navigation)
- manage routing & url of each element (fully generate routing.yml)
- manage displayed menus
- manage permissions to access content or display element in menu
- manage pages associated to url (module/action) and page
- manage page templates (global or specific to version) and template slots)
- manage content (with slots system)
- Manage permissions of CMS administration (for edition, administration, advanced administration, developpement).
- i18n ready (the interface is translated / french translation included)
- Can be used in any kind of module (by extending it or not), any kind of project.
The aim is to give a backend admin to navigation and content management for all kind of Symfony Project. Then plugin usage is quite more complex and quite different that sfSimpleCMS but permits to be used in any kind of project.
This CMS is not l10n, you can't have different versions for a page. But you can maintain different versions for a whole website. Then websites can be totaly different according to their culture and managed separately.
This CMS is currently used by all websites (15+) developped by the author : mainly e-commerce and corporate websites.
Developers
| Name |
Status |
Email |
Sylvain Papet |
lead |
moc.naeco-moc <<ta>> niavlys
|
License
Copyright (c) 2007-2008 Sylvain Papet
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
sfDynamicCMS plugin
Overview
This plugin allows you to add a Dynamic Content Management System (CMS) to your Symfony project with the following features:
Manage different versions of a website (different applications or cultures, usually : frontend but cms can be used in a backend)
For each version : create and manage a tree structure for navigations, breadcrumb navigation
Associate and edit page to navigation element
Manage navigation url and routing parameters for navigation element (generate routing rules in route.yml)
Manage access credential for navigation element
Manage administrator and editor credentials for backend access
Manage page templates (global or specific to version) and template slots
Manage page content with structured dynamic content (slots)
i18n ready (the interface is translated)
User management is controlled through sfGuardPlugin
usable in any kind of template by extending itself or usable as a cms module
The aim is to give a backend admin to navigation and content management for all kind of Symfony Project. Then plugin usage is more complex that sfSimpleCMS but permits to be used in any kind of project.
The aim of the plugin is also to automate some process (like management of images and thumbnails).
This CMS is not l10n, you can't have different version for a page. But you can maintain different version for a whole website. Then website can be different according to culture.
This CMS has been experimented in a backend cms usage : navigation into the backend and backend help pages content are managed with the sfDynamicCMS module.
This CMS is currently used by all websites (~10) developped by Author : mainly e-commerce and corporate websites.
Requirements
The prerequisites for using the sfDynamicCMS plugin are:
The page tree strucure uses the sfPropelActAsNestedSetBehaviorPlugin. The plugin must be installed and behaviors enabled in your propel.ini.
Rich text editing uses tinyMCE. You must install tinyMCE if you want a wysiwyg interface for text editing.
It is recomended but not required to have the following plugin :
Installation
Installation of sfPropelActAsNestedSetBehaviorPlugin plugin
sfPropelActAsNestedSetBehavior Plugin is needed by sfDynamicCMS Plugin, so you might have to install it before :
Install the plugin
symfony plugin-install http://plugins.symfony-project.com/sfPropelActAsNestedSetBehaviorPlugin
Enable Propel behavior support in propel.ini:
propel.builder.AddBehaviors = true
Installation of sfDynamicCMS plugin
To install the plugin for a symfony project, the usual process is to use the symfony command line:
$ php symfony plugin-install http://plugins.symfony-project.com/sfDynamicCMSPlugin
Alternatively, if you don't have PEAR installed, you can download the latest package attached to this plugin's wiki page and extract it under your project's plugins/ directory. You will also have to copy the contents of the myproject/plugins/sfDynamicCMSPlugin/web/ directory into a myproject/web/sfDynamicCMSPlugin/ directory.
Rebuild the model, generate the SQL code for the new tables and insert it into your database:
$ php symfony propel-build-all
Clear the cache to enable the autoloading to find the new classes:
$ php symfony cc
Enable the new sfDynamicCMS modules in your application (usually frontend), via the settings.yml file.
// in myproject/apps/frontend/config/settings.yml
all:
.settings:
enabled_modules: [sfDynamicCMS](default,)
Enable the new sfDynamicCMSAdmin modules in your application (usually backend), via the settings.yml file.
// in myproject/apps/backend/config/settings.yml
all:
.settings:
enabled_modules: [sfDynamicCMSAdmin](default,)
sfDynamicCMSAdmin Configuration
Configuration request mainly to describe slots. The aim is to have a syntax which look like "Admin generator" generator.yml files for slots description
Usually configuration is also used to describe global templates which are used by all version. It is possible in admin to define templates that are used only in a specific version.
app.yml
sfDynamicCMS:
dev_credentials: superadmin
templates:
intro:
name: "Intro page"
slots: []
home:
name: "Homepage"
slots: [text]
page1:
name: "Page model 1"
slots: [image, doc_file](text,)
page2:
name: "Page model 2"
slots: [column2](column1,)
contact:
name: "Contact"
slots: [email](text_contact,)
slots:
text:
name: "Text"
type: Text
params : size=100x10
column1:
name: "Text - 1st column"
type: Text
help: Don't use "CTRL+V" keystroke but "paste" icons.
params: rich=true tinymce_options=height:500,width:300
column2:
name: "Text - 2nd column"
type: Text
help: Don't use "CTRL+V" keystroke but "paste" icons.
params: rich=true tinymce_options=height:500,width:300
image:
name: "Image"
type: Image
params: include_link=page include_remove=true
upload_dir: page
help: Download a JPEG file
doc_file:
name: "Documentation"
type: File
params: include_link=doc_pdf include_remove=true
upload_dir: doc_pdf
help: "Download a pdf file"
email:
name: "E-mail address"
type: Input
params: size=40
dev_credentials: Credential to access developper features (version and routing management)
sfDynamicCMS Configuration
app.yml
sfDynamicCMS:
title: "My Website rules da world"
default_module: default
default_action: index
routes_register: true
localizations: [en](fr,)
recommanded :
title : default title or title prefix/sufix
default_module module called by default while routing (usually : default, my_cms_module )
default_action action called by default while routing (usually : index or my_cms_action )
facultative :
Usage of sfDynamicCMSAdmin : Manage version, navigation and content
Start using the plugin by browsing to the admin module's default page:
http://myproject/backend_dev.php/sfDynamicCMSAdmin
Admin is divided in 2 sections :
If the plugin is used for the first time (when there is no version), it is needed to start by creating a version.
Then :
Create a version (usualy default culture and frontend application)
Define page templates : as global (in app.yml) or as defined for this version only (in page template section)
Create root navigation element (or homepage)
Create navigation elements, create pages, define template used by pages, ...
Manage rooting parameters of navigation elements
Manage pages linked to navigation elements
Manage content of pages
Create a new version and manage his templates, pages and content
...
Next : If you want to use all the power of sfDynamicCMS you should extend one or many modules with sfDynamicCMS.
Usage of sfDynamicCMS : Extend your module to get navigation information and content
You can extend any module without modify how it work.
It is possible to extend a module dedicated to be used as CMS module (for classical pages).
It is also possible to extend a module which contain business logic like product catalog, news, ecommerce module
Without extending module, it is also possible to use all sfDynamicCMS features by coding your own methods
It permit :
to get current navigation element information to know where are the visitor in the website
to get current page template and define it automaticaly
to get current page information (title, meta tags, template) and fill it automaticaly
to get page content (slots)
Action
First extends the actions.php :
actions should inherit from BasesfDynamicCMSActions
require_once(sfConfig::get('sf_plugins_dir'). '/sfDynamicCMSPlugin/modules/sfDynamicCMS/lib/BasesfDynamicCMSActions.class.php');
class defaultActions extends BasesfDynamicCMSActions
{
...
It is recommanded (but optionnal) to add the SfDynamicCMS features to all module actions by adding this 2 lines in preExecute method.
You can also add this 2 lines only in actions which need SfDynamicCMS features.
// Always retrieve navigation information and page content
public function preExecute()
{
$this->current_node=$this->getSfDynamicNode();
if ($this->current_node) $this->current_page=$this->getSfDynamicPage($this->current_node);
// ... my preExecute code ... //
}
// OR //
public function executeNews()
{
//get navigation information
$this->current_node=$this->getSfDynamicNode();
//get static content for the news page
if ($this->current_node) $this->current_page=$this->getSfDynamicPage($this->current_node);
// ... my article action code (business logic) ... //
$this->news=NewsPeer::getLastNewsPublished();
}
first line concern navigation : it just return the current element in navigation tree (if sfDynamicCMS is able to find it).
second line concern page, template and content : it return the current page linked to the navigation element
Moreother, this feature automaticaly define page title, page meta-tags and page template.
Template files
Usually, the template file used is named with the name of the template and the suffix "Success" like my_templateSuccess.php.
But if a template file named with the name of action and the suffix "Success" exist like indexSuccess.php, it will overide this.
It permits to use page content (structured with a generic template slots) with a specific template defined for a specific action.
Then be carefull, indexSuccess.php will overide your template file if you use index action which is usualy the default action.
Templates are not included in sfDynamicCMS, you have to create it.
Example, add in your template 'articleSuccess.php' :
getSlotValue('image')) echo image_tag($current_page->getThumbnail('image',320,240));
echo $current_page->getRichText('text');
if($page_oeuvre->getSlotValue('author')) echo ''.link_to($current_page->getSlotValue('author'),$current_page->getSlotValue('link')).'
';
$next_node=$current_node->retrieveNextSibling();
if (next_node) echo '.rawurldecode(link_to('next article',$next_node->getFirstInternalUri())).
;
?>
Component
Component are usually used for menu : main menu, sub menu or multiple levels menu
Example of usage in Component actions : components.class.php :
public function executeMenu()
{
//get first level navigation elements (main menu) :
$this->elements=SfDynamicCmsNodePeer::getRootNode()->getChildren();
//get current first level navigation element (to highlight it in main menu):
$this->current_element= sfDynamicCMS::getInstance()->getCurrentNode(1);
}
public function executeSumenu()
{
//get current first level navigation element (main menu opened)
$parent_element = sfDynamicCMS::getInstance()->getCurrentNode(1);
//get second level navigation elements (sub menu)
if($parent_element) $this->sub_elements=$axe->getChildren();
//second way, you can just get the name of the current second level navigation element (to highlight it in sub menu)
$this->current_submenuname= sfDynamicCMSTools::getCurrentUrl(2);
}
Example of usage in Component template : _menu.php :
<div id="menu"><ul><?php
foreach ($elements as $element)
{
if ($element->isPublished())
{
if (isset($current_element) && $current_element->getName()==$element->getName()) $class='menu-highlight';
$id='menu-'.$element->getName();
echo "<li>".rawurldecode(link_to('<span>'.$element->getTitle().'</span>',$element->getFirstInternalUri(),array('class' => $class, 'id' => $id, 'title' => $element->getMenuName())))."</li>\n";
}
}
?></ul></div>
sfDynamicCMS ROUTING
sfDynamicCMS permits 3 ways to define a route :
Default routing : route managed automaticaly by sfDynamicCMS
Custom routing : route managed by sfDynamicCMS, same routing parameters that routing.yml can be defined
Traditionnal routing : routing rules defined in routing.yml of the application
Custom routing
By using Custom routing, sfDynamicCMSAdmin module generate rules in routing.yml (without erasing your own rules).
sfDynamicCMS will recognize this kind of rules. This way is usefull to merge your business logic with cms features offered by sfDynamicCMS.
Default routing
By using Default way, there is nothing to define, route is managed automaticaly but not permit to have use a specific module or action.
Default routing doesn't appear in routing.yml, this rules are executed after custom and traditionnal routing rules.
Traditionnal routing
Traditionnal rules can defined in routing.yml before or after the sfDynamicCMS rules (which are automaticaly updated).
Be carefull because sfDynamicCMS might not be able to find where are located this rules in sfDynamicCMS navigation tree.
Dev information
Please note that this plugin is in active development. If you want to help and improve it, please contact Sylvain Papet (my firstname @ com-ocean.com).
Business logic :
"version" = nav (navigation tree) => SfDynamicCmsNav class & sf_dynamic_cms_nav table
"navigation element" = node (navigation node) => SfDynamicCmsNode class & sf_dynamic_cms_node table
"Page" = page => SfDynamicCmsPage class & sf_dynamic_cms_page table
"Content" = slot => SfDynamicCmsSlot class & sf_dynamic_cms_slot table
The plugin as 2 main goals :
sfDynamicCMS class :
sfDynamicCMS : represent current version, perform navigation management and method templates and slots attached to current version
sfDynamicCMSTools : static function to use in extended module and static function used by sfDynamicCMSAdmin
model classes : for nav, node, page & slot
slotType classes : used in sfDynamicCMSAdmin & model (works look-like sfSimpleCms slots)
A lot of things can be refactored and improved.
TODO
- pages management in version management (this is not done at all)
- enhance backend interface
- check and enhance title paramter usage
- add another routing type : hard url
- check access permission to routing.yml files
- check nodes which has same url while creating or updating
- add new slot data types
- review node url generation and make sfDynamicCMS helper
- allow flexible model extension by adding an additional level of class inheritance (http://trac.symfony-project.com/wiki/HowToExtendPropelPluginModel)
- Doc : API
Changelog
0.1.0