Try Tuts+ Premium, Get Cash Back!
HMVC: an Introduction and Application

HMVC: an Introduction and Application

Tutorial Details
  • Technologies: HMVC, PHP, CodeIgniter
  • Difficulty: Intermediate
  • Estimated Completion Time: 60 minutes

This tutorial is an introduction to the Hierarchical Model View Controller(HMVC) pattern, and how it applies to web application development. For this tutorial, I will use examples provided from the CodeIgniter from Scratch series and demonstrate how HMVC can be a valuable modification to your development process. This introduction assumes you have an understanding of the Model View Controller (MVC) pattern. We suggest you read our introduction to MVC to get acquainted with the topic before tackling this tutorial.


What is HMVC?

HMVC is an evolution of the MVC pattern used for most web applications today. It came about as an answer to the salability problems apparent within applications which used MVC. The solution presented in the JavaWorld web site, July 2000, proposed that the standard Model, View, and Controller triad become layered into a “hierarchy of parent-child MCV layers“. The image below illustrates how this works:

Each triad functions independently from one another. A triad can request access to another triad via their controllers. Both of these points allow the application to be distributed over multiple locations, if needed. In addition, the layering of MVC triads allows for a more in depth and robust application development. This leads to several advantages which brings us to our next point.


Why should I use HMVC?

Key advantages to implementing the HMVC pattern in your development cycle:

  • Modularization: Reduction of dependencies between the disparate parts of the application.
  • Organization: Having a folder for each of the relevant triads makes for a lighter work load.
  • Reusability: By nature of the design it is easy to reuse nearly every piece of code.
  • Extendibility: Makes the application more extensible without sacrificing ease of maintenance.

These advantages will allow you to get M.O.R.E out of your application with less headaches.


Setting up HMVC in CodeIgniter

To add extra depth to the CodeIgniter from Scratch series, we will be viewing today’s examples in CodeIgniter. I will lead us though the steps needed to get CodeIgniter working with HMVC. Once we’re done with that, I’ll provide a couple of examples. Let’s begin!

Preface

To run web applications, you need a web server on your computer if you are not working remotely. Here are recommendations with links to installation instructions:


Step 1. Download and Install CodeIgniter

Go to codeigniter.com and click the “Download CodeIgniter” link. If you know how to install it and want to skip past this step click here

Extract the contents of the zip file to your web server’s document root.

Rename the “CodeIgniter_1.7.2” folder to “hmvcExample“.

Move the “hmvcExample/system/application” folder to “hmvcExample/application“. This is common practice with CodeIgniter. The purpose of doing this is to separate the application from the core of the framework. We should now have a directory that looks like the image below:

Open “hmvcExample/application/config/config.php” in your editor of choice.

Edit the site base url to match the location of your install. In my case I would change

$config['base_url'] = "http://example.com/";

into

$config['base_url'] = "http://localhost/hmvcExample/";

Save your changes and close “hmvcExample/application/config/config.php

Test that we have a working version of CodeIgniter. Open your browser and check your “http://yourhost/hmvcExample/”.
You should be greeted with the “Welcome to CodeIgniter” screen below:

That’s it! You have successfully downloaded and installed CodeIgniter. Now we will move on to making it work with the HMVC extension.


Step 2. Download and Install HMVC Extension

Download version 5.2 of the modular extension from the CodeIgniter Wiki.

In the contents of the zip file are three php files:

Move these three files into the “hmvcExample/application/libraries/” folder.

Recheck your browser. You should still see the Welcome to CodeIgniter screen.

It’s time to add the modules. Create the following directory structure “application/modules/welcome/controllers/“.

Move the “application/controllers/welcome.php” to “application/modules/welcome/controllers/welcome.php“.

Recheck your browser. You should still see the Welcome to CodeIgniter screen.

Create the folder “application/modules/welcome/views/

Move the “application/views/welcome_message.php” to “application/modules/welcome/views/welcome_message.php“.

Do a final check on your browser. You should still see the Welcome to CodeIgniter screen.

That’s it! Modular Extensions is installed correctly.


Login Module Example

Now that we have our HMVC enabled instance of CodeIgniter, I will demonstrate some short examples. For our first example I will show how you can apply user access restrictions to pages or entire modules.

Download and unzip CodeIgniter from Scratch Day 6 source files into your web server. You should end up with a folder called “ci_day6/” alongside our “hmvcExample/

Create the “login” module in our “hmvcExample/application” directory. It should end up looking like this

	hmvcExample/application/modules/login/controllers/
	hmvcExample/application/modules/login/models/
	hmvcExample/application/modules/login/views/

Create the “site” module in our “hmvcExample/application” directory. It should end up looking like this

	hmvcExample/application/modules/site/controllers/
	hmvcExample/application/modules/site/models/
	hmvcExample/application/modules/site/views/

TIP: When working with modules I keep a folder named RENAME with the three empty folders controllers, models and views. This saves me a little bit of time anytime I wish to create a new model.

Now we copy over the login module files from “ci_day6/” to our “hmvcExample/“.

	ci_day6/application/controllers/login.php
	ci_day6/application/models/membership_model.php
	ci_day6/application/views/login_form.php
	ci_day6/application/views/signup_form.php
	ci_day6/application/views/signup_successful.php

Copy/Move each of the above files over as listed below

	hmvcExample/application/modules/login/controllers/login.php
	hmvcExample/application/modules/login/models/membership_model.php
	hmvcExample/application/modules/login/views/login_form.php
	hmvcExample/application/modules/login/views/signup_form.php
	hmvcExample/application/modules/login/views/signup_successful.php

Next we copy over the site module files from “ci_day6/” to our “hmvcExample/“.

	ci_day6/application/controllers/site.php
	ci_day6/application/views/logged_in_area.php

Copy/Move each of the above files over as listed below

	hmvcExample/application/modules/site/controllers/site.php
	hmvcExample/application/modules/site/views/logged_in_area.php

The last files to copy over are the global views and CSS and image files. The asterisk (*) denotes folder and all its contents including sub folders

ci_day6/css/*
ci_day6/img/* 
ci_day6/application/views/includes/*

Copy each of the above folders and all their content over as listed below

hmvcExample/css/*
hmvcExample/img/*
hmvcExample/application/views/includes/*

Open “hmvcExample/application/config/autoload.php” and edit it to look like the this:

$autoload['libraries'] = array('database', 'session');	// Need to Autoload DB and Session
/*
| -------------------------------------------------------------------
|  Auto-load Helper Files
| -------------------------------------------------------------------
| Prototype:
|
|	$autoload['helper'] = array('url', 'file');	
*/

$autoload['helper'] = array('url', 'form');		// Need to autoload url and form.

If you have not already done so from step one, open “hmvcExample/application/config/config.php” and edit it so that the base url is set to your appropriate location.

$config['base_url'] = "http://localhost/hmvcExample/";	// web address. WARNING keep trailing / 

Open “hmvcExample/application/config/database.php” and add the appropriate links to your database.

$db['default']['hostname'] = "localhost";		// location of DB server
$db['default']['username'] = "YOUR USERNAME HERE";	// username you use to connect
$db['default']['password'] = "YOUR PASSWORD HERE";	// associated password
$db['default']['database'] = "ci_series";		// The database you want to use

Open your browser to test that the login page displays “http://localhost/hmvcExample/index.php/login

Now to make this login function, we need to create the membership database table. For this, we need to create a table in your PHPMyAdmin.

Select or create your “ci_series” database.

In the sQL tab, paste the code below into the textarea and click go

CREATE TABLE  `ci_series`.`membership` (
`id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`first_name` VARCHAR( 32 ) NOT NULL ,
`last_name` VARCHAR( 32 ) NOT NULL ,
`email_address` VARCHAR( 64 ) NOT NULL ,
`username` VARCHAR( 32 ) NOT NULL ,
`password` VARCHAR( 32 ) NOT NULL
) ENGINE = MYISAM ;

With the membership table created, we click on the create account link on the login page and add a user to the database.

Login in as the user and confirm that you are now in the “site/members_area” of the site. It should look similar to the image below:

Click “logoff” link and try to manually go back to the members area. you will see that you no longer have permission to do so.

So we have our triads grouped, but we are still not quite in HMVC mode yet. In the site controller we find a function called is_logged_in().

	function is_logged_in()
	{
		$is_logged_in = $this->session->userdata('is_logged_in');
		if(!isset($is_logged_in) || $is_logged_in != true)
		{
			echo 'You don\'t have permission to access this page. Login';	
			die();		
		}		
	}

This is a login related function. In MVC mode, this is required because site cannot access login. With HMVC we can fix this.

Cut the is_logged_in() function out of “applications/modules/site/controllers/site.php

Save site.php without the is_logged_in() function.

Open “applications/modules/login/controllers/login.php“.

Paste the is_logged_in() function into the class.

Save login.php

Open “applications/modules/site/controllers/site.php“.

	function __construct()
	{
		parent::Controller();
        $this->is_logged_in();
	}

In the __Construct() function, we make the HMVC call to login’s is_logged_in() function, as seen below:

	function __construct()
	{
		parent::Controller();
        // Format: modules::run('module/controller/action', $param1, $param2, .., $paramN);
        modules::run('login/is_logged_in');
	}

MVC 101 Complete

There you have it! We have successfully altered day six code into HMVC format. The site module now requests the login check instead of having to use its own. While outwardly we observe no difference, the site design has fundamentally been changed. All login functions are now where they belong: inside the login triad. This may seem like a lot of work with small reward but it is not so. Any login changes can be made once. The internal structure of the triad can be edited without having to change the entire application in response. Code replication for other controllers is no longer required. Last but not least, all the related code is in one handy location. This tiny step may not WOW you but when we delve deeper into bigger, complex applications, the M.O.R.E. apparent it will become how effective the HMVC pattern is.


Members Section Example

We are now going to uncover more of HMVC’s power. We just demonstrated how to call a module from a controller. There are other places you can do that as well. HMVC was build with the User Interface (UI) in mind. We get to call modules from our views as a result. This is where the power of HMVC can really shine.

When calling HMVC from a view you will use the same modules::run(). There is only one requirement when doing this. The resulting output from the call must be a html snippet and not a complete view. This is because we are already inside a view at the time we call the run function. We will see this in action down the page as we edit the site module views.


Step 1. Edit Login Controller

We are going to create a block which appears on the top of every page with our user’s name, important links, and logout option. Widgets like this are commonplace on sites today. The image below illustrates the end result.

Open “applications/modules/login/controllers/login.php“.

    function cp()
    {
        if( $this->session->userdata('username') )
        {
            // load the model for this controller
            $this->load->model('membership_model');
            // Get User Details from Database
            $user = $this->membership_model->get_member_details();
            if( !$user )
            {
                // No user found
                return false;
            }
            else
            {
                // display our widget
                $this->load->view('user_widget', $user);
            }			
        }
        else
        {
            // There is no session so we return nothing
            return false;
        }
    }

Paste/Write the code above into the login controller.

cp() receives information from the membership_model function, get_member_details(), which we create in the next step. If a user is found we will display the view snippet detailed in step three. From there we should get the desired block illustrated above.

Save the changes you made to login.php


Step 2. Edit Membership Model

You will notice that we called a get_member_details() from the membership_model. This function gets our user information from the database and will be accessed from a few different sources. We are going to work on that now.

Open “applications/modules/login/models/membership_model.php“.

	function get_member_details($id=false)
	{
		if( !$id )
		{
			// Set Active Record where to the current session's username
			if( $this->session->userdata('username') )
			{
				$this->db->where('username', $this->session->userdata('username'));
			}
			else
			{
				// Return a non logged in person from accessing member profile dashboard
				return false;
			}
		}
		else
		{
			// get the user by id
			$this->db->where('id', $id);
		}
		// Find all records that match this query
		$query = $this->db->get('membership');
		// In this case because we don't have a check set for unique username 
		// we will return the last user created with selected username.
		if($query->num_rows() > 0)
		{
			// Get the last row if there are more than one
			$row = $query->last_row();
			// Assign the row to our return array
			$data['id'] = $row->id;
			$data['first_name'] = $row->first_name;
			$data['last_name'] = $row->last_name;
			// Return the user found
			return $data;
		}
		else 
		{
			// No results found
			return false;
		}

Comment your code! It’s a best practice and will help others understand what you wrote.

Line 01: The function call has a default variable $id. This allows us an option of finding a user by ID rather than by username. This made optional by setting it to false in the declaration.

The rest of the function is straight forward and well commented. We query the membership table for a user via username or ID. The result is saved to the $data array and returned. All other outcomes return false.

Save the changes you made to membership_model.php


Step 3. Create User Widget View

The third and final piece to the widget we are creating is the xhtml snippet, which we can put into any other view. This is called by the login controller’s cp() function which we just wrote.

Open “applications/modules/login/views/user_widget.php“.

<code style="font-family: Monaco, Verdana, Sans-serif; 
                 font-size: 12px; 
                 background-color: #f9f9f9; 
                 border: 1px solid #D0D0D0; 
                 color: #002166; 
                 display: block; 
                 margin: 14px 0 14px 0; 
                 padding: 12px 10px 12px 10px;">
	<?php echo $first_name.' '.$last_name; ?> &middot; 
	<?php echo anchor('site/members_area', 'Dashboard'); ?> | 
	<?php echo anchor('site/profile/'.$id, 'Profile'); ?> | 
    <?php echo anchor('site/messages/'.$id, 'Messages'); ?> | 
	<?php echo anchor('login/logout', 'Logout'); ?>
</code>

Note: It is not a good practice to use inline styling. I opted to put this one instance of inline style for the sake of remaining on topic.

This styled code block takes the information passed from the cp() function. We generate the links using CodeIgniter’s URL helper’s anchor() function. More information about the user guide can be found on codeigniter.com.

After working on those three files we will test the “login/cp” page. We should see something like the image below. Note: You need to be logged int to see it. Be sure to do so before checking the page or you will see nothing.


Step 4. Edit Site Controller

The links in the snippet to profile and messages will return an error for the moment. This is ok because we have not created those functions yet. Lets do that now.

Open “applications/modules/site/controllers/site.php“.

<?php
class Site extends Controller 
{
	function __construct()
	{
		parent::Controller();
	}

	function members_area()
	{
		modules::run('login/is_logged_in');
		$this->load->view('logged_in_area');
	}

__construct()
For the purpose of this example we shall remove the…

modules::run('login/is_logged_in');

…from the function so that we can make specific parts private and have other parts public.

members_area()
We want only logged in users to access the members dashboard area. So we will use the modules:run HMVC function and call the is_logged_in check from the login controller. We then load the logged_in_area view file which will be edited further down the page.

	function messages()
	{
		modules::run('login/is_logged_in');
		$this->load->model('login/membership_model');
		$user = $this->membership_model->get_member_details($this->uri->segment(3));
		if( !$user )
		{
			// No user found
			return false;
		}
		else
		{
			// display our widget
			$this->load->view('member_messages', $user);
		}				
	}

messages()
Like members_area(), we only want logged in users so we have included the is_logged_in check. We have already written the code on how to get user details from the database so we will load the login model, membership_model. This will allow us to get the user information via the get_member_details() function. The third URI segment being passed into that function is an id for the user we wish to get messages for. For example, if the url was:


http://localhost/hmvcExample/index.php/site/messages/43

Then our function get_member_details() would be receiving “43″ as an input variable. Depending on the result of get_member_details(), we are either shown the view: member_messages or we get nothing (as a result of a failed query).

	function profile()
	{
		$this->load->model('login/membership_model');
		$user = $this->membership_model->get_member_details($this->uri->segment(3));
		if( !$user )
		{
			// No user found
			$data['main_content'] = 'member_profile';
			$data['notice'] = 'you need to view a profile id';
			$this->load->view('includes/template', $data);
		}
		else
		{
			// display our widget
			$user['main_content'] = 'member_profile';
			$this->load->view('includes/template', $user);
		}		
	}
}

profile()
Just like any social network; we want the profile pages to be public. So we have not included the is_logged_in check. Just like messages, we call the login triad’s membership_model and query the database for our desired user. In this case, if no user is found, we quit a bit more gracefully. We also notify the visitor that an id needs to be specified. With a successful result, we see the member’s profile.


Step 5 Edit Logged In Area View

Open “applications/modules/site/views/logged_in_area.php“.

<!DOCTYPE html>
<html lang="en">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
	<title>untitled</title>
</head>
<body>
	<?php echo modules::run('login/cp');?>
	<h2>Welcome Back, <?php echo $this->session->userdata('username'); ?>!</h2>
     <p>This section represents the area that only logged in members can access.</p>
</body>
</html>	

Overwrite the contents of the file with the code above.

Line 08: HMVC is put into action here. Our view calls the “login/cp” function, and echoes out the html snippet exactly where we tell it. Notice how we didn’t have to prepare anything ourselves? It’s all handled internally by login for us. Handy isn’t it?

Save the changes you made to logged_in_area.php. Your finished page should display like:


Step 6. Create Member Messages View

Create a new view: “applications/modules/site/views/member_messages.php“.

<!DOCTYPE html>
<html lang="en">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
	<title>untitled</title>
</head>
<body>
	<?php echo modules::run('login/cp');?>
	<h2><?php echo $first_name; ?>'s Messages</h2>
     <p>This could be where the messaging system gets displayed</p>
</body>
</html>	

Write or paste the code above into the newly created file.

This view is pretty much just a clone of the members area to test that login holds on multiple pages. There is one difference: we fished some information from the login module’s membership_model. This is shown as the $first_name variable.

The point of getting user information here would be to pass it on to a module which would return a snippet with the user’s messages.

Save the changes you made to member_messages.php. Your finished page should display like:


Step 7. Create Member Profile View

Create a new view: “applications/modules/site/views/member_profile.php“.

	<?php echo modules::run('login/cp');?>
    <?php if( isset($notice) ): ?>
    <h2>Member Profile Pages</h2>
    <p><?php echo $notice; ?></p>
    <?php else: ?>
	<h2><?php echo $first_name; ?>'s Profile</h2>
     <p>Put all the good wholesome profile info here!</p>
	<?php endif; ?>

Write or paste the code above into the newly created file.

We have an if statement which detects whether a user was found or not. If not, we get brought to an error page stating we need an ID to view a profile.

Again, we retrieve the user information. Just like messages we would use this to retrieve the user’s friend list, latest blog entry, and activity feed, etc.

Save the changes you made to member_profile.php. Your finished page should display like:

What Happens When We Logoff?

Because we want the profile pages to be public, it should still display. Minus the user widget of course.

When logged in, and we go to profile without a third uri segment we see our own profile. Logded off, we will be shown the error below.

We should not be able to view the message or dashboard. When we check the messages page we are greeted with this:

We’re Done

That’s it! We have added more depth to our initial example and demonstrated the different ways to use HMVC.

  • Call modules::run() from a controller.
  • Echo modules::run() from a view to display a HTML snippet.
  • Load a model from another module.

I hope this has been an enlightening experience. HMVC is an extraordinary pattern which makes applications more robust. It is well worth the investment. Give it a try. I promise you won’t ever want to go back to vanilla MVC!

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.mattborja.com/ Matt Borja

    Hey, thanks for the great introductory crash course to HMVC. I was actually led to this tutorial doing some casual research on Modular Extension. What turned me on to ME was a prior research (all us developers seem to be doing these days to keep ourselves in business) to further extend an existing statically built platform for a project now 9 months along. By static, I mean hard coded PHP from the ground up.

    I decided to poke into PyroCMS as a possible base for our current CMS needs and figured I would extend that as I was familiar enough with CodeIgniter. However, I was not familiar with the HMVC concept until I saw that things weren’t arranged the CodeIgniter from Scratch way in PyroCMS. Took me about an hour to realize where everything was at and then picked up from there to hunt down whatever extension or library was being used. Turns out it was an implementation of HMVC using Modular Extension. Not sure if they’re still using it.

    While PyroCMS doesn’t seem to fit the bill adequately as a base for what we’re building, I certainly have a much clearer understanding of HMVC and will conclude with saying that it really doesn’t matter what framework you use so long as it gets the job done efficiently and the final product is just as efficiently executed. For us, CodeIgniter works perfect – mainly because they had better documentation, better support, better implementation, better core, better models, better controllers, better…jk :-P

    Thanks for the great write up! You might want to look at your “You don’t have permission to access this page.” Login is broken and needs to be updated

    Line 41 of application/modules/login/controllers/login.php should read:

    echo ‘You don\’t have permission to access this page. <a href=”‘.site_url().’/login”>Login</a>’;

    • http://philsturgeon.co.uk/ Phil Sturgeon

      Hey Matt,

      We don’t use HMVC in PyroCMS, just “modular MVC”. It’s not that crazy, we just group our MVC into modules instead of putting them all mangled in together.

      HMVC involves the idea of calling other modules like a separate request, instead of just re-arranging your folders.

      Hope that clears up some of the confusion. :)

      • http://gyanmoti.in Nirmal

        Phil, I have been reviewing the internal of the pyroCMS version 2.1.2. Does this version uses HMVC approach?

        Thanks

  • http://www.mattborja.com/ Matt Borja

    Just in case anyone here is inquiring on how to get Modular Extensions – HMVC 5.3 implemented retroactively, there are a few additional steps involved.

    1. The obvious? Start with a fresh CodeIgniter installation (just in case). The not so obvious? Locate the actual download for 5.3. Since wiredesignz moved the project code to bitbucket, you’ll need to use the get source menu (top right of file listing). Here’s the download link for your convenience:

    http://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc/get/a8621f848a0f.zip

    2. Follow the Wiki instructions to extract the files to their respective destinations. Drop Modular Extensions libraries into application/libraries (and in version 4.2 only application/helpers directories) as specified. Drop Modular Extensions libraries into the application/core directory for CI 2.0

    3. There is also a third_party folder also part of the archive you will need to drop into your application/ folder.

    4. Once you have this setup, you will need to go back through and update all your controllers to extend MX_Controller rather than Controller. For example: class Site extends MX_Controller

    5. If you have a constructor method (or __construct itself), that’s fine. However, it appears the parent::Controller statement we’re all familiar with no longer applies with Modular Extensions 5.3. Simply comment it out and refresh your site.

    6. That’s it!

    I went through the HMVC tutorial, made a copy, stripped out the 5.2 files and installed the 5.3 files. Updated my controllers as outlined here and everything seems to be working just fine. Hope someone else will find this useful.

    My little contribution back to the developer community there. Happy modulating!

    • Barry Cogan
      Author

      Thank you for that Matt, I’ll go ahead and update the tutorial to reflect those changes and the current state of Modular extensions :)

    • Ruuter

      I’d add to Matt Borja comment point 4:

      You also need to change your models to CI_Model instead of just Model and not to MX_Model.

      So clearly:
      change all models to: (for example. membership_model.php)
      class Membership_model extends CI_Model

  • http://www.vancelucas.com Vance Lucas

    If you’re looking for a native HMVC framework with a modular organization, check out Alloy:
    http://alloyframework.org

    Kohana3 is also native HMVC:
    http://kohanaframework.org

  • santi

    There’s a typo at the beginning: salability

  • Wiredesignz

    @Barry, Very nice tutorial. Good work man. It’s nice to see so many people appreciate your work.

    • Barry Cogan
      Author

      Mine is but a small contribution next to yours!
      With your your work I would not have been able to write this tutorial with CodeIgniter!

  • david2tm

    Hi,
    I’ve installed that I believe is the latest version of HMVC from here: http://goo.gl/wKIy
    and followed the installation (welcome part works fine)

    but after applying your tutorial, I get error:
    “Unable to locate the file: login_form.php”

    also, then I follow “Login” link from “/index.php/site” it leads to “/login” which is not working until I fix it manually to “/index.php/login”

    PS
    I’m new to ci, trying to learn it…

  • andy78

    I’m using the latest version: Modular Extensions – HMVC 5.3 and can more or less get this to work but there is one important aspect left out of your tutorial – What if you don’t want people to be able to access the widget directly from the url?

    For example if your widget is part of a side bar you don’t want people to be able to go to http://yourdomain/login/cp and access the widget on its own. How do you prevent this? and say the widget is the login view how do you get form validation errors to then display in the widget view and not try to redirect the user to the direct view of the widget?

    Does this make sense? You see what I’m getting at, that this tutorial give us just the very basics but not enough for us noobs to actually use the information to create a usable site.

    If anybody can point me to an example of what Im talking about that would be great, Im struggling with this.

  • Barry Cogan
    Author

    I do understand.

    You are getting into user access restrictions in your side bar example. Which was beyond the scope of this tutorial. If someone tries to access the segment without being logged in it will just show an empty page (in this example) However if you want different segments you will need to set up group permissions and then code an if/else or switch based on user access level.

    As for the form validation errors you will have to have a different controller calling the model which will in turn send you back to the page you were on.

    I do get what you are talking about and I think a tutorial on User Access restricion via HMVC may be in order to help you guys out with the updated modular extensions aswell.

    • andy78

      A User Access restriction via HMVC tutorial would be great!

      I managed to do what I wanted with the login module by using the widget plug-in for intelligent view partials that is available on the forums.

  • nedu

    Need some help here, Im getting this error;

    Call to a member function userdata() on a non-object in C:\www\HMVC\application\modules\login\controllers\login.php on line 76

    and line 76 is;

    $is_logged_in = $this-session-userdata(is_logged_in);

    session library is autoloaded, is there any reason why its seen as a non object.

    Cheers.

    • Emma Davis

      Line 76 should be:

      $is_logged_in = $this->session->userdata(‘is_logged_in’);

  • arief

    how to make a modules inside modules

    apps
    modules
    profile
    modules
    newsFeed
    model
    view
    controller
    request
    model
    view
    controller
    events
    model
    view
    controller
    login
    model
    view
    controller
    etc

    do you have idea how to make the glue the modulation in modulation likes my example above??

  • arief

    how to make a modules inside modules

    apps
    –modules
    —-profile
    ——modules
    ——–newsFeed
    ———-model
    ———-view
    ———-controller
    ——–request
    ———-model
    ———-view
    ———-controller
    ——–events
    ———-model
    ———-view
    ———-controller
    ——login
    ——–model
    ——–view
    ——–controller
    etc

    do you have idea how to make the glue the modulation in modulation likes my example above??

  • smith

    Just trying out the install from step 1 and 2.
    Where is the zip ‘modular_extensions_5231.zip’?
    The one i findcodeigniter-modular-extensions-hmvc-tip.zip
    has many files, not just 3.
    I try to follow the step 2 by moving the 3 files as directed and get 404 page not found.
    How can moving files around without any additional configuration still be expected to work?

  • Smith

    I decided to follow the
    Modular Extensions installation
    instructions at
    https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc/wiki/Home

    So I have folders (on Windows Vista):
    C:\Apache2.2\htdocs\CodeIgniter\system\application\modules\welcome\controllers
    C:\Apache2.2\htdocs\CodeIgniter\system\application\modules\welcome\views
    C:\Apache2.2\htdocs\CodeIgniter\system\application\third_party\MX

    Step 6 says
    6) Access the URL domain/subdir/index.php/welcome => shows Welcome to CodeIgniter
    This url works
    localhost/Codeigniter/index.php/welcome

    Then step 8 says
    move welcome.php to application/modules/welcome/controllers/welcome.php.
    Now the URL
    localhost/Codeigniter/index.php/welcome
    fails with 404

    Is something wrong with my setup? How can the welcome php file be found after moving it?

    Sorry if this is dumb question. i just want to follow this HMVC example and learn CI.
    But I never used CI before.

  • http://www.andreapernici.com Andrea

    I’m using CodeIgniter 2 with DataMapper.
    Is the HMVC library compatible with those ?

    Thanks

  • ken

    I get this …

    A PHP Error was encountered

    Severity: Notice

    Message: Undefined property: Login::$session

    Filename: controllers/login.php

    Line Number: 204

    Fatal error: Call to a member function userdata() on a non-object in D:\xampplite\htdocs\kpcportal2\application\modules\login\controllers\login.php on line 204

    • Karl Ballard

      I get the exact same error, mine just is from a different line.

      $is_logged_in = $this->session->userdata(‘is_logged_in’);

      • Karl Ballard

        Okay – Mine was a school boy error.

        While doing this tutorial I was using CodeIgniter 2.0 and doing exactly what it said in the tutorial..

        Basically instead of:
        class Login extends CI_Controller {

        I should have been doing:
        class Login extends MX_Controller {

  • http://twitter.com/arroyomt Mario Arroyo

    For some reason I had a problem with that line of code:

    $is_logged_in = $this->session->userdata(‘is_logged_in’);

    Apparently, when i use the “modeules::run()” function to load a controller, I have to pass the “$this->session” as a parameter and modify my “is_logged_in()” function like this:

    function is_logged_in($session)
    {
    $is_logged_in = $session->userdata(‘is_logged_in’);
    }

    The the code works fine.

    Why is that happening?

    By the way, thanks for this tutorial!

    • http://twitter.com/arroyomt Mario Arroyo

      Oh, nevermind! In the new version of MX the controllers have to extend the “MX_Controller” class to work. It’s all working fine now!

      Thanks for this introduction tutorial!

  • Kawsar Ahmad

    Please help me to install!!

    i have tried with both version 1.72 and 2.0.

    “Step 2. Download and Install HMVC Extension”
    I downloaded from given link. When i extracts the downloaded zip file (“codeigniter-modular-extensions-hmvc-b498773f4fc4.zip”) found 2 directories
    1. Core
    1.a. MY_Controller.php
    1.b. MY_Loader.php
    1.c. MY_Router.php
    2. third_party
    2.a. MX
    2.a.i. Base.php
    2.a.ii. Ci.php
    2.a.iii. Config.php
    2.a.iv. Controller.php
    2.a.v. Lang.php
    2.a.vi. Loader.php\
    2.a.vii. Modules.php
    2.a.viii. Router.php

    With CodeIgniter 1.72:
    —————————-
    Then i copied MY_Controller.php, MY_Loader.php, MY_Router.php to application/libraries/

    refresh the browser and got “Fatal error: require() [function.require]: Failed opening required ‘apps/third_party/MX/Router.php’ (include_path=’.;\xampp\php\PEAR’) in E:\xampp\htdocs\ci_test\ci_1.72\apps\libraries\MY_Router.php on line 4” message.

    Then I copied third_party folder to application/

    Now I got “Fatal error: Class ‘CI_Lang’ not found in E:\xampp\htdocs\ci_test\ci_1.72\apps\third_party\MX\Lang.php on line 37”

    With CodeIgniter 2.0:
    ————————–
    Then i copied MY_Controller.php, MY_Loader.php, MY_Router.php to application/libraries/
    refresh the browser and got same view as first.

    Then I follow ‘Move the “application/views/welcome_message.php” to “application/modules/welcome/views/welcome_message.php“.’

    I got 404 Page Not Found page.

    Please help me….:(

  • CKLFP

    Hi.
    First things first. @Barry, Very nice tutorial. Good work man. Keep up the good work ;).

    @ALL USERS – here is a thing call versions, this tutorial aims to a different version than the actual ones, CI and HMVC modules. Then there is a thing called BRAIN and it is supposed to used. You also need, at least try to see why is not working.

    @Kawsar Ahmad – Have you ever read the installation guide at https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc/wiki/Home try it and you will be amazed.

    I have an issue too, but I going to try to find the mistake, whether is on the code or in my implementation.
    And this tuts are just a reference we need to do the homework too.

    AGAIN @Barry, Very nice tutorial. Good work man. Keep up the good work ;).

  • Allan

    hi can you add “module within module” ?

  • http://onesmartclick.in onesmartclickin

    Fatal error: Call to a member function get_username() on a non-object in /home/onesmart/public_html/wp-content/themes/argonoid/functions/classes/input/input-socialnetwork.php on line 75 what to do for better results

  • http://www.hostingformula.net alam

    My bad, follow this tutorial blindly. CI 2 is the biggest difference why I’m stuck. Re read more with caution.

  • http://stevendobbelaere.be Steven Dobbelaere

    It doesn’t work with CI2. Solutions anyone?

    • SPeed_FANat1c

      it does work, if you’re using newest version from here https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc/wiki/Home

      and read the instalation instructions from the same page you’ve downloaded.

      You just need to change few things in controllers and models – the class names after word “extends” to CI_Controller or MX_Controller (if you want full HMVC functionality) and CI_Model for models and I guess thats it.

      • Michael Sole

        No there is more but that is a good start.

  • SPeed_FANat1c

    Cool article, nicely explained. Just one thing – it should be updated to current version of CI2, there are few little changes – e.g. instalation, we don’t need to specify base_url anymore, since CI2 knows it by itself.

  • http://pemul4.wordpress.com sigit

    Nice share!

    i’m following the tutorial and adapted use CI 2.0.2. It’s All work!

    Thanks!

  • Bralens

    How can i make subdirectories like this.

    –modules
    ––login
    –––controllers
    –––models
    –––views
    ––admin
    –––blog
    ––––controllers
    ––––models
    ––––views
    –––gallery
    ––––controller
    ––––models
    ––––views

    e.t.c

    • Michael Sole

      You can’t do that but you can have subfolders in your views and models.

  • http://www.ediy.co.nz/ Web Design

    nice one this

  • http://justmyfreak.com justmyfreak

    Thanks for great tutorial. It need minor code change to make it work on CI2. I`m using HMVC right no,it far better than using regular MVC in CI. The code is more reusable. :D
    Thank you…

  • Abhijit Shejwalkar

    i’m following the tutorial and adapted use CI 2.0.2. It’s All work!

  • Abhi

    ci 2.0 version with hmvc not work propley ……!!!!!
    404 page not found error will be display

    plz given me any solution

  • http://jogjaide.com Nanang

    ci 2.0.3 version with hmvc not work propley

  • Mr. Quijote

    Nice introduction, but I am wondering about the first image which shows the HMVC hierarchy. As far as I know, HMVC components are structured in a (directed) Tree which is defined as a circlefree graph. Your image shows a HMVC triad at the bottom which has two parents. This is not possible in a Tree (and shouldn’t be possible in a HMVC hierarchy).

  • Danny Cheeseman

    Hey Barry, Great tut on the basics of HMVC!

    Is there any chance of updating the tut to incorporate CI 2?

    As this is the main basis for most codeigniter projects now this might be a welcome addition to the Net Tuts empire ;)

    Cheers,

    Danny.

  • Jason Tan

    Thank you for the clear tutorial on ME and CI. It would be great if you can post a revised tutorial to use CI v2.x and the latest ME, as there seems to be some significant changes.

  • Paolo Umali

    I don’t get it.

    Why not just do all session detection in a main controller?

    If the router’s class/method being access requires login(or any specific session variable being true), then just redirect them where they can authenticate.

    With your method, there are too many folders to work with when you can just use the default views folder and keep one class’s view under one folder with the class name.

    auth/
    index -> site homepage
    login -> redirected here whenever other classes are being accessed but without the necessary token/permission

    blog/
    index
    post

    store/
    index
    product

    forum/
    index
    thread

  • http://localhost/hmvc huy

    Help me, how to instal Tank Auth with HMVC in codeigniter 2.1.0 :(

  • rashed

    @Barry, Very nice tutorial.

  • zing

    hai barry this is very nice tutorial,thank you

  • http://fivenazs.com NazMin

    hi all, can someone help me how to do jquery ajax with latest CI 2.x, i can do it with CI 2.0.x. Please help me, its seems like its not sending the data in the URL.

  • npCoda

    Can you please tell me how to work with new version of CI, say 2.1.0. Can anyone put downloadable files defining HMVC outline in new version.
    I tried to in 2.1.0 version of CI but I get “404 Page Not Found. The page you requested was not found.”
    I placed MY_Controller.php, MY_Loader.php and MY_Router.php inside system/core/ and third_party/ in root.

  • http://tradeshowdisplaysexperts.tripod.com/ sign holder

    You already know thus considerably on the subject of this subject, produced me personally believe it from a lot of numerous angles. Its like men and women aren’t interested unless it is one thing to do with Woman gaga! Your individual stuffs outstanding. All the time take care of it up!

  • Michael Sole

    The biggest difference between this example and CI 2.1 is that the controller class name has changed to: CI_Controller. There are other things that need to change as well, I too would like to see an updated version of this article that works with CI 2.1. Thanks for the effort, it was helpful none the less.

  • Rajeev

    modules::run(‘module/controller/method’) as indicated here https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc/wiki/Home is not working when you try to run method of control whose name is not same as module.
    For ex. module=> menu
    Controller=>menu1
    Method=> method1

    module::run always load default controller that is same name as module and its method.

  • http://www.gyanmoti.in Nirmal

    I tried this with the latest CodeIgniter_2.1.2 and it worked well with minor tweaks.

    Steps i followed :
    1.Downloaded the CI Framework
    2.Copied the folder “modules” to the application folder
    3.Downloaded wiredesignz / codeigniter-modular-extensions-hmvc. Copied the Core folder and the third party folder to the application folder
    4.Downloaded the Source code from this tutorial and just copied the modules folder to the application folder.
    5.Renamed the Controller to MX_Controller in the Login controller Class. Similarly for Site also
    6.Renamed the Model to CI_Model for the Membership Model class

    Here is the link you can download for you reference : http://bit.ly/LjTiQd

    Note :
    - Make sure the autoload is configured for libraries and helpers like form, helper, database,session etc
    - Also, modify the base path in the .htaccess if you are using without “index.php” in the url

    • http://twitter.com/sinisa_vukovic Sinisa Vukovic

      Thank you so much :)

  • Ammu

    Actually I am beginner to codeigniter…..This article is so helpful for me…. Thank You so much…..

  • Dhanesh

    Hi,
    When I am trying to use the function $this->session->flashdata(‘success’).its not displaying anything in view page,I have allready set the values by using the function $this->session->set_flashdata(‘success’, ‘Mymessage’) from controller

    • Jahanzeb

      Are you echoing the flash data or just running the function?

    • Kunj Patel

      after setting flashdata you have to redirect your controller’s function till then the message wont be display if u dont want to redirct to any another controller’s function or page then just redirect to self controller’s function your success message will be display…

  • Worlon

    Hi, where can I download HMVC? I can’t fint it :/

  • jaskaran

    HI their , great tutorial . Thanks.

  • jamie

    iv been told that each db table needs a module is this correct or would it be each area of the system has a module but with multiple models. e.g. sales orders has salesheader and salesdetails tables but is one area so would we have a module for salesheader and a module for salesdetails or just a module for sales which has seperate controllers and models for this. or is this defeating the purpose of hmvc?

  • bhaktaraz

    thanx alot… so interesting and helpful tutorial for me…