Module for hierarchical views (View) for Kohana
It will be about my first module for the Kohana framework .
Frankly, at the first and subsequent glances at this framework I really liked it. But as you know, there is nothing perfect. It seemed to me that one of the weakest places in Cohan is its rather primitive views. In essence, they are a plain-php file with variables exported to the global scope and accessible via the $ this link to the controller. This is very convenient when you need a presentation for data output, there is nothing superfluous, you can focus on the code. But when we need to display a page layout with a complex arrangement of elements that can vary from section to section ... What should I do? Collect all of the small views in the controller? Not convenient, especially if there are a lot of controllers - God forbid, for example, the number of columns in the markup will change, each controller will have to redistribute blocks of content into columns. Perhaps this is why in version 2.4 there will be (I hope) a module for integrating with Smarty.
I decided to search a little on this topic and found a very interesting topic on the Kohana forum , which made me think. By default, we have linear representations as an inclusive file. We need inheritance, modularity and a clear hierarchy of representations. I know only one entity ideally suited for this description - these are classes :) In this topic, the author just says that he uses this approach for his framework. It was a small matter - write your plan :)
One of my requirements for myself was that it was possible not to completely abandon the usual ideas, because in some cases they are really convenient. I have succeeded. Moreover, I even managed to avoid using custom add-ins of the form MY_View.php for the main classes. This is a plus because no one knows what a difficult hour they can come in handy for you.
My implementation is based on inheriting a new class from View:
I intentionally reduced the render () code here so as not to take up much space, the omitted code does not differ from View :: render ();
In a nutshell, the class does the following: Intercepts the name of the view, before the path and extension are added to it and saves it as the name of the future class + '_View' at the end. When rendering a view, it simply creates a class with a saved name, to which all variables and the current controller are transferred. I also overlap the factory, so that when Inherit_View :: factory is accessed, Inherit_View is created.
Now to create a view with a hierarchical structure, just call new Inherit_View ('Template'); and in the Template.php file the class Template_View should be declared, inherited from Base_Inherit_View, which in turn inherits from ArrayObject from SPL, and therefore access to any field inside Template_View is carried out as $ this-> property or $ this ['property']. And $ this-> controller contains a link to the current controller.
I included demos Html_Strict_View, Simple_Page_View, Another_Page_View in the examples, I think looking at them you can easily understand how many advantages this wrapper of views gives. I also included Inherit_Template_Controller in the module, similar to Template_Controller, only creating Inherit_View rather than View. And of course, according to the tradition of other modules, I turned on the demo controller. A complete combat set, in general :)
Of the minuses of this approach, I can only note that if your layout designer is not you and he does not know PHP, most likely he will send you :) But most of the time I’ll make it myself, therefore I get from this approach only pluses.
Link to the module at the beginning of the article and here . To make the module work, do not forget to include it in $ config ['modules'].
Thanks nexfor having prompted reflection and asked the very first question, why is it so bad with ideas, without him, I probably would not have taken up this matter.
Thank you all very much!
Frankly, at the first and subsequent glances at this framework I really liked it. But as you know, there is nothing perfect. It seemed to me that one of the weakest places in Cohan is its rather primitive views. In essence, they are a plain-php file with variables exported to the global scope and accessible via the $ this link to the controller. This is very convenient when you need a presentation for data output, there is nothing superfluous, you can focus on the code. But when we need to display a page layout with a complex arrangement of elements that can vary from section to section ... What should I do? Collect all of the small views in the controller? Not convenient, especially if there are a lot of controllers - God forbid, for example, the number of columns in the markup will change, each controller will have to redistribute blocks of content into columns. Perhaps this is why in version 2.4 there will be (I hope) a module for integrating with Smarty.
I decided to search a little on this topic and found a very interesting topic on the Kohana forum , which made me think. By default, we have linear representations as an inclusive file. We need inheritance, modularity and a clear hierarchy of representations. I know only one entity ideally suited for this description - these are classes :) In this topic, the author just says that he uses this approach for his framework. It was a small matter - write your plan :)
One of my requirements for myself was that it was possible not to completely abandon the usual ideas, because in some cases they are really convenient. I have succeeded. Moreover, I even managed to avoid using custom add-ins of the form MY_View.php for the main classes. This is a plus because no one knows what a difficult hour they can come in handy for you.
My implementation is based on inheriting a new class from View:
class Inherit_View extends View {
protected $class_name = NULL;
public function set_filename($name, $type = NULL)
{
parent::set_filename($name, $type);
// no slashes allowed in class names.
$this->class_name = str_replace('/', '_', $name).'_View';
return $this;
}
public static function factory($name = NULL, $data = NULL, $type = NULL)
{
return new Inherit_View($name, $data, $type);
}
public function render($print = FALSE, $renderer = FALSE)
{
// Load the file with view only once
require_once($this->kohana_filename);
ob_start();
// Merge global and local data, local overrides global with the same name
new $this->class_name(array_merge(self::$kohana_global_data, $this->kohana_local_data), Kohana::$instance);
$output = ob_get_clean();
return $output;
}
}
* This source code was highlighted with Source Code Highlighter.
I intentionally reduced the render () code here so as not to take up much space, the omitted code does not differ from View :: render ();
In a nutshell, the class does the following: Intercepts the name of the view, before the path and extension are added to it and saves it as the name of the future class + '_View' at the end. When rendering a view, it simply creates a class with a saved name, to which all variables and the current controller are transferred. I also overlap the factory, so that when Inherit_View :: factory is accessed, Inherit_View is created.
Now to create a view with a hierarchical structure, just call new Inherit_View ('Template'); and in the Template.php file the class Template_View should be declared, inherited from Base_Inherit_View, which in turn inherits from ArrayObject from SPL, and therefore access to any field inside Template_View is carried out as $ this-> property or $ this ['property']. And $ this-> controller contains a link to the current controller.
I included demos Html_Strict_View, Simple_Page_View, Another_Page_View in the examples, I think looking at them you can easily understand how many advantages this wrapper of views gives. I also included Inherit_Template_Controller in the module, similar to Template_Controller, only creating Inherit_View rather than View. And of course, according to the tradition of other modules, I turned on the demo controller. A complete combat set, in general :)
Of the minuses of this approach, I can only note that if your layout designer is not you and he does not know PHP, most likely he will send you :) But most of the time I’ll make it myself, therefore I get from this approach only pluses.
Link to the module at the beginning of the article and here . To make the module work, do not forget to include it in $ config ['modules'].
Thanks nexfor having prompted reflection and asked the very first question, why is it so bad with ideas, without him, I probably would not have taken up this matter.
Thank you all very much!