Tag Archives: PHP
Using HAML with CodeIgniter
February 22nd, 2012. Published under PHP. 8 Comments.
And after working several months with Ruby On Rails, a friend of mine called me to participate into a php project using the CodeIgniter framework.
Not a problem for me, but there some things that when you are into, you don’t want to get rid of them, one of them is HAML. Then, I started to look for some code ready to do this, but sadly, I didn’t find anything that was easy to use or up-to-date. After more search I’ve found this project: PHamlP, an updated port of HAML and SASS parser for PHP.
The PHamlP project already have version for Yii and CakePHP framework.
I guess this parser doesn’t work much different from the Rails parser. It will look if the cached version of template exists, if not then it creates, or if the template file gets modified the cache file is updated too.
In this case the cache file it’s the PHP version of your HAML code. But, enough talk, let’s go to the action.
I dunno if this way is the best way to implement the parser on CI, but I didn’t find any performance problems, and one thing to remember, just tested this with the CodeIgniter 2.1.0.
First, go to your application/config/config.php and check what is your subclass_prefix, in this case, let’s suppose that it’s the default MY_
Go to the PHamlP project page and download the code. Create a folder inside application/libraries called phamlp(or whatever you want to use of course) and extract the files from PHamlP package.
After having extracted the files, create a file called MY_Loader.php(Replace the “MY_” with your subclass_prefix) in the application/core folder with the following code:
Edit: Fixed code to work with CI standard functions(it also fixed the problem trying to load a HAML file inside a HAML file)
Edit: Added fix suggested by igoooor
class MY_Loader extends CI_Loader {
function view($view, $vars = array(), $return = false) {
$haml_file = dirname(__DIR__) . "/views/" . $view . ".html.haml";
$view_path = dirname(__DIR__) . "/views/";
if(file_exists($haml_file)) {
load_class('HamlParser', 'libraries/phamlp/haml', '');
$instance =& get_instance();
$haml_cache_path_base = APPPATH . "cache/";
$haml_cache_path = $haml_cache_path_base . $instance->router->fetch_directory() . strtolower(get_class($instance));
if(!is_writable($haml_cache_path_base)) {
$haml_error = 'The HAML cache path(' . $haml_cache_path_base . ') isn\'t writtable!';
log_message('error', $haml_error);
if(ENVIRONMENT != 'production'){
show_error($haml_error);
}
}
if (!file_exists($haml_cache_path)) {
$haml_cache_path_array = explode("/", str_replace($haml_cache_path_base, '', $haml_cache_path));
// Let's go see if the cache structure exists then =)
if(count($haml_cache_path_array) > 1) {
for($haml_cache_path_counter = 0; $haml_cache_path_counter < count($haml_cache_path_array); $haml_cache_path_counter++) {
$haml_cache_path_sliced = $haml_cache_path_base . join("/", array_slice($haml_cache_path_array, 0, $haml_cache_path_counter));
if(!file_exists($haml_cache_path_sliced)) {
mkdir($haml_cache_path_sliced);
}
}
} else {
mkdir($haml_cache_path);
}
}
$haml = new HamlParser();
$rendered = $haml->parse($haml_file, $haml_cache_path);
return $this->_ci_load(array('_ci_path' => $rendered, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return));
} else {
// if no haml file was found, it uses the default render function
return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return));
}
}
}
So, this new loader will look for a file in your view path that the name look like “users.html.haml”(just like the Rails way), if doesn’t find anything it fallback to the default function.
Well, the reason that i said that I dunno if this is the best way, it’s because the workaround with the callback to isolate the assign variables to evict possible conflicts. But, like I said, I didn’t find any performance problems at all. But that’s it, nothing more to do, without much code, and no need to change the core of the framework, just a simple extends.
I’ll be doing another post soon to show you how to implement the SASS parser with the CodeIgniter.
I hope that this gets useful for your as it was for me. Any doubts? Just comment.
Download MY_Loader.php
Thanks for the reading.