Monthly Archives: January 2011

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.

pipeline-thumb

Jeff Atwood on The Pipeline

Like many people, I listen to podcasts most of the time I’m writing code. Unfortunately, most of these podcasts don’t have large financial backing and so at times they will dwindle up and die whilst others are sprouting up to take their place – keeps you on your feet.

Such was the case with one of my favorite podcasts, the StackOverflow Podcast, which nearly reached 90 episodes before shriveling up and dying in April of 2010 (tentatively speaking…could just be on a very long hiatus!). Fortunately, Jeff Atwood (from Coding Horror) still makes his rounds onto other podcasts.

One of Atwood’s latest interviews took place on 5by5‘s show The Pipeline. Head over and listen to the discussion about Jeff’s beginnings up to his present fame with the programmer’s paradise StackOverflow. For convenience, I’ve also placed the audio below.

“Jeff Atwood talks with Dan Benjamin about starting a business, running projects, software development, StackOverflow, and more.”

add_filter

Finding and Linking to Adjacent Posts with Same Custom Key/Value Pair in WordPress

Today I continued working on merging multiple custom post types back into regular posts, and differentiated them with a custom key/value pair. Some of these old post types would link to their adjacent siblings – videos to previous and next videos, cartoons to previous and next cartoons, etc. With these posts no longer being a custom post type, a video would be linking to whatever post preceded it, which would be an article, cartoon, or any number of things – this wasn’t good.

I wasn’t thinking this would be too much of an issue, after all, don’t we have the freedom to provide constraints to functions like previous_post_link() and can’t we tell functions like get_posts() to return only posts whose ID is greater than or less than the current post id? I was wrong on both assumptions – kinda. You do have the freedom to create some constraints on previous_post_link(), but only at the category level. That means if I wanted videos to only link to videos, I would have to use category names as some form of post type declaration, and I’m not about to do that. As for get_posts(), you cannot use any less-than or greater-than logic in relation to the present post ID.

What now? The solution I ended up going with was found in filters, specifically a custom filter tied to the “posts_where” filter. This idea comes from the WordPress documentation on the query_posts() function which provides an example of how to get posts whose date is within a timespan.

So the filter I ended up creating looks like this:

function filter_where_prev( $where = '' ) {
  global $post;
  return $where .= " AND ID < " . $post->ID;
}

I should note that that this code does in fact reside within single.php. The post id used will be from whatever post is presently residing in the $post variable. Next, we add this filter onto WordPress’ native filter. We’ll do this via the add_filter() function.

add_filter( "posts_where", "filter_where_prev" );

At this point we can now leverage the inherent power of the query_posts() function to tie things up. Remember that I wanted to restrict my results to posts that contain a specific key/value pair. Fortunately, this is something that query_posts() can indeed help me with:

query_posts( $query_string . "&meta_key=foo&meta_value=bar" );

Be sure to set your desired order and orderby criteria as well. I’ve left those out of my example for brevity.

With our new query established, we can proceed to run through our own micro-loop:

if ( have_posts() ) :
  while ( have_posts() ) : the_post();
    // Do whatever you like here
    // <li><?php the_title(); ?></li>
  endwhile;
endif;

Once we’re done building a list of references to older (or newer) posts, we need to clean up a bit. We don’t want future queries to use our filter, so we need to remove that. Additionally, we should reset our query as well:

remove_filter( "posts_where", "filter_where_prev" );
wp_reset_query();

Voila! That’s it. Now to do this for both the previous and next items, I had to create two filters. Be sure to remove any filters you create immediately after using them, and always reset your query!

ternary

A Shorter Ternary Operator in PHP 5.3

The ternary operator is simply awesome. It allows for some really beautiful if-else style variable assignments:

$can_drink = ( $age <= 21 ) 
  ? true 
  : false ;

This operator let’s you evaluate a condition, and return one of two results based on that condition. In the example above we’re testing the legal drinking age. If the age is greater than or equal to 21, the value of $can_drink will become true (the first value after the question mark). Otherwise, the value of $can_drink will become false (the value after the colon) (this particular example doesn’t require a ternary operator as the condition evaluated will itself result in either true or false). You can test multiple conditions within the main ternary condition, but the rules still stay the same – if the main condition evaluates to true, the first result is returned, otherwise, the second result will be returned.

The operator is nice, don’t get me wrong, but it’s not always fun to play with. Suppose you’re searching for a value within an array and you would like to return it if found:

$job_title = array_search( "Jonathan Sampson", $emp )
  ? array_search( "Jonathan Sampson", $emp )
  : "n/a" ;

You’ll note that my white-spacing is a little different, but this won’t effect the results of the operator. What I’m doing here is checking to see if “Jonathan Sampson” is a value within the employees array. If “Jonathan Sampson” is in the array, I’d like to return the key for that entry, so I replicate the condition (which returns the key) in the first slot after the question mark so it will be returned if the condition is true. Otherwise, if “Jonathan Sampson” isn’t found in the array (and the condition returns false) I return the string “n/a”.

Either the $job_title variable will have a value like “Software Developer” (given the key for “Jonathan Sampson” is “Software Developer”) or it will be “n/a”. The problem here is that we’re performing the array search twice, which is really ugly. There’s another way we could do this:

$job_key = array_search( "Jonathan Sampson", $emp );
$job_title = $job_key ? $job_key : "n/a" ;

Now we’re only performing the array search once. The array_search function returns either the first key found, or FALSE. As such, $job_title will contain either the key, or the string. But this is still a bit ugly. We’ve got two lines, and repeated calls to the $job_key array.

In PHP5.3 we’re given the option of a much shorter ternary, eliminating the middle column completely. This is helpful when using functions like array_search() which themselves return the result we actually want. They serve both as the condition (since they will return FALSE when the value isn’t found) and the result (since they return the key if the value is found). Now we can do something like this:

$job_title = array_search( "Jonathan Sampson", $emp )  ?: "n/a" ;

Now, if array_search() finds the key, it’s automatically returned into the $job_title variable, else, “n/a” will be returned. Elegant.

thumbnail

Quickly Adding Thumbnails to WordPress Archives

Post thumbnails make archives look much more attractive in my personal opinion, yet they are not natively displayed in the otherwise-beautiful theme shipped with the latest version of WordPress, Twenty Ten.

As is the case with most WordPress stuff, this shouldn’t stop us from adding it in ourselves – this is exactly what we’ll do. I should note that I’m a student of WordPress, and wouldn’t consider myself an expert by any measure, but I do know enough to get around and do so without making a mess (correct me if I proceed to make a mess).

Our goal today is to add a small thumbnail next to our posts on the archive pages of the Twenty Ten theme. Of course what you’ll learn here can easily be applied to most themes. We’ll be making use of primarily two functions, modifying a third, and adding a few lines of CSS to accomplish this today.

We’ll be modifying only two files today, loop.php and style.css. Within loop.php we will add the code to show the image, and within style.css we’ll add the rules to style the post and the image itself. Let’s begin!

loop.php, where the magic happens

Within loop.php we will find and abundance of if-else-statements (at times I will break this down into numerous smaller files to improve readability). Within Twenty Ten version 1.1 we will find a comment on line 122 saying “How to display all other posts.” This is where we will do our initial changes. Look at the two lines following this comment:

<?php else : ?>
<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>

First we’ll want to determine whether or not the post has a thumbnail associated with it. If there is a thumbnail, we’re going to add a class to the post div which will make some changes to the formatting to accommodate the thumbnail itself. If there is no thumbnail, we’ll leave the post div as-is.

<?php else : ?>
<?php $tnail = has_post_thumbnail() ? "hasthumb" : "nothumb" ; ?>
<div id="post-<?php the_ID(); ?>" <?php post_class($tnail); ?>>
<?php the_post_thumbnail( 'thumbnail' ); ?>

There are a couple of things going on here, so let’s break them down individually. First, we’re building a CSS classname off of the presence (or lack) of a thumbnail. For anybody who might be confused with the syntax, we’re using the ternary operator to do this:

$tnail = has_post_thumbnail() ? "hasthumb" : "nothumb" ;

has_post_thumbnail() returns either true, or false. If it’s true, the value of $tnail will be “hasthumb,” and if it’s false the value of $tnail will be “nothumb”. We then carry that value down into our call to post_class() where it will be added to the beginning of a list of many other classnames generated by WordPress for this post.

Within the div that contains the post itself, we add a call to the_post_thumbnail() function and specify that we want the thumbnail size. This function assumes you want the thumbnail size even if you leave out a value. The thumbnail size is configurable in your settings (settings > media) – for my site I’m using the default 150px by 150px. If the post has a thumbnail, the HTML to show the image will be generated and the image will be placed within the resulting HTML.

Styling the Image

Now we need to style the image. Without adding our CSS, the image will sit on top of the post, which isn’t what we want. Instead, we would like to place the image to the left of the post, with a nice gutter between image and content. For this next step, let’s open up style.css and navigate down to the bottom of the file to add the following:

/* =Post Thumbnails
-------------------------------------------------------------- */
body.home div.post.hasthumb,
body.archive div.post.hasthumb,
body.search div.post.hasthumb {
  padding-left: 170px;
  position: relative;
}
body.home div.post.hasthumb img.attachment-thumbnail,
body.archive div.post.hasthumb img.attachment-thumbnail,
body.search div.post.hasthumb img.attachment-thumbnail {
  position: absolute;
  top: 0; left: -5px;
  border: 5px solid #fefefe;
  box-shadow: 0px 1px 3px #CCC;
  -moz-box-shadow: 0px 1px 3px #CCC;
  -webkit-box-shadow: 0px 1px 3px #CCC;
}

A careful look at these rules will show that they will only apply on the home, archive and search pages. Additionally, the selectors only apply to the posts that have images representing them since they are the only entries that have the hasthumb classname.

That’s it, you should be able to save all changes and begin adding a featured image for each of your posts and find it right along side your excerpt.

Kohana checks environment to ensure it can run properly with present configuration.

Install and Setup of Kohana 3, The

Kohana is the wildly popular PHP Framework used by many developers all over. I’ve used it numerous times in the past on some rather different projects and found it to be pretty versatile and reliable over-all. One of my largest projects received well over 100,000 unique visitors a day, and still managed to hold up exceptionally well under the stress.

This post will serve as nothing more than a guide to installing Kohana version 3.

Environment

In order to run Kohana you will need a server, but don’t worry too much as your average computer will do. I develop on windows (for now) so I typically install WAMPServer, which places Apache, MySQL, and PHP all on my box inside a live server environment so that I can develop on the domain http://localhost/ – awfully handy.

Depending on what operating system you’re using, you may not find WAMPServer to be all that helpful. There are always alternatives: MAMP and XAMPP are two popular ones.

The Classic Download, Copy and Paste Procedure

Like so many other frameworks, we’ll begin with downloading Kohana and extracting the files into our project directory. You can download Kohana 3 from the Kohana download page. At the time of this writing, the latest (stable) version is 3.0.9, which also happens to be the version I’ll use in the following examples.

Extract the contents of your download to your project directory. You may keep the standard /kohana folder that comes in the archive, or you can just pull the files themselves our and into your directory. Once you have this done though, load up your favorite browser and navigate to your project directory to begin the requirements testing.

Kohana checks environment to ensure it can run properly with present configuration.

This stage will test your environment for Kohana compatibility. Kohana will need to ensure that your server configuration allows for writable log directories, appropriate versions of PHP and so much more. This screen will give you a nice rundown of how you stack up. All green is all good, but if Kohana finds something it doesn’t like (like unwritable directories) be sure to handle it here and refresh to re-check your system.

If you require assistance setting up your server environment to allow for writable directories, or enabling extensions in the PHP library, please consider visiting serverfault, and online peer-reviewed question and answer website for server maintenance.

As indicated in the automated test, once your system is clear you may delete (or rename) the install.php file to continue the process of setting up Kohana 3.

Setting the Base URL

Some of you may have refreshed your browser only to find a aesthetically pleasing (yet heartbreaking) error on your screen. You got antsy, slow down and keep reading (we’re almost done, I promise). The next thing we need to do is update our base bath to the project on our server.

Kohana uses Apache’s mod_rewrite to beautify your url structure. Much of this logic exists within the example.htaccess file found immediately within your Kohana directory. Open this up to make our next edit.

If necessary, let’s update the following line:

# Installation directory
RewriteBase /

If your project is immediately inside your /www or /htdocs folder (your web-server directory) then you can leave this as /, however if you’ve created a project folder to house your Kohana application you need to point this to where that project is. Hint: it’s the same path that we accessed to get to the previous phase, the system check.

My project happens to be in a custom path, so I’ll update my example.htaccess file.

# Installation directory
RewriteBase /projects/demoKohana/website

When you are ready to save this file, save it as .htaccess in the same directory. It’s an odd filename, but trust me on this. This file is handled by Apache and often times contains very important rules for how requests ought to be handled. You can read more about .htaccess on the Apache website.

Now that we’ve modified the .htaccess file, our directory ought to look like this:

Basic Kohana 3 root directory appearance.

  • application (folder)
  • modules (folder)
  • system (folder)
  • .htaccess
  • build.xml
  • DEVELOPERS.md
  • example.htaccess
  • index.php
  • LICENSE.md
  • install.php (deleted or renamed)
  • README.md

If this looks like your directory, you’re well on your way to finishing the setup process.

Once you’ve confirmed your directory structure is correct, we can move on to the the final touches before starting development with the Kohana 3 framework.

Updating the Bootstrap

Our next, and final, step is to update an array found within application/bootstrap.php. Within bootstrap.php, locate the following lines:

Kohana::init(array(
	'base_url' => '/',
));

Here, again, we’ll want to change the base_url value. Within a comment the Kohana developers tell us that this value represents the “path, and optionally domain, of your application.” As such, if you want to provide the domain you are more than welcome to. I will be using a path instead:

Kohana::init(array(
	'base_url' => '/projects/demoKohana/website',
));

Save, and exit.

At this point, if all went as it should, you should be able to refresh your project directory and find one of the most glorious messages developers have enjoyed since 1974.

To the Controller!

By default, Kohana will run the index action of the default Welcome controller. The default controller and action are set within the bootstrap.php file, located just inside the applications folder. Locate the following lines:

Route::set('default', '(<controller>(/<action>(/<id>)))')
	->defaults(array(
		'controller' => 'welcome',
		'action'     => 'index',
	));

If you would like to change the controller and/or action, you may do so here. Instead of changing the present values, I’m going to leave them as they are and simply take a look at the welcome controller. You can find the welcome controller source located inside application/classes/controllers under the filename welcome.php:

<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Welcome extends Controller {

	public function action_index()
	{
		$this->request->response = 'hello, world!';
	}

} // End Welcome

You can see from this code that all the action_index() method does is send the ‘hello, world!’ message directly to the response. No views are being loaded, so we’ll go ahead and load a view now. We’ll start by creating a new file at application/views/welcome.php and placing within it the text “This is my view.” Next, back in our controller we will make the following change to the action_index method body:

//$this->request->response = 'hello, world!';
$this->request->response = View::factory( 'welcome' );

Here we are loading the welcome view into the response. This now allows us to make changes to our applications/views/welcome.php file rather than modifying the output within the controller itself.

Next up, Using Views in Kohana 3.