gosukiwi's blog

Creating a PHP MVC framework - Part 4

Hello! And welcome to the fourth part of the PHP MVC tutorial, in this part we’ll dive onto the V in MVC, the View.

If you haven’t already, you should read the other parts before this one

The view is in charge of displaying data to the user, it dictates how the data must be shaped, in the web world, the view is generated HTML code.

There are many ways to generate HTML code, the one we were using so far it was the simplest in the PHP world, just embedded PHP, as I specified earlier, the problem with this approach was giving the view layer a bit too much power, making it easy to do some things that should not be done in the view, and should be performed in the controller instead, on the other hand, the advantage is that embedded PHP has no learning curve, as every developer already knows it.

For the framework, we’ll use a template engine to help us out in this case, this will allow us not only prevent the violation of the division of concern as stated above, but also make it easier and faster to write view code, as template engines give us nice syntactic sugar to help us out, also, if a designer has to modify the views, it makes it much easier for her as embedded PHP might look scarier than a template engine syntax.

We are lucky, we also have several awesome libraries to help us out in this case, one of the most popular engines is Twig, inspired by Django’s template engine, it’s easy to use and learn, and it’s pretty much everything we’ll ever need, the only disadvantage beeing it’s quite big.

Some alternatives are Smarty and Blade, personally I really like Blade syntax, but it seems to be tightly couped to Laravel and not easy to include onto any project, so I decided to create Katar, it’s inspired by blade, but much more limited, it doesn’t allow defining sections or nor extending layouts, it’s basically a layer syntactic sugar on top of embedded PHP, the advantages beeing it’s small, and enables to mix PHP onto Katar code.

Again, feel free to use any template engine you like, I’ll use Katar, if you don’t want to use Katar, I reccommend Twig.

Let’s include Katar to our project, it’s as easy as adding it as a dependency to composer.json and let Composer do the rest!

{
  "require": {
    "php-activerecord/php-activerecord": "dev-master",
    "gosukiwi/katar": "dev-master"
  }
}

By running php composer.phar update Composer downloads and installs Katar.

Using Katar For Views

Once composer downloaded Katar for us, we can just start using it, as we have already included the autoloader.

The first change we’re going to do is update our controller to also load Katar and configure it, for this, we need a new folder inside app, a cache folder, to store Katar’s cache, for this we’ll create the folder app/cache, once it’s created let’s update the controller code.

class Controller
{
    private $katar;

    public function __construct() {
        // configure model
        ActiveRecord\Config::initialize(function($cfg)
        {
            // activerecord will autoload all classes inside this folder
            $cfg->set_model_directory(__DIR__ . '/../models');
            // let's use a mysql datbase, in this case the username and
            // password are both root, and the database is php-mvc
            $cfg->set_connections(array(
                'development' => 'mysql://root:root@localhost/php-mvc'
            ));
        });

        // configure views
        // load Katar and set the cache folder to ./app/cache
        $this->katar = new \Katar\Katar(__DIR__ . '/../cache');
    }

    protected function view($file, $params = array()) {
        // katar will compile $file and render the compiled file by
        // including it
        $this->katar->render(__DIR__ . '/../views/' . $file, $params);
    }
}

We made two important changes, the first one, we instantiated Katar onto the instance variable $katar, the other important change is we replaced the old view code with just a line, telling Katar to compile the view for us.

Now that we have Katar all set up, if we update our page it will look just the same, as embedded PHP is just fine for Katar, nevertheless, we are not taking advantage of the library! Let’s replace our view with the following code

<!DOCTYPE html>
<html>
    <head>
        <title>Example View</title>
    </head>
    <body>
        <h1>All posts</h1>
        
        @for $post in $posts
            <h1>{{ $post->title }} - ID: {{ $post->id }}</h1>
            <h2>Created on {{ date('d M Y', $post->created) }}</h2>
            {{ $post->content }}
            <hr />
        @endfor
    </body>
</html>

As you can see it looks much cleaner now! You can read more about Katar’s directives in the GitHub repository.

Conclusion

This tutorial was rather short, but I’d rather keep tutorials separate and not mix several topics onto a single tutorial, as always, if you want the source code you can find it at the GitHub repository, with the tag v3. The next tutorial will probably cover Dependency Injection. See you there!

Comments