4elements, Amsterdam, Holland

  1. Building a Website by Progressive Enhancement

    When building a website you have a few ways to do the fancy stuff. One way is to start by creating the most advanced version you want (with all of the scripts, styles, etc.) and then make it render well in older browsers (graceful degradation). Another is just to decide you don't care about older browsers. A third is to start with a bare bones page, and add scripts and styles so it is readable and usable without them (progressive enhancement). In this series we will focus on the third option.

    Now that you know the theoretical stuff, we can create a simple page to illustrate the general approach. The site we will be creating will be just a simple information site: a few links, some text, images, and a contact form.

    We will use the widely adopted F layout (if you don't know what it is take a look at this great article on Web Design Tuts+: Understanding the F-Layout in Web Design).

    Step 1: Basic HTML

    Start by creating the index.html file with this HTML code:

    <!DOCTYPE html> 
            <title>Example Website</title> 

    Step 2: Heading and Menu

    Now let's create a heading for our website. To comply with the rules we will just use the <h1> tag for it:

    <h1>Our Sample Heading</h1> 

    After that we can create the menu. Usually you would use the <ul> tag for it, but since the page has to look decent without CSS, we will use the <nav> tag and put anchors in it:

        <a href="index.html">Home</a> 
        <a href="about.html">About</a> 
        <a href="offer.html">Offer</a> 
        <a href="contact.html">Contact</a> 

    Note that even if you don't use indentation in your code (and you should to make it more readable) you have to do it here, since without CSS the tabulators (or spaces) between the links are the only thing that will separate them (the distance will be the same no matter if you use tabulators or spaces, the browser will take care of that). Of course you will not notice it since the browser has a default CSS for them.

    Here is how our page should look:

    Step 3: Example Content and Footer

    To get some sample text, you can go to http://www.lipsum.com/ and generate a few paragraphs. Now remember the rules: we will not put the content in any special container <div>. It has to be semantic, so we will use the HTML5 <main> element. Put the text in the <p> tags just below the menu.

        <p> Lorem ipsum dolor sit amet... </p> 
        <p> Nam aliquet tempor turpis... </p> 

    Now add the footer using the <footer> tag:

    <footer>Copyright &copy; 2014 SomeNonExistent Company. All rights reserved.</footer> 

    The page should now look like this:

    You can create the About and Offer pages in the same way—they will not have anything special in them (you can add their names as <h2> tags just above the content).

    Step 4: The Contact Form

    The last thing to do in HTML is the contact page. Copy the contents of your index.html to contact.html and remove the contents of the <main> element.

    Now add the heading for the form (into the <main> tag):

    <h2>Contact Us</h2> 

    After that we can add a <form> element with appropriate fields for the user to fill (since the server side of things stays pretty much the same I will not cover it here, so if you want to test your form you will have to write the back-end yourself):

    <form method="POST"> 
    	    <label for="name">Your name:</label> 
    		<input id="name" name="name"> 
    		<label for="email">Your email:</label> 
    		<input id="email" name="email"> 
    		<label for="message">Your message:</label> 
    		<textarea id="message"></textarea> 
    	<button type="submit" value="Send">Send</button> 
    	<button type="reset" value="Reset">Reset</button> 

    The <p> tags do not break the semanticity rule because the label and input combo is actually a paragraph. The contact page should look like this:

    The CSS

    Now that our page is working, we can start to make it look a bit better. Create a file and name it style.css. Now add this line to the <head> section of your document:

    <link rel="stylesheet" href="style.css"> 

    Step 5: Base Styles

    The first thing to do would be to change the fonts and overall shape of the page:

    * { font-family: Calibri, sans-serif; } 
    body { width: 900px; margin: auto; } 

    Two lines of CSS and you can see that the page looks a bit better as it's no longer using the default fonts.

    Step 6: The Header

    Now let's add some looks to the header: space it a bit, change the font size, and add the background:

    h1 { 
        padding: 100px 10px 20px; 
        margin: 0; 
        background: #dfdfdf; 
        font-weight: normal; 
        font-size: 3em; 

    Notice how we changed the font size—we used em instead of any other unit. This is because of the last of the rules explained in the first part of this series. Users can change the base size of the font and if we had, for example, used px, their settings would not be respected by our stylesheet.

    Step 7: The Menu

    After fixing the header's look, we can get on with the menu. We will also change the font size of the anchors, remove their underline, and add a background when they are hovered over or when they have an "active" class:

    nav { background: #aed8ff } 
    nav a { text-decoration: none; font-size: 1.3em; color: #333; padding: 15px 25px; display: inline-block; } 
    nav a:hover, nav a.active { background: #dfdfdf; color: #666; } 

    Now add the "active" class to the appropriate anchors in your files so they are "pressed" when the page is visited:

    <a href="index.html" class="active">Home</a>

    Here is how it should look like now:

    Step 8: The Content

    We will not do much here, just improve the readability a bit by increasing the line height (don't forget about users' settings—we can change the size of purely visual elements like headers and buttons, but users set their default font size for a reason). We'll also change the font and add some padding:

    p { 
        font-family: Helvetica, Arial, Sans-Serif; 
        line-height: 1.6; 
        text-align: justify; 
        padding: 10px; 

    Here is the result (notice how the readability improved with such a small change):

    Step 9: The Footer

    This will also be just a little, cosmetic change: background, padding, and centered text:

    footer { padding: 10px; background: #dfdfdf; text-align: center; }

    Here is how the footer looks like now:

    Step 10: The Form

    The last thing to do is to fix the looks of our contact form. First, let's remove the padding and margin of the <p> elements:

    form p { margin: 0; padding: 0; }

    Now let's set the width of the <input> elements and <textarea> to be the same. We also set display: block on them to line them up nicely:

    form input, form textarea { width: 300px; display: block; }

    Finally we change the <button>s to take up half of the form's width:

    form button { margin: 10px 0; padding: 5px; width: 148px; } 

    This is the final result:


    This is the end of this part. In the next article, we will use some JavaScript (jQuery to be more exact) to add some interactive elements to our website.

    I guess some of you will think that this tutorial didn't show anything you didn't know about HTML or CSS. But look at it this way: We created a design that is based on its content and not on the designer's fantasy. Of course, it's pretty simple and not very good looking, but I didn't wanted to throw massive amounts of CSS and/or other assets here.

    The point is easy to see if you remove the stylesheet from the document—its layout stays the same and you can still use the page without problems.



    Leave a comment › Posted in: Daily

    1. WordPress Error Handling with WP_Error Class II

      In the first part of this series on handling errors in WordPress with the WP_Error class, we took a look at an introduction of the PHP class, we examined the class properties and methods and their roles and functions complemented by code examples.

      In this final part of the series, we will be building a fairly simple contact form plugin to demonstrate how to handle errors in plugin development. The contact-form plugin will have shortcode and template tag support so it can be implemented in posts and pages using the former and in a theme using the latter. 

      Contact-Form Plugin Development

      The contact form will consist of five form fields - four input elements and a textarea element.

      I'm sure you are familiar with all the contact-form field. Note that when an email is sent via the contact-form, the phone number get appended to the message. This is evident in the send_mail function.

      Let's get started coding the plugin. First the plugin header:

       Plugin Name: Contact Form Lite
       Plugin URI: http://code.tutsplus.com
       Description: Easy contact form plugin
       Author: Agbonghama Collins
       Author URI: http://tech4sky.com

      The plugin will consist of five PHP functions as outlined below.

      1. contact_html_form() will contain the HTML form code of the plugin.
      2. validate_form() handles the plugin error. we will see error handling using WP_Error in action in this function.
      3. send_mail() handles the sending of email.
      4. contact_form_function() brings together and process the above functions
      5. contact_form_shortcode() is the shortcode callback function.

      The HTML form code of the plugin contained in contact_html_form() function  is as follows.

      function contact_html_form() {
          global $name, $email, $phone_number, $subject, $message;
      	echo '<form action="' . get_permalink() . '" method="post">
      	<label for="name">Name <strong>*</strong></label>
      	<input type="text" name="sender_name" value="' . ( isset( $_POST['sender_name'] ) ? $name : null ) . '" />
      	<label for="email">Email <strong>*</strong></label>
      	<input type="text" name="sender_email" value="' . ( isset( $_POST['sender_email'] ) ? $email : null ) . '" />
      	<label for="phonenumber">Phone Number <strong>*</strong></label>
      	<input type="text" name="sender_phonenumber" value="' . ( isset( $_POST['sender_phonenumber'] ) ? $phone_number : null ) . '" />
      	<label for="subject">Subject <strong>*</strong></label>
      	<input type="text" name="email_subject" value="' . ( isset( $_POST['email_subject'] ) ? $subject : null ) . '" />
      	<label for="message">Message <strong>*</strong></label>
      	<textarea name="email_message">' . ( isset( $_POST['email_message'] ) ? $message : null ) . '</textarea>
      	<input type="submit" name="send_message" value="Send" />

      Next is the error handling function validate_form().

      The following are the constraint to be implemented by the plugin which will be enforced by the error handling function.

      Note that:

      • no field should be left empty
      • the name field must contain an alphabetic character
      • the email should be valid
      • the phone number should be numeric

      The validate_form() function will accept the form fields as it argument so it can validate the form data for errors. Below is the code for the error-handling function that enforces the above plugin constraint fully commented so you'll easily trace its code

      function validate_form( $name, $email, $phone_number, $subject, $message ) {
          // Make the WP_Error object global    
      	global $form_error;
      	// instantiate the class
      	$form_error = new WP_Error;
      	// If any field is left empty, add the error message to the error object
      	if ( empty( $name ) || empty( $email ) || empty( $phone_number ) || empty( $subject ) || empty( $message ) ) {
      		$form_error->add( 'field', 'No field should be left empty' );
      	// if the name field isn't alphabetic, add the error message
      	if ( ! ctype_alpha( $name ) ) {
      		$form_error->add( 'invalid_name', 'Invalid name entered' );
      	// Check if the email is valid
      	if ( ! is_email( $email ) ) {
      		$form_error->add( 'invalid_email', 'Email is not valid' );
      	// if phone number isn't numeric, throw an error
      	if ( ! is_numeric( $phone_number ) ) {
      		$form_error->add( 'phone_number', 'Phone-number is not numbers' );
      	// if $form_error is WordPress Error, loop through the error object
      	// and echo the error
      	if ( is_wp_error( $form_error ) ) {
      		foreach ( $form_error->get_error_messages() as $error ) {
      			echo '<div>';
      			echo '<strong>ERROR</strong>:';
      			echo $error . '<br/>';
      			echo '</div>';

      The send_mail function handles the email sending.

      function send_mail( $name, $email, $phone_number, $subject, $message ) {
          global $form_error;
      	// Ensure WP_Error object ($form_error) contain no error
      	if ( 1 > count( $form_error->get_error_messages() ) ) {
      		// sanitize user form input
      		$name 			= 	sanitize_text_field( $name );
      		$email 			= 	sanitize_email( $email );
      		$phone_number 	= 	esc_attr( $phone_number );
      		$subject 		= 	sanitize_text_field( $subject );
      		$message 		= 	esc_textarea( $message );
      		// set the variable argument use by the wp_mail
      		$message 	.= 	'\n Phone Number:' . $phone_number;
      		$to 		= 	'admin@tech4sky.com';
      		$headers 	= 	"From: $name <$email>" . "\r\n";
      		// If email has been process for sending, display a success message	
      		if ( wp_mail( $to, $subject, $message, $headers ) ) {
      			echo "Thanks for contacting me.";

      Let's take a look at what's going on in the send_mail function.

      First, the $form_error object is made global so it can be accessed outside the function scope. A check is made to ensure the $form_error object contains no error message. If true, the contact form input is sanitized.

      The $to variable stores the email address the message sent via the contact form will be sent to. On a standard contact-form plugin, the variable should contain the WordPress administrator email retrieve from the database or from the plugin settings.

      Take note of how the phone number get concatenated to the message.

      Finally, the wp_mail function sends the mail. 

      The contact_form_function() function processes the function and also serve as the plugin template tag.

      function contact_form_function() {
          global $name, $email, $phone_number, $subject, $message;
      	if ( isset($_POST['send_message']) ) {
      		// Get the form data
      		$name 			= 	$_POST['sender_name'];
      		$email 			= 	$_POST['sender_email'];
      		$phone_number 	= 	$_POST['sender_phonenumber'];
      		$subject 		= 	$_POST['email_subject'];
      		$message 		= 	$_POST['email_message'];
      		// validate the user form input
      		validate_form( $name, $email, $phone_number, $subject, $message );
      		// send the mail
      		send_mail( $name, $email, $phone_number, $subject, $message );
      	// display the contact form

      Remember the contact-form plugin is going to have shortcode support. Below is the shortcode call-back function together with the add_shortcode function that registers the shortcode.

      // Register a new shortcode: [cf_contact_form]
      add_shortcode('cf_contact_form', 'contact_form_shortcode');
      // Shortcode callback function
      function contact_form_shortcode() {
          return ob_get_clean();

      Using The Plugin

      Use the shortcode [cf_contact_form] to include the contact-form in a post or page.
      To include the contact-form in your theme, use the template tag <?php contact_form_function(); ?> .


      In this article, we took a look at how to use the WP_Error class to handle errors in plugins. I also showed us a practical use-case on how to handle errors in plugin using the class. You can find the plugin file attached to this article.

      Happy Coding!



      Leave a comment › Posted in: Daily

    1. Magento Theme Development: Template Files

      In this article, we will be covering the basics of Magento template files. We will go over their introduction and do some basic modifications. 

      This will include displaying featured products on the homepage and how to load JavaScript in the footer.

      Following on from our previous article, we have seen that the layout files control each block in a theme and decide what does and doesn't get displayed. But what gets rendered inside of that block is where the template files come into action.

      In this article, we will be focusing on the following directories:

      • Template - app/design/frontend/<package_name>/<theme_name>/template/
      • Locale - app/design/frontend/<package_name>/<theme_name>/locale/

      If you've just joined us please be sure to checkout the previous articles in this series.

      For reference, we've covered:

      1. An Introduction
      2. Layout Files

      Without further a do, let's get started.


      Magento template files are PHTML files made up of a mixture of HTML and PHP, some of which render a page such as 1column.phtml while others render specific blocks within a page such as header.phtml

      For the majority of the time during development of a website these are the files we'll mostly be working with, for front end developers, that is. Once the XML is in place and a template gets called, it is expected that the file will be parsed and displayed accordingly.

      There are hundreds of template files available, knowing which one to edit and then track down the file in the hierarchy can be tricky when first starting out. 

      All is well though, there are a few neat admin area settings which can help us out, they will save us hours of headache!

      Important to note, we can only use the following settings at the "Website" or "Store View" scope, the settings aren't available to us on the "Default Config" scope, so we must remember to change the scope once logged in. This is useful though as it means we can toggle the settings just for a particular website or store view rather than globally.

      Template Hints

      These will quickly identify which files are being loaded for a specific page by showing us the path to the file. Toggling it on or off is a quick setting change in the admin area. 

      Head over to system > configuration. Then in the left hand menu scroll all the way down to the bottom and click "Developer" from under the "Advanced" heading. Once we have changed the scope to "Main Website" we then have the setting available to us under "Debug".

      It would appear that nothing has happened once you've clicked save config, but if you go to the front end of the website, the homepage for example, and refresh the page you will see the hints coming through. 

      With this we now know where the files are located, and if any modifications are required simply copy the file across from base to our theme and modify as necessary.

      We can also set "Add Block Name to Hints" to "Yes" if we want further information, this is generally used for back end development so I wouldn't worry about this setting too much.

      Now, on to the code. I will run through a couple of modifications which are often used in theme development, but again I will only be touching the surface on whats possible.

      1. Displaying featured products on the homepage
      2. Loading JavaScript in the Footer

      Let's get started...

      1. Displaying Featured Products on the Homepage

      This point has to be the most common request on any website, everyone wants to show off a handful of products on the landing page of their site right?

      It's actually much easier than you'd imagine, with a combination of XML and PHP we can achieve this in no time. There are, as with many things in Magento, more than one way of doing this. I'm going to show you what I think is the easiest method.

      First up, we need to create our category in the admin area that will hold our products. Once logged in head over to catalog > manage categories. For this example, we will create a subcategory under root, so we need to click on "Root Catalog" and then click on the "Add Subcategory" button. Enter a title for the category, make sure "Is Active" is set to "Yes" and then click "Save Category".

      Make a note of the category ID number at the top as we will be needing this later on:

      This will be a good time to also add some products to the category we have just created. To do this click on the "Category Products" tab and select the products you want to display, not forgetting to click "Save Category" once we have finished.

      Next up, we need to create our template where our foreach loop will be run.

      For this we will base it off the product list template which has all the necessary code already done for us, we just need to make a few adjustments to suit our needs.


      Copy to:


      We will then make some modifications to our file.

      1. Load in our product collection via the category ID
      2. Only display one view, I have picked the grid view but feel free to change this
      3. Remove the toolbar as this is no longer needed
      4. Add in our category name for a heading

      The finished file will look like the following:

       * Product list template
       * @see Mage_Catalog_Block_Product_List
          $_categoryId = 35;
          $_category = new Mage_Catalog_Model_Category();
          $_productCollection = $_category->getProductCollection();
      <h2><?php echo $_category->getName(); ?></h2>
      <?php if(!$_productCollection->count()): ?>
          <p class="note-msg"><?php echo $this->__('There are no products matching the selection.') ?></p>
      <?php else: ?>
          <div class="category-products">
              <ul class="products-grid">
                  <?php foreach ($_productCollection as $_product): ?>
                      <li class="item">
                          <a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $this->stripTags($this->getImageLabel($_product, 'small_image'), null, true) ?>" class="product-image">
                              <img src="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(135); ?>" width="135" height="135" alt="<?php echo $this->stripTags($this->getImageLabel($_product, 'small_image'), null, true) ?>" />
                          <h2 class="product-name">
                              <a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $this->stripTags($_product->getName(), null, true) ?>">
                                  <?php echo $_product->getName(); ?>
                          <?php if($_product->getRatingSummary()): ?>
                              <?php echo $this->getReviewsSummaryHtml($_product, 'short') ?>
                          <?php endif; ?>
                          <?php echo $this->getPriceHtml($_product, true) ?>
                          <div class="actions">
                              <?php if($_product->isSaleable()): ?>
                                  <button type="button" title="<?php echo $this->__('Add to Cart') ?>" class="button btn-cart" onclick="setLocation('<?php echo $this->getAddToCartUrl($_product) ?>')"><span><span><?php echo $this->__('Add to Cart') ?></span></span></button>
                              <?php else: ?>
                                  <p class="availability out-of-stock"><span><?php echo $this->__('Out of stock') ?></span></p>
                              <?php endif; ?>
                              <ul class="add-to-links">
                                  <?php if ($this->helper('wishlist')->isAllow()) : ?>
                                      <li><a href="<?php echo $this->helper('wishlist')->getAddUrl($_product) ?>" class="link-wishlist"><?php echo $this->__('Add to Wishlist') ?></a></li>
                                  <?php endif; ?>
                                  <?php if($_compareUrl=$this->getAddToCompareUrl($_product)): ?>
                                      <li><span class="separator">|</span> <a href="<?php echo $_compareUrl ?>" class="link-compare"><?php echo $this->__('Add to Compare') ?></a></li>
                                  <?php endif; ?>
                  <?php endforeach ?>
      <?php endif; ?>

      Don't forget to change the value of the $_categoryId variable to your category ID.

      Lastly we just need to create an XML block that will load in the template we have created above. We will do this in our local.xml file like so:

      <?xml version="1.0"?>
      <layout version="0.1.0">
              <reference name="content">
                  <!-- home featured products -->
                  <block type="catalog/product_list" name="home.featured.products" after="-" template="catalog/product/list-home-featured.phtml" />

      That's all there is to it, pretty straight forward right? Below is a screenshot of the finished product.

      2. Loading JavaScript in the Footer

      For starters, we would think Magento already has this ability built in through the XML when we add our scripts, some sort of parameter we could pass in, but we would be wrong - Magento isn't going to make it that easy for us!

      WordPress, on the other hand, does this perfectly via the wp_register_script. Maybe a back end developer will pick up on this and add in the ability to pass through an additional XML parameter, now there's a side project for someone to get cracking with. 

      Any takers?

      So, fortunately for now there is an alternative method to getting this to work.

      I think it's important to cover this topic as it will improve the speed of our site which everyone wants. I tend to leave Magento core JavaScript files left as they are in the <head>, I may minify them but apart from that they remain as they are.

      Anything we add in on top of Magento, such as jQuery and our own custom functions there is no harm in loading these in the footer. When developing a website I tend to keep a keen eye on the <head> tag, when a third party module gets installed it usually adds something in here. With a bit of work we can edit the third party module XML and point it to load in the footer - it's well worth the extra five minutes doing so!

      First we need to create an XML block in our local.xml file within the default layout handle like so:

      <?xml version="1.0"?>
      <layout version="0.1.0">
              <reference name="root">
                  <!-- adds ability to load js in the footer -->
                  <block type="page/html_head" name="footer.js" as="footer.js" template="page/html/footer-js.phtml">
                      <action method="addItem"><type>skin_js</type><name>js/build/jquery.min.js</name></action>

      Notice we are using the same method of adding JavaScript files as we did in the previous article. If you need a refresher click here, for demonstration purposes we will add in a local copy of jQuery.

      Now we can go about creating our template file. Create a new file in:


      with the following content:

      <?php echo $this->getCssJsHtml() ?>

      Lastly we need to add a single line of code into our template files just before the closing </body> tag.

      Our template files can be found at app/design/frontend/base/default/page/ not forgetting to copy them over to our own theme. There are multiple template files, I have collated a list together below:

      • 1column.phtml
      • 2columns-left.phtml
      • 2columns-right.phtml
      • 3columns.phtml

      Below is an example of how it should look:

              <?php echo $this->getAbsoluteFooter() ?>
              <!-- adds ability to load js in the footer -->
              <?php echo $this->getChildHtml('footer.js') ?>

      With all the steps now complete if we refresh our page and view source we will now see the script being loaded in just before the closing </body> tag.

      If you've made it this far I think a congratulations is in order! There is a lot to take in one sitting but hopefully it's all starting to make sense.

      Wrapping It Up!

      This series is only the tip of the iceberg, Magento is a very powerful platform and has much more to offer than what we have covered. I hope it has given you an insight into the theme principles of Magento and that you can put it to good use.

      There's no better way to learn Magento but to just get stuck in, you'll learn the ropes in no time.

      As always I'm more than happy to assist if you need a hand with anything. Also be sure to checkout my Magento Boilerplate which has a whole bunch of goodies inside.

      Until next time.



      Leave a comment › Posted in: Daily

    1. New Course: Linux Web Developer Setup

      What You'll Learn

      If you've ever wanted to get started developing with Linux, then our new Linux Web Developer Setup course is ideal for you. Get acquainted with the Linux system, understand its mechanics, and learn how you can set up an environment that supports your development. 

      Tuts+ instructor José Mota will take you through the whole process from installing Linux to learning how you can use it to do your web development work. He'll show you how to maintain your Linux desktop and how it integrates with other systems, and you'll also learn some of the key tools you need for development with popular languages like Ruby, JavaScript, and PHP.

      By the end of this course you’ll be ready to start using Linux for all your web development projects. 

      Start Learning With a 14 Day Free Trial

      You can take our new Linux course straight away with a completely free 14 day trial of a Tuts+ subscription. Start your free 14 day trial today, to access this course and hundreds of others.



      Leave a comment › Posted in: Daily

    1. Create a Custom Page in OpenCart

      Before getting started, note that we're planning specifically on jumping right into the article. 

      To that end, we're assuming that you have a working copy of OpenCart installed and are ready to get to work.

      The Basic Workflow

      OpenCart is built using the popular programming MVC pattern. There is also one more element added to this pattern named "L" - a language part - so it's called MVC-L pattern in OpenCart. I won't go into the details of the MVC pattern as it's a very popular and familiar design pattern and we've covered it in great detail in other tutorials. 

      That said, we still need to look at the workflow using this pattern.

      First, the controller acts as an entry point for any page in which you'll define most of the application logic. The model deals with the back-end database, and the view is responsible for preparing the content to be rendered to the end user. In the context of OpenCart, you'll at least need to implement a controller and a view in order to create a new custom page.

      Setting Up the Controller

      First, let's try to understand the role of the controller in OpenCart. The controller is the first element that will get executed when you request any page. Primarily, it's responsible for setting up the variables which will be later on used in the view for the display. Although in the generic controller, there are a lot of things happening:

      • You can load language files so that you can use language variables for the static text display.
      • You can load model files so that you can use methods defined in those models to fetch data from the back-end database.
      • You can define the template file which will be used by the view.
      • You can set up the custom variables by assigning them content which will be used in the template file.
      • You can declare the children templates which you would like to display as a part of the main template. The simplest example of this is the header and footer templates which you would like to display in your main template.
      • Finally, you can also set values for the stuff like document title, meta description etc.

      Enough theory, right? Let's see how our custom controller looks like. Go ahead and create a new directory custompage underneath catalog/controller. Create a new file mycustompage.php underneath catalog/controller/custompage. Paste the following code in the newly created controller file "mycustompage.php".

      class ControllerCustompageMycustompage extends Controller {
        public function index() {
          // set title of the page
          $this->document->setTitle("My Custom Page");
          // define template file
          if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/custompage/mycustompage.tpl')) {
            $this->template = $this->config->get('config_template') . '/template/custompage/mycustompage.tpl';
          } else {
            $this->template = 'default/template/custompage/mycustompage.tpl';
          // define children templates
          $this->children = array(
          // set data to the variable
          $this->data['my_custom_text'] = "This is my custom page.";
          // call the "View" to render the output

      Let's understand the naming convention of the controller class. The controller class name is constructed by following the directory structure and camel case convention. Notice that the class name begins with "Controller" keyword followed by the directory name ("Custompage") in which the class file resides. And finally the name of class file ("Mycustompage") is appended at the end. Now let's dissect each section in detail.

      First we've set the value of the html title tag for our custom page.

      $this->document->setTitle("My Custom Page");

      In the next section, we've defined the template file name which will be used by the "View" element. An important thing to note here is that we have first checked that if the template file is available in the custom theme set from the back-end, if it's available in the custom theme we'll use that otherwise we'll use the template file in the "default" theme. 

      This is the concept of template overriding.

      if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/custompage/mycustompage.tpl')) {
        $this->template = $this->config->get('config_template') . '/template/custompage/mycustompage.tpl';
      } else {
        $this->template = 'default/template/custompage/mycustompage.tpl';

      We have also defined the children templates using the array. As an example, common/header maps to the template file located at catalog/view/theme/default/template/common/header.tpl and executes the same. Result of that will be assigned to $header variable which you can use in your template file to display the site header.

      $this->children = array(

      Furthermore, we've demonstrated how you can set up the custom variables which will be available in the template file. Although we have used a simple static text here, you could assign a more sensible content, say for example a products array fetched from the

      $this->data['my_custom_text'] = "This is my custom page.";

      Finally, the most important thing is to call view so that the actual rendering process can begin.


      So that's the glimpse of controller workflow.

      In the front-end, you'll access this controller by using the query string variable  route=custompage/mycustompage. It's important to note here is that if you define the controller method with any other name except index you need to specify that as well in the URL. 

      For example, if you have created method named custom, your front-end URL format should look like route=custompage/mycustompage/custom.

      Let's understand how OpenCart maps any url to the specific controller file. The format of the route variable is {directory}/{filename}/{methodname}. {directory} maps to the directory under catalog/controller. {filename} maps to the name of the controller file under catalog/controller/{directory}. And finally, it'll look for the controller method named {methodname} if it's specified in the route, otherwise it'll call the default index method.

      Prepare the View

      In this section, we'll create the view template file which we defined earlier in the controller index method. Go ahead and create a new directory custompage underneath catalog/view/theme/default/template. Create a new file mycustompage.tpl underneath catalog/view/theme/default/template/custompage. Paste the following content in the newly created template file mycustompage.tpl.

          echo $header;
          echo $column_left;
          echo $column_right; ?>
          <div id="content">
                  echo $content_top;
                  echo $my_custom_text;
                  echo $content_bottom;
      <?php echo $footer; ?>

      So this is our main layout template file which is responsible for displaying the content of our custom page. In this template file, we have just used the variables we've set up in the controller's index method. 

      The only custom variable in this template file is $my_custom_text, rest of the variables contain the contents related to the children templates like header, footer etc. The variables $column_left, $column_right, $content_top and $content_bottom are used to display the modules assigned to our custom page from the back-end.

      If you want to assign modules to our custom page, first you need to create a new layout entry from the back-end. After you have added a new layout, you would like to add a route such as custompage/mycustompage entry for that layout. Now you can assign any module to our custom page as well.

      You have just built a complete custom page in the OpenCart! You can check the same at URL: http://www.yoursiteurl.com/index.php?route=custompage/mycustompage.

      Custom Page Layout


      In this tutorial, we've learned how to create our own custom page in OpenCart. If you are familiar with the MVC pattern, the workflow to create a new custom page should be familiar.

      Go ahead and explore few core files to get familiar with the code. I would like you to extend our example by loading model and language files in the controller and see how things work! Awaiting for the feedback, questions, and comments!



      Leave a comment › Posted in: Daily

  • Page 3 of 32 pages  < 1 2 3 4 5 >  Last ›
  • Browse the Blog