< Back to Part1 - Building a Simple Module

Part 2 - using Smarty templates in a module


In this tutorial I will teach you how to use smarty templates and sanitation in a module. So, let's start! First grab the completed tutorial module from part1. Install it. By looking at the code in index.php we can see there's a big mixture of php code and html. With big modules it gets very hard and difficult to read what that is for. That's the big advantage of smarty. We can create html templates that are easy to read and modify yet can be generated dynamically. XOOPS and ImpressCMS use smarty with it's own code. Let's create our first smarty template. Open xoops_version.php. Now add the code in red: // Templates $modversion['templates'][1]['file'] = 'tut_main.html'; $modversion['templates'][1]['description'] = ''; ? Basically this is telling XOOPS & ImpressCMS to add a template called tut_main.html to the DB. Now lets create a directory in the tutorial module called templates. Now create an html file inside this directory called tut_main.html. (NOTE: Normally, all template files use .html. Make sure there is NO code inside this file. It should be an empty file.) Now go to module administration and update the tutorial module. You will notice that tut_main.html gets processed by the core. OK, great! Let's go to the next step.

Writing a Smarty template.

Smarty templates are just simple html pages with some special code, in the case of XOOPS and ImpressCMS this code is enclosed with <{}>. For example, to grab the XOOPS url in a smarty template you would use: <{$xoops_url}> To keep this tutorial simple, I'm going to use an alternative method so that code doesn't get too complicated. Rename file index.php to index_original.php. Now create a new index.php file with the following code: $xoopsOption['template_main'] = 'tut_main.html'; require(XOOPS_ROOT_PATH.'/header.php'); $xoopsTpl->assign('mytest', 'Hello World!'); require(XOOPS_ROOT_PATH.'/footer.php'); ?> This code has 2 new lines. The first $xoopsOption tells the core which template page to use here. In this case tut_main.html. The second is where smarty shows in all it's glory; we can assign php vars to smarty vars. What does this mean exactly? In this case the smarty var 'mytest' will be replaced in our smarty template with 'Hello World!'. Now open the smarty template in /templates/tut_main.html and write the following: <{$mytest}> NOTE: Make sure you write this in code view if you are using a wysiwyg editor such as dreamweaver!
Click on tutorial from the main menu and you will see: Hello World!
Excellent! We now have a working smarty template for the main page of our module. Now lets take this further to create the same functionality from part 1. In part 1 we had a table with 4 columns that listed info from the DB. Lets create a table header in our smarty template. Erase <{$mytest}> from the template and replace with:

<{$smarty.const.TT_NAME}> <{$smarty.const.TT_ADDRESS}> <{$smarty.const.TT_TELEPHONE}> <{$smarty.const.TT_EMAIL}>

Don't forget to use code view! Now if you click on tutorial from the main menu we will see a table with 4 columns. You will notice that I'm using $smarty.const to retrieve language constants which are set in /tutorial/language/english/main.php There is an alternative way of setting constants using $xoopsTpl->assign however I would recommend not using this method since it's an extra line of code to worry about.

Arrays, What are they good for?

Open index_original.php and take a look at the code used to list all the contents in our DB table. You will notice that I use a var for each field; $name, $address, etc and then output the result using echo. Using a smarty template with this method will not work. We need to use a different method, where the result is stored in a single var that then gets assigned to a smarty var. This is where the beauty of arrays comes into play. We are going to create an array called $client that will store all info for each of our users. Open index.php and replace existing code with this: assign('client', $clientdata); function clientLoader(){ global $xoopsDB; $client=array(); $q=1; $query = $xoopsDB->query(' SELECT * FROM ' . $xoopsDB->prefix('tutorial_myform')); while($myrow = $xoopsDB->fetchArray($query) ) { $client[$q]['name'] = $myrow['name']; $client[$q]['address'] = $myrow['address']; $client[$q]['telephone'] = $myrow['telephone']; $client[$q]['email'] = $myrow['email']; $q++; } return $client; } require(XOOPS_ROOT_PATH.'/footer.php'); ?>
There are a couple of new things here; I'm using functions for the first time. Functions are great when you have a piece of code that will be used more than once. It also keeps things cleaner to read. In this case I created a function called clientLoader that goes to the DB, loads all info then returns in the form of an array. But let me explain exactly what's happening inside this function: function clientLoader(){ global $xoopsDB; The first line creates the function, in this case clientLoader. The second line declares $xoopsDB as a global. If you declare a var such as $mytest on your page, if you try and call it from inside a function it will not work. You will need to declare it as a global to access it from inside the function, which is this case. $client=array(); $q=1; It's always a good practice to declare a var as an array before you start putting data into it. The second line is a helper var I'm going to use. I'll explain its use later on. $query = $xoopsDB->query(' SELECT * FROM ' . $xoopsDB->prefix('tutorial_myform')); while($myrow = $xoopsDB->fetchArray($query) ) { $client[$q]['name'] = $myrow['name']; $client[$q]['address'] = $myrow['address']; $client[$q]['telephone'] = $myrow['telephone']; $client[$q]['email'] = $myrow['email']; $q++; } The first line here accesses the DB, then it will load all the info into out $client 1 row each time. This is where $q comes into play,since I set $q=1, our first row will be $client[1]['name']='something', etc. The $q++ increases the value of $q by 1, so the next row will be 2 and so on. return $client; } After it's finished getting all the info, the function will return $client. You also need to place a closing bracket to close the function. Now back to our assign: $clientdata=clientLoader(); $xoopsTpl->assign('client', $clientdata); Here we create a var called $clientdata which is then assigned to a smarty var called client. This takes care of everything on the php side. Now let's setup our smarty template to receive this info. Open tut_main.html and replace all code with this:

<{$smarty.const.TT_NAME}> <{$smarty.const.TT_ADDRESS}> <{$smarty.const.TT_TELEPHONE}> <{$smarty.const.TT_EMAIL}>
<{$cli.name}> <{$cli.address}> <{$cli.telephone}> <{$cli.email}>

Here I'm using a foreach loop to iterate through each client. Each client adds a row to the table. There are many people who advocate the use of tableless css designs. However since this is simple module tutorial, I'm using this method.
Click on tutorial from the main menu. If you haven't used part 1 then you possibly don't have any info in your DB.

Forms and Smarty templates

Lets now create a form to insert new clients in our DB. I'm basically going to use the same code from part 1. There are a couple of ways of doing this with smarty templates, I'm going to show the one with the most possibilities, which isn't necessarily the easiest. Open xoops_version.php and all the code with this: $modversion['templates'][1]['file'] = 'tut_form.html'; $modversion['templates'][1]['description'] = ''; $modversion['templates'][2]['file'] = 'tut_main.html'; $modversion['templates'][2]['description'] = ''; ?> You will notice 2 things, One is a new template and the other is that our main template is now number two. The reason for this is that I will be including tut_form.html inside tut_main.html. In order to include a smarty template inside another, you first need to declare the template which is to be included.
Now go to folder templates and create a blank html file called tut_form.html. Next goto module administration and update tutorial module. Now open tut_form.html and place this code:


Ok, now lets open tut_main.html and add this 1 line at the very top: <{include file="db:tut_form.html"}> Now if you click tutorial from the main menu you now see a form at the top of our page. Lets take this a step further, replace tut_main.html with this code:

Add new Client

<{if $addnew==1}> <{include file="db:tut_form.html"}> <{/if}>

<{$smarty.const.TT_NAME}> <{$smarty.const.TT_ADDRESS}> <{$smarty.const.TT_TELEPHONE}> <{$smarty.const.TT_EMAIL}>
<{$cli.name}> <{$cli.address}> <{$cli.telephone}> <{$cli.email}>

Now you have a link called Add new Client, the objective is, when this link is clicked, the form will be displayed. Now open index.php and replace all the code with this: if (isset($_GET['addnew'])){ $xoopsTpl->assign('addnew', 1); } $clientdata=clientLoader(); $xoopsTpl->assign('client', $clientdata); function clientLoader(){ global $xoopsDB; $client=array(); $q=1; $query = $xoopsDB->query(' SELECT * FROM ' . $xoopsDB->prefix('tutorial_myform')); while($myrow = $xoopsDB->fetchArray($query) ) { $client[$q]['name'] = $myrow['name']; $client[$q]['address'] = $myrow['address']; $client[$q]['telephone'] = $myrow['telephone']; $client[$q]['email'] = $myrow['email']; $q++; } return $client; } require(XOOPS_ROOT_PATH.'/footer.php'); ?> I've added an if condition that checks when the link was pressed. If it was then smarty var addnew is set to 1, thus displaying template tut_form.html. Now let's properly process the info from the form and insert it into the DB. I'm going to use code from part 1. Open index.php and replace all code with this: assign('addnew', 1); } if (isset($_POST['submit'])){ if (empty($_POST['name'])){ $xoopsTpl->assign('msg', "Please fill in a name"); } else { $name=$_POST['name']; $address=$_POST['address']; $tel=$_POST['tel']; $email=$_POST['email']; $query = "Insert into ".$xoopsDB->prefix("tutorial_myform")." (name, address, telephone, email) values ('$name', '$address', '$tel', '$email' )"; $res=$xoopsDB->query($query); if(!$res) { $xoopsTpl->assign('msg', "error: $query"); } else { $xoopsTpl->assign('msg', "Data was correctly inserted into DB!"); } } } $clientdata=clientLoader(); $xoopsTpl->assign('client', $clientdata); function clientLoader(){ global $xoopsDB; $client=array(); $q=1; $query = $xoopsDB->query(' SELECT * FROM ' . $xoopsDB->prefix('tutorial_myform')); while($myrow = $xoopsDB->fetchArray($query) ) { $client[$q]['name'] = $myrow['name']; $client[$q]['address'] = $myrow['address']; $client[$q]['telephone'] = $myrow['telephone']; $client[$q]['email'] = $myrow['email']; $q++; } return $client; } require(XOOPS_ROOT_PATH.'/footer.php'); ?> I've already explained this part in part 1. The only changes I made are in purple. I've basically set assigned the error and success message to a smarty var called msg. So lets open tut_main.html and in the very first line of code place this: <{$msg}> Now click on tutorial from the main menu, click add new client, fill the form and click submit. We have now added a new client to our DB! There's just one more step to conclude this part, and that's text sanitation. There's a saying among web developers, never trust the content of your users! This means you should always play safe and assume that there could be malicious intentions from people using your site. With that being said, never allow someone to access your database using forms (or gets) without properly checking if the fields contain valid data types. This is how sql injections occur, by allowing people to write invalid data into forms, which then get passed to the DB to be processed. Fortunately the core already has a sanitation process that you can easily use in your module. Open index.php and replace all the code with this: assign('addnew', 1); } if (isset($_POST['submit'])){ if (empty($_POST['name'])){ echo 'please fill in a name'; } else { $myts = myTextSanitizer::getInstance(); $name=$myts->addslashes($_POST['name']); $address=$myts->addslashes($_POST['address']); $tel=$myts->addslashes($_POST['tel']); $email=$myts->addslashes($_POST['email']); $query = "Insert into ".$xoopsDB->prefix("tutorial_myform")." (name, address, telephone, email) values ('$name', '$address', '$tel', '$email' )"; $res=$xoopsDB->query($query); if(!$res) { $xoopsTpl->assign('msg', "error: $query"); } else { $xoopsTpl->assign('msg', "Data was correctly inserted into DB!"); } } } $clientdata=clientLoader(); $xoopsTpl->assign('client', $clientdata); function clientLoader(){ global $xoopsDB; $client=array(); $q=1; $query = $xoopsDB->query(' SELECT * FROM ' . $xoopsDB->prefix('tutorial_myform')); while($myrow = $xoopsDB->fetchArray($query) ) { $client[$q]['name'] = $myrow['name']; $client[$q]['address'] = $myrow['address']; $client[$q]['telephone'] = $myrow['telephone']; $client[$q]['email'] = $myrow['email']; $q++; } return $client; } require(XOOPS_ROOT_PATH.'/footer.php'); ?> Now the data can be safely placed in your DB.

Continue to Part 3 - Building an AJAX module >

Last modified on 2010/11/27 by Anonymous
The comments are owned by the poster. We aren't responsible for their content.