Home » Php » How to include Smarty 3 into Laravel 4?

How to include Smarty 3 into Laravel 4?

Posted by: admin November 29, 2017 Leave a comment

Questions:

I am new to Laravel, so still getting used to the concepts, however I have around 10 years of experience using Smarty. So I wish to capitalize on that (apart from the fact that Blade seems to lack too many features I find useful and ready out of the box in Smarty, but anyway besides the point of this question).

I have been looking around to find the right way of using Smarty in Laravel, and although on a few forums such as here it seems to be possible its not clear what I need to do to use it properly within the framework. More concretely my questions are:

  1. Which Composer package should I include in my composer.json? There seems to be this which includes Smarty itself, because it was modified (not too keen about that). And here they also suggest http://bundles.laravel.com/bundle/SmartyView. Not sure if it is the same, because the bundles sub-domain of laravel.com isn’t even coming up. It used to come up a few days ago, but I don’t know if they turned it off because bundles are now obsolete and replaced by packages… not sure. There is also this

  2. How should I configure Laravel to use Smarty views instead of Blade views?

  3. Given that Laravel uses REST style pretty URLs, how should I include CSS and JS files from Smarty
    views, such that the path to them is dynamically set by Laravel? In Blade you do something like: {{ HTML::style('css/style.css') }}. Can I use something similar? Or better still set a template variable from the code by calling the HTML class? (I don’t really like calling PHP code within templates that should just be doing presentation logic.)

Sorry if some questions are a bit trivial.

Answers:

OK so after some more research, I managed to painlessly integrate Smarty 3 within Laravel 4. I am not sure if it is the best way, but its working perfectly, so open to comments or further suggestions.

I installed this Smarty View for Laravel and followed the instructions to add it in the list of providers in app/config/app.php. After running the php artisan config:publish latrell/smarty command the configuration was automatically created and I was ready to go. This package also seems to use the proper Smarty libraries rather than some modified templates.

I then just created a plain old HTML file, with a .tpl extension in the app/views directory, and a corresponding controller in the app/controllers directory, together with the corresponding route in routes.php and hey presto, it worked without a hitch.

I even modified the BaseController to maintain a common list of template variables (such as the CSS styles etc.) to inject in the HTML without putting ugly PHP code in the template. (I don’t know if there’s a better way to set them directly into the View from the BaseController rather than expecting the sub-class to pass them in the call to the make method, but I guess thats a different question.)

Code below for who might need it:

HelloWorld.tpl

<!doctype html>
<html lang="en">
<head>
    <title>Hello World</title>
    <meta charset="UTF-8">
    {$style}
</head>
<body>
    <div>
        <h1>Hello {$name}</h1>
    </div>
</body>
</html>

BaseController.php

class BaseController extends Controller {

    protected $template_vars = array();

    protected function addTemplateVar($key, $value)
    {
        $this->template_vars[$key] = $value;
    }

    /**
     * Setup the layout used by the controller.
     *
     * @return void
     */
    protected function setupLayout()
    {
        //not sure if I need this any more since I am using Smarty
        if ( ! is_null($this->layout))
        {
            $this->layout = View::make($this->layout);
        }

        $this->addTemplateVar("style", HTML::style("css/bootstrap.css"));
    }

}

HelloWorldController.php

class HelloWorldController extends BaseController 
{          
    public function showHelloWorld()
    {
        $this->addTemplateVar('name', 'World!');
        return View::make('helloworld', $this->template_vars);
    }
}

In routes.php:

Route::get('helloworld', '[email protected]');

Hope its useful for someone else.