Lo primero que tenemos es la estructura interna del CMS:
- controllers
- apps.cms2.controllers.CmsController.class.php
- model
- cms
- cms2.model.cms.Layout.class.php
- cms2.model.cms.Module.class.php
- cms2.model.cms.Page.class.php
- cms2.model.cms.PageZone.class.php
- cms2.model.cms.Zone.class.php
- views
- cms
- createModule.view.php
- createPage.view.php
- displayPage.view.php
- displayPageRO.view.php
- editModule.view.php
- listModules.view.php
- listPages.view.php
- module
- displayModule.template.php
El objetivo es crear un módulo para poder mostrar HTML y editarlo de forma visual en la web.
Lo primero que hacemos es crear la clase en el modelo, y ubicarla en model/nombreDelModulo:
YuppLoader::load('cms2.model.cms', 'Module'); class HtmlModule extends Module { function __construct($args = array (), $isSimpleInstance = false) { $this->setWithTable("cms_html_module"); $this->addAttribute("content", Datatypes :: TEXT); parent :: __construct($args, $isSimpleInstance); } public static function listAll(ArrayObject $params) { self :: $thisClass = __CLASS__; return PersistentObject :: listAll($params); } public static function count() { self :: $thisClass = __CLASS__; return PersistentObject :: count(); } public static function get($id) { self :: $thisClass = __CLASS__; return PersistentObject :: get($id); } public static function findBy(Condition $condition, ArrayObject $params) { self :: $thisClass = __CLASS__; return PersistentObject :: findBy($condition, $params); } public static function countBy(Condition $condition) { self :: $thisClass = __CLASS__; return PersistentObject :: countBy($condition); } }
El módulo se llama HtmlModule, y siempre debe extender a Module. La estructura de directorios en model quedará así:
- model
- cms
- ...
- htmlModule
- cms2.model.htmlModule.HtmlModule.class.php
Ahora necesitamos crear un controlador que implemente las acciones particulares sobe ese módulo, como editar el contenido. El controlador debe tener el mismo nombre que el módulo. Aquí está el código del controlador:
YuppLoader::load('cms2.model.htmlModule', 'HtmlModule'); class HtmlModuleController extends YuppController { /** * Edita el contenido del modulo de HTML. * * in: id * in: pageId */ public function editAction() { $module = HtmlModule::get($this->params['id']); if (isset($this->params['doit'])) { $module->setProperties($this->params); if (!$module->save()) print_r($module->getErrors()); return $this->renderString('Modulo salvado correctamente'); } return array('module'=>$module); } }
Aquí está la estructura de directorios resultante de controladores:
- controllers
- apps.cms2.controllers.CmsController.class.php
- apps.cms2.controllers.HtmlModuleController.class.php
Por último, se implementan las vistas del módulo. Una vista será para la edición del contenido, y otra para la visualización del contenido del módulo. La estructura de directorios resultante es la siguiente:
- views
- cms
- ....
- module
- displayModule.template.php
- htmlModule
- edit.view.php
- displayModule.template.php
Como se puede ver, en realidad la vista de visualización del contenido del módulo es en realidad un template.
displayModule.template.php:
<?php echo $module->getContent(); ?> <?php if ($mode=='edit') : ?> <div class="customModuleActions"> <a href="'htmlModule', 'action'=>'edit', 'class'=>$module->getClass(), 'id'=>$module->getId())); ?>" alt="editar html" class="edit_html"> <?php echo h('img', array('app'=>'cms2', 'src'=>'edit.gif')); ?> </a> </div> <?php endif; ?>
Este template muestra el contenido del módulo, y si estamos en modo "edit", muestra el botón para editar el contenido del módulo.
edit.view.php:
<?php $m = Model::getInstance(); $module = $m->get('module'); YuppLoader::load('core.mvc', 'DisplayHelper'); ?> <html> <head> <style> body { padding: 5px; } </style> <?php echo h('js', array('app'=>'cms2', 'name'=>'jquery/jquery-1.5.1.min')); ?> <?php echo h('js', array('app'=>'cms2', 'name'=>'jquery/jquery.form-2.84')); ?> <script type="text/javascript"> // Funcion que va a llamar el editor cuando termine de cargar (ver config del TinyMCE) var htmlinit = function() { parent.modalReady(document); // Notifica para que el parent actualice el tamanio del iframe } $(document).ready( function() { // Para que actualice el textarea con el contenido del TinyMCE, antes de mandarlo por ajax. // Ref: http://maestric.com/doc/javascript/tinymce_jquery_ajax_form $('#editForm').bind('form-pre-serialize', function(e) { tinyMCE.triggerSave(); }); // Submitea el form por ajax $('#editForm').ajaxForm({ // Cuando el servidor responde ok, quiero actualizar // automaticamente el HTML del modulo sin hacer F5. success: function (res, status, response) { // Este es el modulo que cambia en el dom var module = $('#getClass().'__'.$module->getId(); ?>', parent.document); // Tengo que pedir al servidor el HTML actualizado para este modulo // Luego meto el actualizado en el dom, antes del que cambie // Luego elimino el modulo viejo del dom para que quede solo el actualizado $.ajax({ url: ''cms', 'action'=>'moduleContent', 'params'=>array('class'=>$module->getClass(), 'id'=>$module->getId()))); ?>', success: function (newModuleContent, status) { // Actualiza solo el contenido! module.children('.moduleContent').html(newModuleContent); // Obtengo ventana modal var modal = $('#modal', parent.document); // Selecciona ventana // Cierra ventana modal modal.fadeOut('slow').css('display', 'none').children('iframe').attr('src', ''); } }); } }); }); </script> </head> <body> <form id="editForm" method="post" action="'edit')); ?>"> <input type="hidden" name="id" value="getId(); ?>" /> <input type="hidden" name="pageId" value="get('pageId'); ?>" /> <?php DisplayHelper::html( 'content', $module->getContent() ); ?> <input type="submit" name="doit" value="Guardar" /> </form> </body> </html>
Eso es todo. Cualquiera puede desarrollar sus propios módulos, por ejemplo un cliente de twitter, un visualizador de videos de youtube, un blog, un albúm de fotos, etc, el límite es la imaginación!
.