Views in Kohana3

Views: 6033Comments: 0
Web frameworks

Это перевод моего русскоязычного туториала Views в Kohana3

In the previous tutorial we have deployed Kohana3 to XAMPP environment and have made very-very simple site. Such an approach may exist but mostly it is a not developer-friendly one because of dealing with markup in controller. More convenient way is to separate all markup-related stuff in so-called View entities, working like templates. And in Kohana3 we have an implementation of MVC (Model-View-Controller) so we can use Kohanian Views to build output.

Let’s add some Views to our present mini-site. For example, make template for our super-navigation, OK? First create folder application/views/elements/ and file navigation.php inside. I’m not a good designer, so html will be very simple:

<ul id="site_nav">
<li style="display: inline; font-weight: bold;">Navigation: </li>
if (is_array($items) AND ! empty($items))
    foreach ($items as $item)
    <li style="display: inline;"><?php echo $item; ?></li>
} else {
    echo 'No navigation presented';

Than we have to init it in the controller and push there needed data. I think that more logically to make this in our method Controller_Welcome::_simple_nav() that form our navigation element. But previously we have to modify this method to return skeleton array instead of the string. It’s simple: replace string concatenation by array item adding

$slugs[] = HTML::anchor($slug, url::title($slug));

Next we can use the classic (Kohana 2) way to init View and to send data there

$view = new View('elements/navigation');
$view->items = $slugs;

More elegant way is to use fabric generation View::factory(‘template_name’) and setting View::set('template_var', $controller_var), that allow to assign to some View variable $template_var  value of $controller_var from controller:


$view = View::factory('elements/navigation')

To get some output assign $view to $this->request->response. All works!

We can simplify the formation of rendered page by eliminating routine need to attach main template and echo it in $this->request->response. To do this let’s inherit our controller not from Controller, but from Controller_Template:

class Controller_Welcome extends Controller_Template {

In such a case we shouldn’t forget that by default for main View Kohana looks for view/template.php file. So declare main View evidently if needed

public $template = 'custom_template';

Naturally, such an inheritance (from Controller_Template) may be (really should be) useful not only for main View declaration but also for some preliminary routine tasks in your app. But not in this very tutor smile

Create base template custom_template.php and put in into views/:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "">
<html xmlns="" xml:lang="en" lang="en">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="keywords" content="" />
<meta name="description" content="" />
<title><?php if ( ! empty($title)) echo $title; ?></title>
<div class="container">
    <div id="navigation">
        <?php echo $navigation; ?>
    <div id="content">
        <?php echo $content; ?>

Then in the controller we should populate it by actual data:

public function action_index()
    $this->template->title = 'Main page';
    $this->template->content = 'hello, world!!';
    $this->template->navigation = $this->_simple_nav();

Other controller actions are like that. Note that there is no any assigning to $this->request->response. It has been done in inherited method Controller_Welcome::after().

Let’s add more fun in routine proc of templates filling. View::bind() method will help us “bind” some controller variable to template variable on very early stages of executing. Using bind() we can simple “assign and forget”. For example create new View to output some content application/views/elements/content.php

<?php echo $p1; ?>
<?php echo $p2; ?>

After initializing in controller we should set $p1 and $p2 but can not do that before they are defined:


$this->template->content = View::factory('elements/content')
$par1 = 'news 1';
$par2 = 'news 2';

returns error.

Bind() will help us in such a case:

$this->template->content = View::factory('elements/content')
$par1 = 'news 1';
$par2 = 'news 2';

This approach is essentially comfortable when working with loops and/or complicated conditional trees when tracking the variable final value is tricky (or some final assigning can take place). You simply bind() variable immediately after method beginning… and enjoy smile

My commentators proposed a nice example of View::bind(): assigning some similar entities (article comments) in the loop:

$subview = View::factory('comments')->bind('comment', $comment);
foreach($comments as $comment)
  echo $subview;

That's all!

You can download zipped application folder.

Оставьте комментарий!

Используйте нормальные имена.



Если вы уже зарегистрированы как комментатор или хотите зарегистрироваться, укажите пароль и свой действующий email. При регистрации на указанный адрес придет письмо с кодом активации и ссылкой на ваш персональный аккаунт, где вы сможете изменить свои данные, включая адрес сайта, ник, описание, контакты и т.д., а также подписку на новые комментарии.

MaxSiteAuth. Войти через loginza