20091208 Creating Modules for Digitalus CMS v1.9

Embed Size (px)

Citation preview

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    1/26

    Digitalus CMS Tutorial: Creating Modules 1/26

    Developing custom user modules for Digitalus CMS

    Introduction

    General

    The Digitalus CMS offers the possibility to create user custom modules.

    As the Zend Framework, these modules follow the MVC pattern (Model-View-Controller).

    The administration backend contains a separate tab to deal with modules.On this page all existing modules are listed. By choosing a specific module from the list, theoptions for this module appear and modifications can be made (creating an instance of amodule, e.g. a specific blog).

    Digitalus CMS modules are linked to single pages. In the Pages tab one can select a module for

    a specific page from the list of existing modules. This means that the same module can beselected for different pages.

    This How-To shows how to create simplistic guestbook module; it refers to the Digitalus CMSversion 1.9.

    The How-To should be thought of as a starting point and is in no way complete. It shows howthe Digitalus CMS deals with modules, but it doesn't show the basics of Zend_Framework orPHP programming (also security aspects are only touched slightly).

    What do we want our module to do?

    A guestbook is often found on websites. It gives a website visitor the opportunity to leave acomment, e.g. whether he likes the site or not.

    Mostly, the comments are stored into a database and can be listed in the order of theirsubmission date.

    So, what do we need?

    We need a public frontend to:

    show a list of already submitted guestbook entries

    provide an HTML form for users to submit a new entry

    We need an administration backend for our module to:

    create instances of the guestbook

    delete guestbook entries that have illegal or offending contents

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    2/26

    Digitalus CMS Tutorial: Creating Modules 2/26

    Directory Structure

    Digitalus CMS modules are found in the directory/application/modules.

    The way modules are handled by the CMS requires to have at least two controllers and view

    scripts, i.e. indexandpublic. More controllers and view scripts can be created as we will see.To start with our module create a directory called guestbook. As modules follow the MVCpattern create the following subdirectories as proposed by the Zend Framework:

    /application/modules/guestbook:

    controllers

    data

    forms

    models

    views

    helpers

    scripts

    index

    public

    The data directory will later store several different data, e.g. translation files.

    Now already, the module guestbookappears on the admin tab Modules.

    When clicking on the link an exception occurs:

    Fatal error: Uncaught exception 'Zend_Controller_Dispatcher_Exception' with message 'Invalid controllerspecified (index)' in /var/www/...

    As already mentioned the IndexController is needed for the backend.

    Check the link! The reference is something like urlOfWebsite/mod_guestbook.

    Create a page called MyGuestbookPage with the default template that links to the guestbookmodule.On the more content pane You will see a module selector, but the guestbookmodule doesn'tappear.

    In the frontend go to Your page just created!In th source code of that page You should find the following lines:

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    3/26

    Digitalus CMS Tutorial: Creating Modules 3/26

    Start with the admin backend

    Let's create an IndexController and a view:

    /application/modules/guestbook/controllers/IndexController.php:

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    4/26

    Digitalus CMS Tutorial: Creating Modules 4/26

    /application/modules/guestbook/views/scripts/index/index.options.phtml:

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    5/26

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    6/26

    Digitalus CMS Tutorial: Creating Modules 6/26

    Frontend entry form

    Let's create a form for the website visitor to be able to send a new guestbook entry.

    Change Your already existing files as follows:

    /application/modules/guestbook/forms/Entry.php

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    7/26

    Digitalus CMS Tutorial: Creating Modules 7/26

    /application/modules/guestbook/views/scripts/public/index.phtml:

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    8/26

    Digitalus CMS Tutorial: Creating Modules 8/26

    Do some action

    Okay, but what happens when we push the button?

    We have set the following action in the PublicController:

    $entryForm->setAction($_SERVER['REQUEST_URI']);

    So, the action of the form is the url we come from.

    The PublicControllermust react differently depending on whether the form is submitted or not.

    What do we expect the form to do? It should validate the input and if valid send the data to theserver and store it into a database. That means, first of all we need a model for the guestbookentry that extendsZend_Db_Table_Abstractsomehow.

    The model

    The Digitalus CMS offers some basic classes that already extend this abstract class, but it alsoprovides some models that could be extended for our specific use.

    The Model_Page model is a good base to build own classes on as it provides several usefulmethods. It is already linked to a database (pages). More complex modules might require veryspecial databases, but that's not shown in this tutorial.

    The new model should assist us in creating new entries, deleting entries and fetching entriesfrom the database.

    Let's create the model with these basic methods:

    /application/modules/guestbook/models/Entry.php:

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    9/26

    Digitalus CMS Tutorial: Creating Modules 9/26

    The controller

    Now we need to modify the PublicController.

    /application/modules/guestbook/controllers/PublicController.php:

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    10/26

    Digitalus CMS Tutorial: Creating Modules 10/26

    But what guestbook are the entries related to? And what about the content? When and how is itstored to the database?

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    11/26

    Digitalus CMS Tutorial: Creating Modules 11/26

    The guestbook

    We want to create a guestbook in the administration backend. Then we want to assign aspecific guestbook to a page.

    For the creation of guestbook we need an HTML form. It's almost the same as the Entry_Form. /application/modules/guestbook/forms/Entry.php:

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    12/26

    Digitalus CMS Tutorial: Creating Modules 12/26

    The action for the HTML form leads to the createAction of the GuestbookController. Both don'texist so far. Also, a guestbook model would be a good idea.

    Let's start with the model.

    /application/modules/guestbook/models/Guestbook.php:

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    13/26

    Digitalus CMS Tutorial: Creating Modules 13/26

    Now to the GuestbookController:

    /application/modules/guestbook/controllers/GuestbookController.php:

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    14/26

    Digitalus CMS Tutorial: Creating Modules 14/26

    The createAction checks whether the submitted form is valid. If so, a new guestbook is createdvia the Model_Guestbookand we redirect to the editAction If not, we redirect to the indexActionof the IndexController. We don't need a view script for the createAction because we do notdisplay anything but redirect promptly to the editAction.

    The interesting things are done within the editAction. Again, we check whether the HTML form is

    submitted and valid. If not, we search the database for the current guestbook and populate it'scontent into the HTML form, so we can edit it. If it is submitted, we retrieve the contents of theHTML form and update the guestbook with it.

    Last but not least, the view script(s):

    /application/modules/guestbook/views/scripts/guestbook/edit.phtml:

    We're ready to create and update a guestbook.

    Using specific guestbooks for pages

    Now, we want to assign our freshly created guestbook to a specific page.

    What exactly do we want to do? We have created a page called MyGuestbookPage. And wehave created a guestbook called MyGuestbook.

    When we are editing the page MyGuestbookPage, we want to select the module guestbookforthe page and we want to select the guestbook MyGuestbook.

    First of all, we create a view helper for this task. In /application/modules/guestbook/views/helperscreate the file SelectGuestbook.phpwith following content.

    /application/modules/guestbook/views/helpers/SelectGuestbook.php:

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    15/26

    Digitalus CMS Tutorial: Creating Modules 15/26

    /application/modules/guestbook/views/scripts/index/index.options.phtml:

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    16/26

    Digitalus CMS Tutorial: Creating Modules 16/26

    public$moduleData;

    public$properties;

    publicfunction init()

    {

    $module = new Digitalus_Module(); $this->moduleData = $module->getData();

    $this->properties = Digitalus_Module_Property::load('mod_guestbook');

    }

    publicfunction indexAction()

    {

    $entryForm = new Entry_Form();

    $entryForm->setAction($_SERVER['REQUEST_URI']);

    $submit = $entryForm->getElement('submit');

    $submit->setLabel($this->view->getTranslation('Create Guestbook Entry'));

    $mdlGuestbook = new Guestbook_Guestbook();

    $mdlEntry = new Guestbook_Entry();

    if($guestbookId = $this->moduleData->guestbook > 0) {

    $this->view->guestbook = $mdlGuestbook->find($this->moduleData->guestbook)->current();

    $this->view->entries = $mdlEntry->getEntries($this->moduleData->guestbook);

    $entryForm->getElement('guestbook_id')->setValue($this->moduleData->guestbook);

    }

    if($this->_request->isPost() && $entryForm->isValid($_POST)) {

    $values = $entryForm->getValues();

    $entry = $mdlEntry->createEntry($values['guestbook_id'],substr($values['content'],0,250));

    $arrayContent = array(

    'page_id' => $values['guestbook_id'],

    'id' => $entry->id,

    'author' => $values['author'],

    'email' => $values['email'],

    'content' => $values['content'],

    );

    $entry = $mdlEntry->edit($arrayContent);

    }

    $this->view->form = $entryForm;

    }

    }

    Now that we know the guestbook id, we can use it to store the guestbook entry's content at theright place.

    We create an array with the values to be stored and use the edit() method to store it into thedatabase.

    Also, we pass the entries for the current guestbook and the guestbook itself to the view. We willneed it later.

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    17/26

    Digitalus CMS Tutorial: Creating Modules 17/26

    Extending the backend

    Wouldn't it be nice to have a list of all existing guestbooks in the backend?

    Well, we will need it as soon as we want to modify a guestbook later.

    Let's modify our IndexController.

    /application/modules/guestbook/controllers/IndexController.php:

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    18/26

    Digitalus CMS Tutorial: Creating Modules 18/26

    echo'

    ' .

    $this->getTranslation('This guestbook does not have any entries') .

    '

    ';

    }

    We take the view variable entries and loop through it if it exists. We have defined the variableentries in our GuestbookController.

    For each entry a link is created. The reference of the link is something like/mod_guestbook/entry/edit/id/$entryId.

    But wait, we don't have an EntryController! Time to create it.

    /application/modules/guestbook/controllers/EntryController.php:

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    19/26

    Digitalus CMS Tutorial: Creating Modules 19/26

    $entryArray['author'] = $entry->author;

    $entryArray['email'] = $entry->email;

    $entryArray['content'] = $entry->content;

    $entryForm->populate($entryArray);

    }

    $guestbook = $mdlGuestbook->find($entry->guestbookId)->current();

    $this->view->form = $entryForm;

    $this->view->guestbook = $guestbook; $this->view->entry = $entry;

    $this->view->breadcrumbs[$guestbook->name] = $this->view->getBaseUrl() .

    '/mod_guestbook/guestbook/edit/id/' . $guestbook->id;

    $this->view->breadcrumbs[$entry->author] = $this->view->getBaseUrl() .

    '/mod_guestbook/entry/edit/id/' . $entry->id;

    $this->view->toolbarLinks['Delete'] = $this->view->getBaseUrl() .

    '/mod_guestbook/entry/delete/id/' . $entry->id;

    }

    publicfunction deleteAction()

    {

    $mdlEntry = new Guestbook_Entry(); $id = $this->_request->getParam('id');

    $entry = $mdlEntry->getEntry($id);

    $mdlEntry->deletePageById($id);

    $this->_request->setParam('id',$entry->guestbookId);

    $this->_forward('edit','guestbook');

    }

    }

    Most of the stuff is the same or almost the same as for the GuestbookController. We have aninit() method, an editAction and a deleteAction. Init() method and deleteAction should be clear.

    What's happening in the EditAction? Well, we display the Entry_Form if it is not submitted or ifthe form is not valid. Otherwise, the entry is updated using an updateEntry() method of theGuestbook_Entrymodel that doesn't exist by now.

    Let's create it.

    /application/modules/guestbook/models/Entry.php:

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    20/26

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    21/26

    Digitalus CMS Tutorial: Creating Modules 21/26

    Extending the frontend

    In the preliminary we said that we wanted to display existing guestbook entries in the frontend.

    At the moment the frontend only displays the HTML form to send new entries to the database.

    So, we have to modify our frontend view script, which is thepublic/index.phtml. /application/modules/guestbook/views/scripts/public/index.phtml:

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    22/26

    Digitalus CMS Tutorial: Creating Modules 22/26

    $entryForm->setAction($_SERVER['REQUEST_URI']);

    $submit = $entryForm->getElement('submit');

    $submit->setLabel($this->view->getTranslation('Create Guestbook Entry'));

    $mdlGuestbook = new Guestbook_Guestbook(); $mdlEntry = new Guestbook_Entry();

    if($guestbookId = $this->moduleData->guestbook > 0) { $this->view->guestbook = $mdlGuestbook->find($this->moduleData->guestbook)->current();

    $this->view->entries = $mdlEntry->getEntries($this->moduleData->guestbook);

    $entryForm->getElement('guestbook_id')->setValue($this->moduleData->guestbook);

    }

    if($this->_request->isPost() && $entryForm->isValid($_POST)) {

    $values = $entryForm->getValues();

    $entry = $mdlEntry->createEntry($values['guestbook_id'],substr($values['content'],0,100));

    $arrayContent = array(

    'page_id' => $values['guestbook_id'],

    'id' => $entry->id,

    'author' => $values['author'],

    'email' => $values['email'],

    'content' => $values['content'],

    );

    $entry = $mdlEntry->edit($arrayContent);

    $this->view->form = $this->view->partial('partials/message.phtml',$arrayContent);

    } else {

    $this->view->form = $entryForm;

    }

    }

    }

    If the form is submitted successfully, not the form is displayed, but again a partial that looks asfollows:

    /application/modules/guestbook/views/scripts/partials/message.phtml:

    Very simple; we take the passed value authorto create a short message.

    Partials have the advantage that You can split Your view scripts into smaller parts that can beused over and over again. The drawback is the worse performance.

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    23/26

    Digitalus CMS Tutorial: Creating Modules 23/26

    What about form validation?

    Our two forms are still kind of raw without any form validation. It's good practice to let theZend_Validators do the validation of forms.

    Let's add some validators, attributes and custom error messages to the Entry_Form:

    /application/modules/guestbook/forms/Entry.php:

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    24/26

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    25/26

    Digitalus CMS Tutorial: Creating Modules 25/26

    Translations

    Finally, let's add a translation file.

    Create the file/application/module/guestbook/data/language/german.csv.

    If You're choosing German as Your administrator language, the contents of this file will appear.

    /application/modules/guestbook/data/language/german.csv:

    # admin section -- Module guestbook --

    # GERMAN

    # admin section -- Entry --

    "Guestbook";"Gstebuch"

    "guestbook";"Gstebuch"

    "Update Guestbook Entry";"Gstebuch Eintrag aktualisieren

    "Guestbook Entry";"Gstebuch Eintrag"

    "Back to";"Zurck zu"

    "Update Entry";"Eintrag aktualisieren"

    # admin section -- Guestbook --

    "Guestbook Entries";"Gstebuch Eintrge"

    "This guestbook does not have any entries";"Dieses Gstebuch enthlt keine Eintrge"

    "Update Guestbook";"Gstebuch aktualisieren"

    "Guestbook Name";"Name des Gstebuchs"

    # admin section -- Index --

    "The guestbook module enables you to publish multiple guestbooks on your site.";"Das Gstebuch ermglicht es

    Ihnen, mehrere Gstebcher auf Ihren Seiten zu verffentlichen."

    "Create Guestbook";"Gstebuch erstellen"

    "My Guestbooks";"Meine Gstebcher"

    "You do not have any guestbooks currently";"Es gibt momentan keine Gstebcher"

    "Guestbook Module";"Gstebuch Modul"

    "The guestbook module enables you to publish multiple guestbooks on your site."

    "Create a new guestbook";"Erstellen eines neuen Gstebuchs"

    # admin section -- Public --

    "Create Guestbook Entry";"Gstebuch Eintrag erstellen"

    "Select a guestbook";"Gstebuch auswhlen"

    "Current entries in guestbook ";"Aktuelle Eintrge im Gstebuch "

    "Number of entries: ";"Anzahl der Eintrge: "

  • 7/27/2019 20091208 Creating Modules for Digitalus CMS v1.9

    26/26

    Digitalus CMS Tutorial: Creating Modules 26/26

    Properties

    Each module has aproperties.xmlfile. This file can define any information that might berequired for the module:

    /application/modules/guestbook/properties.xml:

    book_open.png

    Guestbook

    The icon is used in the backend for the module.

    The label is shown on the module tab in the backend.

    You load the properties using the Digitalus_Module_Propertyclass:

    $props = Digitalus_Module_Property::load('mod_guestbook');

    ACL

    You can tie your module into the core CMS access control system by adding an acl.xmlfile.There are 3 levels of control in this model:

    1. Module level: you don't have to do anything for this2. Controller level: you list the controllers3. Action level: you list the controller actions as well

    /application/modules/guestbook/acl.xml:

    index

    delete

    edit

    create

    delete

    edit

    SummaryThe Digitalus CMS provides a smooth way to enhance the base system with custom usermodules.

    In this tutorial You learned how to build Your own simple guestbook module.

    Until now, we have a basic application. It is not perfect but a good starting point.

    Further enhancements could be:

    more advanced design

    custom form decorators

    notify admin for each new entry (per email)

    deploy publishing system