Tag Archives: mvc

kohana-view

Using Views in Kohana 3

What is a View?

If you’ve never worked with Kohana Views in the past, they’re not hard to understand. Controllers handle most of your logic, Models handle the database communication, and Views handle the presentation of the data (generally-speaking). In Kohana, views are very easy to work with. Unfortunately, a fresh install of Kohana won’t contain a default view for you so we’ll have to make one ourselves. I trust you’ve installed and configured Kohana 3 on your server and are ready for what follows.

Adding our first View

Stepping back a moment, by default Kohana’s example controller sends text directly to the output without loading a view – perhaps you’ll find cases where this is desirable (especially when debugging), but for the most part it’s not what you’ll want to be doing. When developing your next project, you’ll want to build views that represent templates, modules, and many other aspects of your design.

Suppose we have the following saved to application/views/myview.php

<p>If you see me, the view loaded.</p>

This is nothing more than a paragraph element and some static text, but let’s load it from within a controller. I should mention that there are a couple different ways you can load a view, but they’re all pretty straight forward and intuitive.

Loading our View

class Controller_Demo extends Controller {
  public function action_index()
  {
    $this->request->response = View::factory( 'myview' );
  }
}

In this case we’re using the static factory method of the View class to load the view file we previously created. Note also that I’m not providing the .php extension – Kohana figures that out for itself. If myview.php was in a subfolder, we would reflect that in the path passed to the factory method.

Kohana 3 is loaded onto my localhost, so visiting http://localhost/kohana/demo/index results in showing me the contents of my view, meaning the view was loaded properly. If your view isn’t loading properly, make sure you placed it within application/views, and that your controller code contains no mistakes.

Handling a View from a variable

Another way to load a view is to place it within a variable reference, and then pass that into the response.

class Controller_Demo extends Controller {
  public function action_index()
  {
    $view = View::factory( 'myview' );
    $this->request->response = $view->render();
  }
}

With time you’ll settle on the method you prefer most. In fact, what we’re about to cover might help determine which method you prefer most.

Passing Data to your View

Views are not necessarily restricted to being static files – they wouldn’t be all that useful if they were. Controllers can pass variables into views to be displayed upon pages. Let’s go back to our view from above and change our static text to something a bit more dynamic and open to more possibilities:

<p><?php echo $message; ?></p>

Here our view is expecting to display the $message variable, so we have to be sure to provide this value within our controller. Passing variables and values into views is also a task that can be done a couple different ways. One very common method is to create an associative array, and pass that into the static factory method:

class Controller_Demo extends Controller {
  public function action_index()
  {
    $data['message'] = "Hello, World";
    $this->request->response = View::factory( 'myview', $data );
  }
}

What this does is makes all $data array keys available within the view as variables themselves, so $data[‘message’] within the view is $message. Refreshing your page should result in a new message, “Hello, World”.

Adding Data via the Set Method

The view class also contains many method to allow the adding data on a variable-by-variable basis. We can use the set method to add a variable to a view as well.

class Controller_Demo extends Controller {
  public function action_index()
  {
    $this->request->response = View::factory( 'myview' )
      ->set( 'message', 'Hello, World' );
  }
}

The set method of the view class accepts two parameters: 1) The key, and 2) the value. Like the previous method, this also creates a variable called $message within the view with whatever value you provide. The set method also allows you to add an array of values:

class Controller_Demo extends Controller {
  public function action_index()
  {
    $this->request->response = View::factory( 'myview' )
      ->set( array( 'Name' => 'Jonathan', 'Year' => 2011 ) );
  }
}

When you provide an array, the set method will cycle through your array and add all of your values as if you had done each one of them individually with the previous style of using the set method.

Chaining the Set Method

Another thing to note about the set method is that it’s chainable, meaning you can run it over and over and over again.

class Controller_Demo extends Controller {
  public function action_index()
  {
    $this->request->response = View::factory( 'myview' )
      ->set( 'name', 'Jonathan' )
      ->set( 'year', '2011' )
      ->set( 'website', 'http://sampsonresume.com' );
  }
}

Working directly with the View

So far we’ve been using the set method in conjunction with the static factory method, but you can do the same thing even if you apply the view to a variable earlier in the control:

class Controller_Demo extends Controller {
  public function action_index()
  {
    $view = View::factory('myview');
    $view->set( 'name', 'Jonathan' );
    $this->request->response = $view->render();
  }
}

Another method of adding data is to just add it directly to the view object itself:

class Controller_Demo extends Controller {
  public function action_index()
  {
    $view = View::factory('myview');
    $view->message = "Hello, World";
    $this->request->response = $view->render();
  }
}

Setting Global Variables

At times you may want to make a variable available to all views that are loaded. The view class makes this easy as well via its global data array.

class Controller_Demo extends Controller {
  public function action_index()
  {
    View::set_global('message', 'Hello World');
    $this->request->response = View::factory('myview')
      ->set( 'myWidget', View::factory('anotherview') );
  }
}

In this example you can see that we call the set_global method early in the controller logic. The variable $message will now be available in all views loaded. You can also see that I’ve loaded a second view into the first, and represented it with the variable $myWidget. Both views can reliably access the global $message variable now.

There’s still a lot more you can do with views, like passing variables by reference via the bind method. The bind method is just like the set method, with the one caveat that the variable is being passed by reference and isn’t being copied:

class Controller_Demo extends Controller {
  public function action_index()
  {
    $view = View::factory( 'myview' );
    $myVal = "Hello, World";
    $view->bind( 'message', $myVal );
    $this->request->response = $view;
  }
}

In this example $myVal is being assigned by reference to $view->message. If the value of $myVal changes, this change will reflect automatically within $view->message since the value is assigned by reference via the bind method. You can also use the bind_global method if you need set_global functionality while maintaining references.