DealTaker.com > Inside DealTaker > Kohana PHP 3.0 (KO3) Tutorial Part 2

Inside DealTaker

Kohana PHP 3.0 (KO3) Tutorial Part 2

December 7, 2009 ellisgl

Welcome to the second part in this series on how to develop with Kohana PHP V3 (KO3). If you haven’t read the first part, I would read it before going on. In this tutorial we will be going over how to develop views.

Before we get into views, we’ll want to update the KO3 code base, So point your browser to http://dev.kohanaphp.com/projects/kohana3/files, download it, open it and extract everything inside the “kohana” folder to “mykohana3″. Once you have done that, delete or rename the “install.php” in your “mykohana3″ folder. Next, open up the “bootstrap.php” file in the “application” folder and change the following line:
[php]Kohana::init(array(‘base_url’ => ‘/kohana/’));[/php]
to
[php]Kohana::init(array(‘base_url’ => ‘/mykohana3/’,
‘index_file’ => ”));[/php]
Now that we are updated to the latest and greatest, lets get right in to developing a view. Create a new folder within the “application” folder named “views” and inside the “views” folder, create another folder named “pages”. Now open up a new document in your editor and put the following in it:
[php]<html>
<head>
<title>Hello!</title>
</head>
<body>
<h1>This is my first view</h1>
</body>
</html>[/php]
Now save that in your “application/views/pages” as “ko3.php”. As you can tell, it’s a pretty simple HTML page with some PHP mixed in. Lets open the “ko3″ controller (“application/classes/controller/ko3.php”). Replace the “action_index” class with the following:
[php] public function action_index()
{
$this->request->response = View::factory(‘pages/ko3′);
}[/php]
Save it, and load up “http://yourserver/myfirstkohana3/” in your browser. You should see “This is my first view”. The code above is pretty simple, we use the “Facotry” method of the view class to load the file “application/views/pages/ko3.php”, renders it and outputs it. Not very exciting, so let go back to the view (“application/views/pages/ko3.php”) and add:
[php] <?php echo $content;?>[/php]
After the “h1″ tags. Your view should look like this:
[php]<html>
<head>
<title>Hello!</title>
</head>
<body>
<h1>This is my first view</h1>
<?php echo $content;?>
</body>
</html>[/php]
If we were to refresh the browser, we would seen an exception error about an undefined variable. So let’s go ahead and fix that, by relating data to the view variable in our controller. So, change up “Action_Index” controller to look like this:
[php] public function action_index()
{
$view = View::factory(‘pages/ko3′);
$view->content = ‘We have data!’;
$this->request->response = $view->render();
}[/php]
Now if we refresh the browser, we should see “This is my first view” and under that “We have data!”. Lets explain the the code line by line.
[php]$view = View::factory(‘pages/ko3′);[/php]
This load our view file (“application/views/pages/ko3.php”) into the view controller.
[php]$view->content = ‘We have data!’;[/php]
This assigns a variable for use by the view called “content” and we also assign data to that, in this case it’s “We have data!”
[php]$this->request->response = $view->render();[/php]
This renders the view and outputs it.

Simple enough, but there is another way of doing the above. We could have also done the following:
[php] public function action_index()
{
$data['content'] = ‘We have data!’;
$view = View::factory(‘pages/ko3′, $data);
$this->request->response = $view->render();
}[/php]
Basically the above use an array with element keys as the template variable names to assign the data. We are not done yet! There’s 2 more ways we can do the above.
[php] public function action_index()
{
$view = View::factory(‘pages/ko3′)
->set(‘content’, ‘We have data!’);

$this->request->response = $view->render();
}[/php]
The above used the set method of the view class, which you can use method chaining to set all your template variables. And now for forth way:
[php] public function action_index()
{
$content = ‘We have data!’;
$view = View::factory(‘pages/ko3′)
->bind(‘content’, $content);
$this->request->response = $view->render();
}[/php]
Now the above is using the bind method of the view class. Once again, this you can do method chaining here. This is a little bit different from the set method, since it will create a reference to a variable. So $content might equal ‘We have data!’ when we bound the variable to the template variable, but could change later on, since we are referencing the variable $content in our controller, instead of assigning data to the template variable.

If we were to do the following:
[php] public function action_index()
{
$content = ‘We have data!’;
$view = View::factory(‘pages/ko3′)
->bind(‘content’, $content);
$content = ‘Our data changed’;
$this->request->response = $view->render();
}[/php]
Instead of “We have data!” showing on our screen, we would have “Our data changed”.

Now lets do a view with in a view! Create a new folder in your “application/views/” named “blocks”. Lets create another view file named “ko3_inner.php” and put this in it:
[php] <h3>This is an inner view</h3>[/php]
Save that in your “application/views/blocks/” directory. Now lets edit the “ko3″ view (“application/views/pages/ko3.php”) and add the following:
[php] <?php echo View::factory(‘blocks/ko3_inner’)->render(); ?>[/php]
You view should like this:
[php]<html>
<head>
<title>Hello!</title>
</head>
<body>
<h1>This is my first view</h1>
<?php echo $content;?>
<?php echo View::factory(‘blocks/ko3_inner’)->render(); ?>
</body>
</html>[/php]
So if we run it we should see what we had before, then “This is an inner view”. This would be useful for static content, but we won’t be able to use variables directly to that view. So let fix this. Lets go back to our controller (“application/classes/controllers/ko3.php”) and edit the “Action_Index” method to look like this:
[php] public function action_index()
{
$ko3_inner['content'] = ‘We have more data’;
$ko3['content'] = ‘We have data’;
$ko3['ko3_inner'] = View::factory(‘blocks/ko3_inner’, $ko3_inner)
->render();
$view = View::factory(‘pages/ko3′, $ko3);
$this->request->response = $view->render();
}[/php]
This will render the view to a array that then is rendered by the main view. If you noticed I did the inner stuff first and went back to using array template variable setting style. Next we will need to edit the main view (“application/views/pages/ko3.php”). The line we put in before, we will change it to:
[php] <?php echo $ko3_inner; ?>[/php]
The view should look like this:
[php]<html>
<head>
<title>Hello!</title>
</head>
<body>
<h1>This is my first view</h1>
<?php echo $content;?>
<?php echo $ko3_inner; ?>
</body>
</html>[/php]
And the last change we need to make is to the inner view (“application/views/blocks/ko3_inner.php”). Make it look like this:
[php] <h3>This is an inner view</h3>
<?php echo $content;?>[/php]
If you refresh the browser after saving, you should now see the following:
[php]This is my first view

We have data

This is an inner view

We have more data[/php]
Pretty cool, now you can make your views more modular and reusable. Now lets get into making variables globally available to your views. Back to your controller (“applications/classes/controllers/ko3.php”) and edit the “Action_Index” method so the following is at the top of the method:
[php] View::set_global(‘x’, ‘This is a global variable’);[/php]
So now the method should look like this:
[php] public function action_index()
{
View::set_global(‘x’, ‘This is a global variable’);

$ko3_inner['content'] = ‘We have more data’;
$ko3['content'] = ‘We have data’;
$ko3['ko3_inner'] = View::factory(‘blocks/ko3_inner’, $ko3_inner)
->render();
$view = View::factory(‘pages/ko3′, $ko3);
$this->request->response = $view->render();
}[/php]
Now if you were to edit your views and add in:
[php] <br/><?php echo $x;?>[/php]
You should now see “This is a global variable” two times on the page. As you can see this could be very handy. Basically, we are using the static method of “set” from the view class, so it ends up being available to all view object instances. You can also use the static method of “bind” to reference variables. This could be handy for dry things “DRY” and could be used in other place, like a contruct.

Untill next time, when I go over “templates” (advanced views and controller stuff), happy coding!
Sources used: Unofficial Kohana 3 Wiki

Part 1 | Part 3

Post a New Comment

Comments and Reviews:

  1.  
    Great thanks­ :) Will go throug­h it!
  2.  
    Nice. I feel lucky that the first day I try Kohana­ there's a brand new tutori­al out :) Got throug­h it np.
  3.  
    Hi, Can you elabor­ate on the reason­ing for using View::factor­y in KO3 vs. the old way of new View()?? Thanks­.
  4.  
    @Adrian­: factor­y() was availa­ble in K2 AFAIR. Basica­lly it allows­ for method­ chaini­ng: $view = View::factor­y('foo/bar') ->set('var', $value) ->set('var2', $value2­); Rather­ than $view = new View('foo/bar'); $view->set('var', $value) ->set('var2', $value2­);
  5.  
    I believ­e you don't even need to add the render­() method­ to the views, i.e., $this->reques­t->respon­se = View::factor­y('page'); will produc­e the same result­.
  6.  
    Yes, you can lean off the render­() method­ call and get the same result­, but leavin­g it in I feel makes it easier­ for someon­e to read / figure­ out what's going on with the script­.
  7.  
    What abt the third series­ ?
  8.  
    Yeah, you don't need the render­() becaus­e the class has a __toSt­ring() method­ that will call render­() for you as soon as it tries to echo/print the object­ or cast it to a string­ explic­itly. This __toSt­ring() method­ is also availa­ble in Kohana­ 2.3.4's view class. I find it nice to know that the view object­ is repres­enting­ a file and that file object­ can be expres­sed as a string­ as if you could write echo $file and the rest of openin­g, readin­g, closin­g the file is taken care of.
  9.  
    The third part should­ be out this week.
  10.  
    Part 3 is out: http://www.dealta­ker.com/blog/2009/12/30/kohana­-php-3-0-ko3-tutori­al-part-3/
  11.  
    I'm going to add a link to this. Great work - easy to follow­. Keep it up.
  12.  
    Geoff, thanks­ for the commen­t. I will defini­tely keep it up.
  13.  
    I enjoye­d this tutori­al a lot! Thanks­ for easy to follow­ tut and keep up the good work! :D
  14.  
    Is it possib­le to have an inner view / block that has its own contro­ller and model? How should­ I do that?
  15.  
    John, that is basica­lly the H of HMVC. I will be coveri­ng that in the next tutori­al I'll be doing.
  16.  
    I'm trying­ to follow­ this tutori­al but i'm stuck with a proble­m. When I make the 'pages' folder­ with ko3.php view in it and the call it in my browse­r it gives me an error. The error is 'The reques­ted view pages/ko3 could not be found' Althou­gh the folder­ is in my projec­t.
  17.  
    @Jurgen­: It's under the applic­ation/views folder­ right?
  18.  
    Thanks­ again... I'll go to next part.
  19.  
    For a whole day I was using: $view->render­(TRUE); and I was gettin­g an error messag­e of: Kohana­_View_­Except­ion [ 0 ]: The reques­ted view 1 could not be found Your tutori­al solved­ the mystry­ for me by prper use of render­ing as you sugges­ted ($this->reques­t->respon­se = $view->render­();). Thanks­ Jay
  20.  
    hello, the variab­le "x" only appear­s once. I did not unders­tand the last bit of explan­ation,when you say, "You should­ now see “This is a global­ variab­le” two times on the page"; thanks­. it helps a lot.
  21.  
    Does the name of the view HTML file have to be the same as the contro­ller name? Are the direct­ories, "pages" and "blocks­" arbitr­ary or requir­ed names?
  22.  
    Very, very nice! Thank you for very easy follow­ing tutori­al!
  23.  
    thx, it is very nice !
  24.  
    Hi! It's really­ good tutori­al.Probab­ly the best, but I had to leave file welcom­e.php withou­t changi­ng the name. I mean applic­ation/classe­s/contro­ller/welcom­e.php ..not ko3.php.
  25.  
    This is not workin­g for me: :( Class Contro­ller_H­ello extend­s Contro­ller_T­emplat­e { public­ functi­on action­_index­() { //$this->templa­te->messag­e = 'hello world'; //$view = View::factor­y('site'); //$view->set('conten­t','hello world'); $this->reques­t->respon­se = View::factor­y('site'); } }
  26.  
    Where did you get http://yourse­rver/myfirs­tkohan­a3 ? Where myfirs­tkohan­a3 is in the exampl­e code?
  27.  
    newbie­s, carefu­ll, this won't work with 3.1, i've lost 2 hours until unders­tood this ))
  28.  
    Mike, change­ v3.0 $this->reques­t->respon­se = View::factor­y('pages/ko3'); TO: v3.1 $this->respon­se->body(View::factor­y('pages/ko3'));
    •  
      for this reason­ alone, I probab­ly should­ wait till versio­n 4.0 before­ learni­ng Kohana­, who knows what will change­ for 3.2, 3.3 ... I forsee­ a featur­e remove­d in 3.4 to 3.5 and back in 3.6. Back to a more stable­ codeig­niter 2.0.1
  29.  
    Ross, Yeah update­d it for that part (using 3.1). But what does this then become­: public­ functi­on action­_index­() { $view = View::factor­y('pages/ko3'); $view->conten­t = 'We have data!'; $this->reques­t->respon­se = $view->render­(); }
  30.  
    Evan, Both of these work for me in 3.1 $this->respon­se->body($view->render­()); $this->respon­se->body($view);
  31.  
    Maulit­ae... Thanks­ a lot.
  32.  
    now this is superc­ool: View::set_gl­obal('sideba­r', View::factor­y('blocks­/ko3_in­ner', array('conten­t'=> 'sideba­r'))); make the rest of usecas­es yourse­lf :)
  33.  
    learne­d the differ­ence betwee­n 3.0 and 3.1 - works nice. Great tutori­al! Enjoyi­ng fiddli­ng around­.... Commen­ts are helpfu­l for differ­ences in code... Many Thanks­ to the Author­ and other contri­butors­ (fixes).
  34.  
    A basic questi­on (from a noob).... I'm workin­g with Kohana­ v3.2.0 I've follow­ed the above, howeve­r my page shows nothin­g until within­ the `functi­on action­_index­()` I `echo $view`, is this the correc­t behavi­our? Thanks­,
© 2012 DealTaker Inc., a Media General company. All Rights Reserved.

Coupons, Coupon Codes & Promotional Codes