Smarty PHP plugin for Lithium PHP
Adds Smarty Templating Engine support to Lithium PHP Framework.
I can't claim to be a fan of smarty, or php templating languages in general, but Smarty was a requirement from my employer.
So, alas, here is a plugin to run lithium thru smarty properly.
There are several ways to grab and use this project:
-
Clone/Download the plugin into your app's
libraries
directory. -
This is great for development but will require you go to this directory and manually pull any future changes
In your app's libraries
directory enter the following
git submodule add https://github.com/joseym/li3_smarty.git li3_smarty
You could add this in your app path as well, just make sure you tell it to place the submodule in
libraries/li3_smarty
rather than justli3_smarty
.
This is a great way to manage several plugins. If you add all of your libraries this way then you can stay up to date with all of them by running this command from your libraries directory (or wherever you created the submodule):
git submodule update
This goes out and pulls all of the repos you have loaded into submodules. Handy!
That doesn't have to keep us from using it! It just means that we may have to take an extra step or two in order to get Composer running with Lithium. See this highly instructive article by @daschl and lets do our best to make Lithium as easy to use as possible!
Modify your projects composer.json
file
{
"require": {
...
"joseym/li3_smarty": "master"
...
}
}
Tell your app to load the plugin by adding the following to your app's config/bootstrap/libraries.php
:
<?php
Libraries::add('li3_smarty');
?>
This has similar benefits to submodules however with composer you don't need to know much about the plugin, just it's vendor name (joseym
) and it's library name (li3_smarty
) and what branch you want (master
). Packagist handles the rest!
Everything should be preconfigured to just work. However: should you feel the need to add additional template paths, or dump your compiled templates elsewhere, you can! Just pass an array of options to your Libraries::add call:
<?php
Libraries:add('li3_smarty', array(
'compile_dir' => PATH_TO_COMPILE_DIRECTORY,
'cache_dir' => PATH_TO_CACHE_DIRECTORY,
'template_dir' => array(
ADDITIONAL_TEMPLATE_DIRECTORY
),
'plugin_dir' => array(
ADDITIONAL_PLUGIN_DIRECTORY
)
));
?>
Note that the compile and cache directories need to be writable by your Apache (or whatever web server you use)
The plugin was written to mimic core Li3 variable assignment - therefore you can pass variables to your views like normal
PagesController.php
<?php
...
class PagesController extends \lithium\action\Controller {
public function home(){
$var = "test variable!";
$this->set(compact('var'));
}
?>
Then in your view:
home.html.tpl
I want to display my {$var}
which will render "I want to display my test variable!
"
You may have noticed that the view ended in .tpl, this is required for the plugin to parse the template as a smarty template.
Arguably one of the single most useful things smarty offers is its template inheritance.
This plugin treats views as layouts, so your view will need to extend the proper layout in order for it to render properly.
Think of this as
$this->content()
in reverse, you tell your view which layout to use rather than the layout where to include your view.
default.html.tpl
notice: layouts are also
.tpl
files
<html>
<head>...</head>
<body>
{block name="content"}{/block}
</body>
</html>
home.html.tpl
{extends file="default.html.tpl"}
{block name="content"}
<p>This is the view content that needs to be passed to <code>default.html.tpl</code></p>
<p>Also ... I want to display my {$var}</p>
{/block}
Now http://localhost/home
would render as
<html>
<head>...</head>
<body>
<p>This is the view content that needs to be passed to <code>default.html.tpl</code></p>
<p>Also ... I want to display my `test variable!`</p>
</body>
</html>
If you want to add extraordinarily nifty functionality to smarty then you would do so by writing a smarty plugin.
If you choose to write some of these you can place them in one of the following locations and they will be automatically included for you and ready for use in your layouts/views:
extensions/plugins
- from within your lithium appli3_smarty/plugins
- this is where I'm adding plugins I feel should be distributed with this lithium plugin.
I wont get into how or why you'd write these so check out the smarty plugin docs if you'd like to learn more about his feature (they're like helpers written for smarty).
This ... was tricky.
Smarty disables your ability to use PHP in your views and no longer supports the "escape" block function that would allow you to add raw PHP. Therefore extra effort was required to expose Lithium PHP view functionality to smarty.
To lose lithium php helpers is the same as losing both feet and 4 fingers, including both thumbs ... I HAD to come up with a way to expose helpers to smarty templates.
I've written a smarty plugin, called helper
which exposes all lithium helper methods to the smarty template.
Lithium Link Helper
<?= $this->html->link('My Github', 'http://www.github.com/joseym', array('class' => 'external')); ?>
Smarty Link Helper
...
<body>
{helper init="html:link" title="My Github" href="http://www.github.com/joseym" options=['class' => 'external']}
</body>
...
Both of the above would return <a href="http://www.github.com/joseym" class="external">My Github</a>
I'm going to break the smarty helper method down for you
- helper :
required
This calls the helper smarty plugin - init :
required
This is the class:method you want to use; in my example I'm using thehtml
class with thelink
helper -html:link
- title : optional This, and any other params are optional and depend on the lithium helper you're using
- href : optional same as
title
, it's optional for the smarty helper method but a requirement for the lithium html link helper.
Note: Helper params can be called anything, we could have just as easily called
title
andhref
name
andurl
. The only key names that arerequired
to be as show above areinit
andoptions
- options : optional An Associative array of optional parameters as used by lithium
If you are passing in an array of options the key must be called
options
for it to be used correctly by the smarty plugin
That should do it, I've tested with a few different core helpers and it works as expected, please log an issue if a helper fails to work properly with this method and I'll attempt to add support as soon as possible.
Again, since Smarty makes it impossible to use PHP in templates this means that in order to call Lithium elements
for use in a view powered by Smarty the element rendering methods needed to be exposed to smarty. Again, we do this by extending smarty thru a plugin function.
Lets say you have a menu
element, and you need to pass it user data. For the sake of this example we'll call the element file menu.html.tpl
as it's an HTML/Smarty file.
Lithium Element
I assume you already know about elements, they're enormously handy.
<?= $this->view()->render(array('element' => 'menu'), array('user' => $currentUser)); ?>
Smarty Element
...
<body>
{element file="menu" data=['user' => $currentUser]}
</body>
...
-
The
file
parameter is the name of the element, the file extension.html.tpl
is automatically appended. -
The
data
array is where you'd pass variables from your view to your element. It is optional.
Consider this: Elements + Smarty template inheritance. You define a default element in the primary layout and wrap it in smarty
{block}
's, then, later down the template chain you add a different element, or update the params on the current element. Powerful!
As always, I welcome your collaboration to make things "even more betterer", so fork and contribute if you feel the need.
Documentation available at http://www.smarty.net/docs/en/