Bekijk deze pagina in het Engels - vanaf daar zijn ook andere talen te vinden.
Modules aanmaken
Dit leerprogramma neemt u mee door de stappen waarmee een nieuwe CMSMS-module aangemaakt kan worden.
Noodzakelijke voorkennis
Deze tutorial gaat ervan uit dat u bekend bent met:
- PHP programmeren
- Basis object-geörienteerde programmeringsconcepten (encapsulation, inheritance, enz.)
- MySQL (of databases in het algemeen) -- tables, fields, data types, SQL syntax, enz. Ook moet u weten hoe u een database-beheertool gebruikt, zoals PhpMyAdmin om de CMSMS database te bekijken.
- Hoe CMSMS werkt vanuit de bezoeker gezien -- U weet wat sjablonen, stylesheets, pagina's en inhoud zijn, u weet dat u rechten kunt instellen voor diverse functionaliteiten en dat u door het toevoegen van {tags} in sjablonen de inhoud van modules kunt weergeven.
Er is geen kennis van de werking van CMSMS-modules nodig -- dat wordt in deze tutorial besproken!
Wat gaan we bouwen?
We gaan een heel eenvoudige product-catalogusmodule maken. Gebruikers met beheerstaken moeten productinformatie aan de database kunnen toevoegen via het beheerpaneel en vervolgens een pagina aanmaken dat alle producten in het systeem toont. Uiteindelijk moeten beheerders de mogelijkheid hebben verschillende weergaveopties te kiezen (aantal kolommen per pagina, enz.) om het mogelijk te maken producten te categoriseren op type of producent. Dus verschillende pagina's zullen andere verzamelingen producten tonen. Ook moet het mogelijk zijn te paginascheiding aan te brengen (aantal producten per pagina), productafbeeldingen te uploaden en te tonen en tenslotte moet de productinformatie doorzoekbaar zijn. Echter voor het doel van dit leerprogramma zullen we het eenvoudig houden -- productinformatie wordt beperkt tot de naam, een beschrijving en een prijs en alle producten worden getoond op een enkele pagina. We zullen deze module "Catlist" noemen (om verwarring met de bestaande Cataloger module te voorkomen).
Structuur van een CMSMS-module
Het kan nogal verwarrend zijn om uit te zoeken hoe de structuur van een module in elkaar zit -- welke code waar moet staan, welke bestanden kritisch zijn, enz. Ten eerste is het belangrijk te weten dat alles wat nodig is voor de module in de map staat die de naam van de module draagt. Omdat de naam van onze module "Catlist" is, zullen we onze modulemap dus "Catlist" noemen. De map staat in de "Modules" map van de CMSMS-installatie. Als u naar enkele van de bestaande modules kijkt (bijvoorbeeld de Skeleton-module), dan zult u veel bestanden en submappen zien. Deze kunnen grofweg opgedeeld worden in:
- action.___.php bestanden: Deze bestanden bevatten code die diverse "acties" afhandelen die worden aangeroepen door CMSMS -- bijvoorbeeld als het beheerpaneel bepaalde rechten moet controleren of als er nieuwe pagina's in de database worden opgeslagen. Net als bij de onderstaande "method.___.php" bestanden, zijn deze bestanden niet verplicht -- alle code in deze bestanden kan ook worden gestopt in het "Modulenaam.module.php"-bestand. Daarom zullen we voor het doel van dit leerprogramma geen "action.___.php" bestanden gebruiken, maar houd in gedachten dat u uiteindelijk de code wilt opdelen in meerdere bestanden om het geheel onderhoudbaar te houden.
- "images" map: Iedere afbeelding die wordt getoond in uw module (oftewel in het beheerpaneel of in het frontend-deel voor de bezoekers) wordt hier opgeslagen.
- index.html bestand: Dit is altijd een leeg bestand. Voor het geval dat het adres naar deze map direct in de browser's adresbalk wordt getypt, voorkomt dit bestand dat de inhoud van de map wordt getoond (dit is dus een veiligheidsmaatregel).
- "lang" map: Om meerdere talen te ondersteunen, kunt u taalbestanden in deze map plaatsen (een bestand per taal) en vervolgens in uw module-code in plaats van tekst-strings de functie "$this->Lang('string_naam')" aanroepen waarmee de tekst uit het juiste taalbestand wordt gehaald.
- method.___.php bestanden: Deze bestanden bevatten code die verschillende "method" afhandelen die worden aangeroepen doorCMSMS -- normal is dit voor installatie, opwaardering en deinstallatie van een module. Net als bij de bovengenoemde "action.___.php" bestanden, zijn deze bestanden niet verplicht -- alle code in deze bestanden kan ook in "Modulenaam.module.php" worden gestopt. Dus wederom, in dit leerprogramma zullen we deze bestanden niet gebruiken. Bij grotere modules is het gebruik echter wel aan te bevelen in verband met de betere onderhoudbaarheid.
- Modulenaam.module.php bestand: Dit bestand is het hart van uw module -- hier vindt alle actie plaats! Alle code die het installeren en deinstalleren van uw module verzorgt, de beheerder toestaat producten aan de database toe te voegen en die de producten in de frontend toont komt in dit bestand.
- "templates" map: Iedere sjabloon (template) die wordt gebruikt om de inhoud van uw module te tonen zit in deze map -- deze sjablonen worden gebruikt om zowel het beheerpaneel weer te geven, als de moduleinhoud op de frontend site.
Hoe CMSMS de moduleinhoud weergeeft
Het meest ingewikkelde concept om te begrijpen is de manier waarop CMSMS de moduleinhoud weergeeft op de frontend van de website. Er zijn twee manieren om dit te verwezenlijken:
- Invoegen van een {module} tag in een pagina: De beheerende gebruiker maakt een nieuwe pagina aan van het inhoudstype "content" en voegt een tag toe (in ons geval "{cms_module module='Catlist'}"). Dit heeft als effect dat de module's DoAction functie uit onze Catlist.module.php bestand wordt aangeroepen. Hiermee wordt data uit de database gehaald en in een van onze smarty-sjablonen geplaatst, die vervolgens weer in de pagina wordt gevoegd.
- Aanmaken van een nieuw inhoudstype: Nieuwe inhoudstypen worden toegevoegd aan het keuzemenu van het "Bewerk pagina" scherm in het beheerpaneel. Als dit inhoudstype wordt geselecteerd, dan krijgt de beherend gebruiker een scherm te zien waarmee verschillende parameters voor de module opgegeven kunnen worden. Deze parameters komen overeen met de parameters die u beschikbaar stelt in uw {module} tag. Als een pagina met uw inhoudstype wordt opgeslagen dan is het netto effect gelijk aan het aanmaken van een pagina met het inhoudstype "content" met in het tekstgebied de {module} tag toegevoegd (het verschil is dat de parameters nu ingesteld zijn via een gebruikersvriendelijk scherm zodat niet alle parameters onthouden hoeven te worden).
In dit leerprogramma wordt methode 1 aangehouden -- invoegen van een {module} tag in een "content"-type pagina.
De eerste stap: Aanmaken van de modulemap
Goed, we zijn nu klaar om onze module te gaan maken! Begin met het navigeren naar de "Modules" map van uw CMSMS-installatie. Maak een nieuwe map aan met de naam "Catlist". Let op de spelling en het gebruik van hoofdletters -- het is belangrijk dat we overal op dezelfde wijze naar onze module verwijzen. Met een tekst-editor maken we nu een nieuw bestand aan met de naam "Catlist.module.php" (nogmaals, let op de spelling). We starten met de basis -- plak de onderstaande code (afkomstig uit de Skeleton module) in het bestand:
<?php /* Uw initiële Class declaratie. De naam van het bestand moet "[class's name].module.php" zijn of in dit geval Catlist.module.php */ class Catlist extends CMSModule { /*--------------------------------------------------------- GetName() moet de exacte class-naam van de module teruggeven Als deze niet overeenkomen gaat er van alles mis. Dit is de naam die getoond worden in de Modules-pagina in het beheerpaneel. ---------------------------------------------------------*/ function GetName() { return 'Catlist'; } /*--------------------------------------------------------- GetFriendlyName() This can return any string. This is the name that's shown in the Admin Menus and section pages (if the module has an admin component). ---------------------------------------------------------*/ function GetFriendlyName() { return 'Simple Catalog Product List'; } /*--------------------------------------------------------- GetVersion() This can return any string, preferably a number or something that makes sense for designating a version. The CMS will use this to identify whether or not the installed version of the module is current, and the module will use it to figure out how to upgrade itself if requested. ---------------------------------------------------------*/ function GetVersion() { return '0.1'; } /*--------------------------------------------------------- IsPluginModule() This function returns true or false, depending upon whether users can include the module in a page or template using a smarty tag of the form {cms_module module='Skeleton' param1=val param2=val...} If your module does not get included in pages or templates, return "false" here. (Required if you want to use the method DoAction later.) ---------------------------------------------------------*/ function IsPluginModule() { return true; } } ?>
Ok, het is nog niet veel, maar wel een begin. Het commentaar legt uit wat iedere functie doet (hoewel dit nogal voor de hand liggend is). Als u het nog niet gedaan heeft, bewaar dan dit bestand in de "Catlist" map die we zojuist aangemaakt hebben en noem dit bestand "Catlist.module.php".
Laten we nu eens kijken naar de multi-language mogelijkheid van CMSMS. Hiermee bieden we vertalers de mogelijkheid hun eigen vertaling van de module toe te voegen (immers, dit is een open-source project!) Zoals hierboven al is uitgelegd kunt u, in plaats van letterlijke tekst in uw code beter de functie "$this->Lang()" gebruiken om de juiste tekst uit een apart taalbestand te halen.
Laten we een structuur maken om dat te doen. Maak een nieuwe map aan binnen de bestaande "Catlist" map genaamd "lang". Ga terug naar uw tekst-editor en maak een nieuw bestand aan in de "lang"-map genaamd "en_US.php". Tot zover is de enige string die we in dit bestand willen zetten de "Friendly Name" (omdat de werkelijke modulenaam altijd gelijk is, onafhankelijk van de gekozen taal). Voeg de volgende code toe aan het nieuwe bestand:
<?php $lang['friendlyname'] = 'Simple Catalog Product List'; ?>
Merk op: de taal in het bestand en_US.php moet uiteraard Engels zijn. Ga nu terug naar het "Catlist.module.php" bestand en verander de regel in de "GetFriendlyName()" functie naar:
return $this->Lang('friendlyname');
Als u of iemand anders een nieuwe taal aan de module wilt toevoegen, dan moeten ze een nieuw bestand in de "lang" map plaatsen (bijvoorbeeld, "no_NO.php" voor Noors) en de waarde van $lang['friendlyname'] naar iets meer... Noors.
Het schrijven installatie- en deinstallatie-code
De meeste modules zullen toevoegingen aan de CMSMS database nodig hebben (zodat gegevens bewaard kunnen worden en weer opgehaald), nieuwe rechten (zodat beheerders gebruikers kunnen toestaan om bepaalde taken uit te voeren of de uitvoering daarvan juist blokkeren) en enkele voorkeursinstellingen (waarmee beheerders verschillende instellingen kunnen veranderen). Al deze zaken moeten doorgevoerd worden tijdens de installatie van de module en we plaatsen ze in de functie genaamd "Install()". Hiermee worden ze uitgevoerd als op de "installeren" link wordt geklikt vanuit het beheerpaneel. Voor het doel van deze module zullen we een enkele database-tabel aanmaken om productinformatie in op te slaan en een enkele rechten-rol die toestaat (of blokkeert) dat gebruikers producten toevoegen/bewerken/verwijderen van de catalogus. We hebben geen voorkeuren.
Voeg als eerste deze functie toe aan het Catlist.module.php bestand:
function Install() { }
De database-tabel zal heel eenvoudig zijn -- er zijn velden voor de product-ID, productnaam, productomschrijving en de prijs. CMSMS gebruikt de ADODB-bibliotheek om gegevens met de database uit te wisselen (zie de ADODB manual voor meer details Engels). Zet de volgende code in het Catlist.module.php bestand (binnen de gekrulde haakjes van de Catlist class):
function Install() { //Get a reference to the database $db = $this->cms->db; // mysql-specific, but ignored by other database $taboptarray = array('mysql' => 'TYPE=MyISAM'); //Make a new "dictionary" (ADODB-speak for a table) $dict = NewDataDictionary($db); //Add the fields as a comma-separated string. // See the ADODB manual for a list of available field types. //In our case, the id is an integer, the name is a varchar(100) field, // the description is a text field, and the price is a float. $flds = "id I KEY, name C(100), description X, price F"; //Tell ADODB to create the table called "module_catlist_products", // using the our field descriptions from above. //Note the naming scheme that should be followed when adding tables to the database, // so as to make it easy to recognize who the table belongs to, and to avoid conflict with other modules. $sqlarray = $dict->CreateTableSQL(cms_db_prefix().'module_catlist_products', $flds, $taboptarray); $dict->ExecuteSQLArray($sqlarray); //Now create a "sequence", which is used internally by CMSMS and ADODB // to increment our id value each time a new record is inserted into the table. $db->CreateSequence(cms_db_prefix().'module_catlist_products_seq'); }
Voeg nu nog een regel toe aan het einde van de functie zodat de rechten-rol in het systeem wordt aangemaakt:
function Install() { /* ... alle bovenstaande database-code... */ // Creëer een recht // Het eerste argument is de naam van het recht dat zal worden gebruikt door het systeem. // Het tweede argument bevat een gedetailleerdere beschrijving van het recht. $this->CreatePermission('Catlist Admin', 'Manage Catlist'); }
Voeg ook deze functie toe (tussen de gekrulde haken van de Catlist class), die zal worden getoond aan de beheerder na een succesvolle installatie
function InstallPostMessage() { return $this->Lang('postinstall'); }
en natuurlijk moet de melding in de Engelse taal aan ons "lang" bestand worden toegevoegd:
$lang['postinstall'] = 'Catlist successfully installed!';
Omdat installeren van deze module ons verplicht een aantal zaken aan het CMSMS-systeem toe te voegen, zullen we dit weer moeten verwijderen als de module wordt gedeinstalleerd. Het zal niet verbazen dat dit in de functie "Uninstall()" wordt uitgevoerd. Feitelijk moeten we alle veranderingen ongedaan maken die met de functie "Install()" zijn doorgevoerd. Voeg de volgende code toe aan het Catlist.module.php bestand (wederom binnen de gekrulde haken van de Catlist class):
function Uninstall() { //Get a reference to the database $db = $this->cms->db; //Remove the database table $dict = NewDataDictionary( $db ); $sqlarray = $dict->DropTableSQL( cms_db_prefix().'module_catlist_products' ); $dict->ExecuteSQLArray($sqlarray); //Remove the sequence $db->DropSequence( cms_db_prefix().'module_catlist_products_seq' ); //Remove the permission $this->RemovePermission('Catlist Admin'); }
Net als bij het installeren willen we een bericht aan de beheerder geven dat het deinstalleren voltooid is. Daarnaast moet de beheerder een "Weet u het zeker?" bericht krijgen, voordat de actie wordt voortgezet. Dit is zeker van belang als er productgegevens permanent uit onze databasetabel worden verwijderd. Zoals eerder moeten de volgende functies weer aan het Catlist.module.php bestand worden toegevoegd:
function UninstallPreMessage() { return $this->Lang('uninstall_confirm'); } function UninstallPostMessage() { return $this->Lang('postuninstall'); }
Tenslotte voegen we de volgende regels toe aan de Engelse versie van het "lang" bestand:
$lang['uninstall_confirm'] = 'All product data in the catalog will be deleted!' . 'Are you sure you want to uninstall the Catlist module?'; $lang['postuninstall'] = 'Catlist successfully un-installed.';
Goed, we hebben nu voldoende code aangemaakt om de nieuwe module te kunnen uitproberen!
Producten op de website weergeven
Zoals eerder gezegd gaan we een functie in ons Catlist.module.php bestand maken met de naam "DoAction" -- deze functie wordt aangeroepen als CMSMS een {cms_module module='Catlist'} tag op de pagina tegenkomt. Het resultaat van de functie HTML-code met een lijst van alle prodcuten in onze database. Voeg het volgende toe aan de Catlist class in het Catlist.module.php bestand:
function DoAction($action, $id, $params, $returnid=-1) { }
Voor nu zullen we de functie parameters even laten voor wat ze zijn, maar ze zijn wel nodig in de functiedeclaratie anders volgen er foutmeldingen.
De module zal verschillende HTML-code genereren, afhankelijk van de context. Op een normale webpagina bijvoorbeeld zullen we de productencatalogus tonen, maar in het beheerpaneel een formulier waarmee gegevens ingevoerd kunnen worden. Onze functie weet wat het moet uitvoeren aan de hand van de $action parameter. In deze tutorial zullen we alleen uitvoer genereren als de module-tag in een webpagina wordt aangeroepen en deze functie wordt 'default' genoemd.
Zo, laten we een wat nader op de DoAction functie ingaan:
function DoAction($action, $id, $params, $returnid=-1) { if ($action == 'default') { $db =& $this->GetDb(); $sql = 'SELECT * FROM ' . cms_db_prefix().'module_catlist_products;'; $dbresult =& $db->Execute($sql); $list = "<br /><br />\n"; $list .= "<ul>\n"; while ($dbresult && $row = $dbresult->FetchRow()) { $list .= "<li><b>" . $row['name'] . '</b><br />'; $list .= $row['description'] . '<br />'; $list .= money_format('%n', $row['price']) . '<br />'; $list .= "</li>\n"; } $list .= "</ul>\n"; $list .= "<br /><br />\n"; } // assign to Smarty global $gCms; $this->smarty->assign('list', $list); /** *Insert: {cms_module module='Catlist'}{$list} *in your page template *But there has to be a way for this to work without the {$list} tag... **/ return; }
Deze code voert een query uit en distilleert daarmee gegevens uit de database die we aangemaakt hebben via de Install functie. Vervolgens loopt het door de query-resultaten en schrijft het HTML-code weg via de echo functie. Om dit te testen heeft u enkele voorbeeldproducten in de database nodig. Omdat we nog geen beheerscherm voor 'Catlist' beschikbaar hebben, moeten we deze voorbeeldproducten handmatig in de database zetten (bijvoorbeeld met phpMyAdmin). Ga vervolgens naar het beheerpaneel van CMSMS en kies Uitbreidingen -> Modules, zoek de Catlist-module in de lijst en klik "Installeren". Voeg vervolgens een nieuwe pagina aan de website toe (Inhoud -> Pagina's) of bewerk een bestaande pagina en voeg de module-tag toe -- {cms_module module='Catlist'} -- in het Inhoud-tekstvak. Bewaar de pagina en bekijk deze op uw website. Tada! U moet een lijst met de producten zien die u in de database ingevoerd heeft.
Splits de getoonde HTML in smarty-sjablonen
Nu gaan we verder met het gebruik van de krachtige sjablonen-engine: Smarty. Het doel van deze paragraaf is het splitsen van de module-kern (hoe het werkt) van de weergave (hoe het eruit ziet).
Eerst maken we een nieuwe map genaamd "templates". In deze map komen alle sjablonen die nodig zijn voor onze module, dus de specifieke sjablonen die we gaan bouwen voor de module). Maak een nieuw bestand met de naam "display.tpl" en zet hier de volgende code in:
<br> <br> <ul> {section name=element loop=$list} <li><b>{$list[element].name}</b><br>{$list[element].description}<br>{$list[element].price} € <br></li> {/section} </ul> <br> <br>
Deze sjabloon gebruikt de Smarty-syntax. De regel <li><b>{$list[element].name}</b><br>{$list[element].description}<br>{$list[element].price} € <br></li> toont de naam, de beschrijving en de prijs van het huidige product. We gebruiken {section name=element loop=$list} om hetzelfde mechanisme toe te passen op alle elementen uit $list.
Nu hebben we ons sjabloon. Om deze te gebruiken passen we de eerdere methode DoAction als volgt aan:
function DoAction($action, $id, $params, $returnid=-1) { if ($action == 'default') { $db =& $this->GetDb(); $sql = 'SELECT * FROM ' . cms_db_prefix().'module_catlist_products;'; $dbresult =& $db->Execute($sql); // Creating a new array for all products $list = array(); //For each product of the database while ($dbresult && $row = $dbresult->FetchRow()) { // Get the number of current items in the list $i = count($list); // Set the different params $list[$i]['name'] = $row['name']; $list[$i]['description'] = $row['description']; $list[$i]['price'] = $row['price']; } // assign to Smarty $this->smarty->assign('list', $list); // Display the populated template echo $this->ProcessTemplate('display.tpl'); } return; }
Pas uw voorbeeldpagina aan door {cms_module module='Catlist'}{$list} te veranderen in {cms_module module='Catlist'} .
More To Come
Todo:
- Add an Admin Panel that allows for product data entry and editing.
- Add a "product details" page that shows full details of a single product.
- Add product images.
- Integrate searching into the catalog
- Separate displayed html out into smarty dedicated templates (almost done)
- Separate different actions out into multiple files
- Add ability to put products into categories (so a single page can show a single category's products, and different categories can be different sub-pages to provide easier and more sensible browsing via the built-in CMSMS menu system)
- Add module parameters for display options (product category, pagination, number of columns, etc.)
Bijdragen aan de Nederlandse wiki? Check dan eerst het forum-topic WIKI - wat doen we daarmee?