Of Dice, Dabblet, and CSS

I discovered dabblet.com some time back and never really spent much time there. Don’t get me wrong, it made a great first impression, however I am not super-talented in the CSS department, and it seems to be a tool for those who are.

I decided to return this evening and try my hand at creating some dice with nothing but CSS. I recently became a Potentate of the Rose, so this was a relevant and timely interest. After a couple hours of distracted back-and-forth, I finally had something pretty attractive.

While I don’t consider myself much of a CSS power-house, dabblet.com made the tedious process of building these die super-fun and very palatable. If you find yourself giving dabblet a run (and I suggest you do it), be sure to thank @leaverou for all of her hard work on such an awesome tool.

The final result can be seen here, or in the framed demo below.

Creating Your Own Custom jQuery Filters

Chances are you have probably used custom filters in jQuery from time to time to save on verbose selectors. For instance, if we wanted all of the buttons, selects, inputs, and textareas within a form we could do the following:

$("button, textarea, input, select", "#myForm");

You can see how that quickly piles up and gets a bit heavy. jQuery natively provides us with the :input filter which grabs all form elements:

$("#myForm :input");

While these both do the same thing, it’s far easier to call :input than it is to construct a large selector containing all of the particular form elements we can remember at the time. There is a bit of  a performance issue with things like :input though, since they have to cycle over all potential elements. That’s why it’s wise to limit our load by providing some context, in this case we’re looking only within #myForm.

While we can do a lot with what jQuery brings out-of-the-box, we’re capable of doing so much more using some of the tools it provides us with.

You’ve likely used .filter to sift through your elements before applying some effects:

$("div").filter(":visible").hide();

The filter method can take a string expression like :visible and determine which of the div elements meet its demands, and which don’t. Those that don’t will be dropped, and all remaining will have .hide called against them. This method can take a function as well:

$("div").filter(function(){
    return $(this).text() === "Foobar";
}).hide();

Here we are manually sifting through the elements based upon some examination of their properties. We return true or false, depending on whether the current element being evaluated has the text “Foobar” or not. This solution isn’t very flexible though, what if I wanted to check different things for different strings?

Fortunately jQuery exposes itself in such a way that we can extend its base filters and add our own.

Our focus from here will be on $.expr[“:”]. Within the jQuery function ($) is an object called expr. This object has objects within, one of which is called “:”. This object is where we will place our new method, and provide the necessary functionality to determine which elements pass, and which fail.

$.extend($.expr[":"], {
    exactly: function(){
        return true;
    }
});

With nothing more than the above, we can already use our filter:

$("div:exactly");

Granted, it doesn’t do anything, but it doesn’t blow up in our face either! As is the case with most callback methods, the element currently being handled is referred to as this. With that, we could already perform some logic:

$.extend($.expr[":"], {
    exactly: function(){
        return $(this).text() === "Foobar";
    }
});

Of all the div elements we’re cycling over, only those whose text content loosely equals “Foobar” will be kept, while all others are discarded. But again, who wants to hard-code “Foobar” into the definition of the filter? Wouldn’t it be better if our filter worked like :contains in that it took some parameters?

It is at this point we need to look at the arguments passed to our function. We can do so by logging the arguments object from within:

$.extend($.expr[":"], {
    exactly: function(){
        console.log( arguments );
    }
});

$("div:exactly");

In our console we find the following:

[<div>​Hello World</div>​,   0, Array[4], NodeList[3]]
[<div>​Hello, World</div>​,  1, Array[4], NodeList[3]]
[<div>​Hello, World.</div>​, 2, Array[4], NodeList[3]]

My selector evaluated three div elements. The first argument passed to my function is the element itself. The second is the index of the element. Third is an array of details about the selector itself (more about that in a minute), and the last item is a NodeList of all elements being evaluated.

In this particular instance, our selector array looks like this:

[":exactly", "exactly", undefined, undefined]

We see it has a reference to the filter, the term used in the filter, and then two undefined values. If we were to modify our filter a bit to accept a parameter, we would see the following:

$("div:exactly(Foobar)");
[":exactly(Foobar)", "exactly", "", "Foobar"]

The first value is our entire selector. The second is our filter name, third in this case is empty (though if we wrapped our term in single quotes, this entry would be a single quote as the outer-most single-quotes would be removed from the last item in this array), and last is the actual parameter passed in. Armed with this knowledge, we can then finish our custom filter:

$.extend($.expr[":"], {
    exactly: function( element, index, details, collection ){
        return $(element).text() === details[3];
    }
});

At this point, we can now select any element based on its text value:

$("div:exactly(foo), p:exactly(bar)");

We now have a reusable solution to a common task.

First Impression of Windows 8 (Developer Preview)

I downloaded the developer preview of Windows 8 a few weeks ago so that I could begin playing with Internet Explorer 10. After setting up a new partition and loading the OS into a dual-boot environment, I was quickly up and running in Windows 8. I’ve been using the operating system almost exclusively now for a while, and I wanted to share some of the things I like, and some of the things I don’t like so much. In complete honesty, the likes greatly outweigh the dislikes – in fact, the dislikes are probably too few to require more than half a hand to list (but of course that may grow with more exposure and experience).

I write this today as somebody who knows nothing about what specific goals Microsoft has in developing this operating system. All I know is that it’s something of a one-size-fits-all, in that it’s intended to be used on both the desktop, as well as the mobile tablet interface. I’ll be honest, that fact alone had me a little suspicious. My desktop and my tablet are two radically different experiences. But could Microsoft really pull it off, and create something for both?

Fast, So Fast!

Setting up windows was quick and required very little effort. One thing I thought was especially interesting was the prompt I received to give the Setup Wizard my Live account email address. My user account is directly tied to my Live account, which I thought was pretty cool.

As cool as the Live account integration was, that wasn’t what floored me during setup: the actual boot time was! From the boot screen to my login screen, the process of getting into the OS often takes less than a few seconds. Honestly, when I select the Windows 8 Developer Preview from my boot screen, I find it difficult to actually count more than 2 seconds or so – what a joy it is to not sit and wait.

Here’s another demo online from Microsoft themselves, though I think my PC loads up just a bit faster – but hey, it’s no contest, right? 🙂

Of course the boot screen itself is pretty handsome now too – no more white text on a black background, Windows 8 is purdy!

Multiple Displays

I am running Windows 8 on a dual-monitor setup. This meant that when I log into the machine, my left (Primary) monitor loads up the new start screen, and my right monitor (secondary display) loads up a more traditional looking desktop.

This was the first major impression made – the interface for interacting with the computer had changed completely. While a little lost, and scared, I was excited. Scrolling up and down would slide all of these neat little panels left and right, revealing games, applications and other goodies. The first thing I did was jump into the Zero Gravity game and get lost in weightless-adventure for about an hour (I didn’t have my sound working at this point, so I’m surprised I managed to play that long without audio).

Gorgeous New Task Manager

After poking around on this screen for a bit, I clicked the “desktop” panel which slid the start screen out of the way to reveal a classic desktop experience on both monitors – ah, now I feel at home.

I was curious how much memory this OS uses, so I decided to visit the performance tab from the task-manager: CTRL+ALT+DEL brought up another nice screen, and sure enough, Task Manager was there on the list of items to select.

Immediately I noticed a much nicer looking task manager – good for him, he’s been pretty ugly for as long as I can remember.

I love how much details is shared in this newer task manager, and how nicely presented it is as well. The varying yellow background colors change as frequently as the values in the cells do themselves. It’s pretty neat – just a small panel of flashing cells and fluctuating numbers. Really puts you in that “I’m Neo, and I’ll bend your reality” state of mind. But this wasn’t what I wanted to see, I wanted to see the Performance tab.

Goodness, even more beauty! I love the colors, the layout, the entire experience is just awesome. I realize I probably sound like a Microsoft fan-boy at this point, but I don’t have an agenda here, my excitement is entirely organic. From one panel I can see my CPU usage, Memory usage, current Disk usage, Data sent and received over ethernet, as well as my current transfers in Kbps, and so much more. And to top it off, it’s actually aesthetically pleasing.

Okay, Time for a Complaint (Kinda)

I would hardly convince you that I’m being fair here if I didn’t list a few things that bother me about my initial experience with Windows 8 Developer Preview. Your Start button (or ‘Pearl’) is no more, it’s dead, it’s gone – write up its eulogy. Unfortunately,  I don’t think that we have been given anything better in its place. In fact, we’re given a very confusing alternative.

Both of my displays have their own taskbar, and both also have their own start button. This wouldn’t be so bad if each of the start buttons didn’t behave differently. On my main display, hovering over the start button reveals a small fly-out menu, as well as a large over-sized date (which I actually like):

Careful, don’t click that button. Clicking it will throw you back into the start screen with the fancy panels. This is what I mean by the start button that we all know and love is dead. I instinctively click this thing about once a day it seems, especially when I’m trying to find something I just installed.

Meanwhile, over on display two, there’s an odd looking icon in the place of the start button:

This button, when clicked, actually swaps the two buttons. If you click this, the start button from the primary display will replace this, and this will occupy the old location of the primary start button. Confusing, eh?

Essentially this button moves your fancy-panel screen over to this display. Clicking this button on my secondary display causes the neat new home screen of panels to be revealed on this monitor as opposed to my primary monitor.

The complaint here is that the traditional start button that we have known for nearly all of Windows’ history is dead and gone. Admittedly, it doesn’t take long to get used to this new behavior, but it’s entirely unexpected. Additionally, you can’t just hover over any portion of the main start button to reveal the fly-up mini-menu. From what I can tell, you have to hover over the lower-left corner of the button. At times I’ve found myself hovering over the button while thinking to myself “What the eph, computer – respond!”

Finally, Smart Taskbars!

The taskbar has always been a frustrating thing for me. I’ve found myself wanting them to be a bit smarter for several iterations of the Windows operating system, and with Windows 8, Microsoft has delivered! One feature in particular really excited me.

So, a lot of this stuff is pretty standard, but the “Windows appear” portion is what caught my attention. To be honest, I didn’t really understand what it meant, “Unique to each taskbar,” so I selected it and applied. I immediately found out that any programs opened on my primary display would show up in my primary taskbar, and any programs opened on my secondary display would show up in my secondary taskbar.

Further, dragging a window from display 2 over to display 1 results in taskbar 2 giving up the application to taskbar 1. Awesome! No longer does my taskbar just tell me that I have a program opened, somewhere, but it is now smart enough to tell me which display contains which application.

This post is quickly becoming a bit too large, so I’ll cut it off here. The more I use the Developer Preview the more I’ll have to say about it. But so far, I’m very pleased with what I’ve been seeing. Nice work, Microsoft.

Sometimes jQuery is (not) the Answer

It’s difficult to say, as much as I love jQuery I must admit that it is at times the wrong route to take when addressing a problem.

While looking over a few questions on StackOverflow today I came across a poster who was seeking to modify the width of all nested elements within a container – he naturally thought jQuery would be a good, simple solution – and it is. But while it may be simple, it’s wrong in this case.

Rather than coming right out and answering with something like:

$("#container").find("*").width("100%");

I instead took just a moment to whip up a test case on http://jsperf.com (great site for testing the performance advantages of one method over others.) Just as I had suspected, jQuery would be slower than raw JavaScript – much, much slower.

var i,
    container = document.getElementById("container"),
    tags = container.getElementsByTagName("*"),
    total = tags.length;

for ( i = 0; i < total; i++ ) {
  tags[i].style.width = '100%';
}

This simple block does the same thing as the aforementioned jQuery code, but it’s much faster. In fact, in the time it takes the jQuery code to perform 20k operations, the raw JavaScript code performs nearly 300k!

You can see this particular performance test online at http://jsperf.com/resizing-children.

Unexpected Results While Styling WordPress Menus

Today I sat down to convert a static theme consisting of nothing more than HTML and CSS into a WordPress theme, complete with calls to functions like wp_nav_menu() for the construction of the menu’s. For this particular theme I began with a copy of the TwentyTen theme. When I came across the task of establishing a navigational menu I found some rather unexpected results from WordPress – something I think they should consider changing in future releases. (Note: The following assumes version 3.1.3 is being used)

When you open up header.php in the TwentyTen theme you’ll find the following on or around line 85:

<?php wp_nav_menu( array( 
  'container_class' => 'menu-header', 
  'theme_location' => 'primary' 
) ); ?>

This is really pretty straight forward. It defines itself as the location for any menu assigned to the “primary” spot. Additionally, it sets a container class to “menu-header”. Given this information, we should expect this to result in is an unordered list wrapped in a div (the default container is a div) that has the class “menu-header”. So what markup is generated by WordPress when somebody sets up a fresh copy of it and checks out their TwentyTen theme?

<div class="menu">
  <ul>
    <!-- ... -->
  </ul>
</div>

At first there may not appear to be any problems, but look more closely at the container class declared in the call to wp_nav_menu() and what is actually applied in the generated markup. While we declared a class of “menu-header”, what we actually get is a class of “menu”. This really frustrated me this evening.

Some users of WordPress have been unable to reproduce this effect, and the reason is fairly simple why they couldn’t – they likely have a menu already assigned to the “primary” location. Anybody who does not initially have a menu created and applied to this location will be left scratching their head.

So what is WordPress doing exactly? Initially WordPress will look for a menu assigned to this location, if it doesn’t find one it will move on to do something else. Along down the line, just before throwing its hands up completely it will call a fallback method to generate something for the user. The default fallback method is provided for us in the source (line 141):

$defaults = array( 
  /* ... */
  'fallback_cb' => 'wp_page_menu'
  /* ... */
);

So if no menu is present when wp_nav_menu() is called, it will fallback into calling the wp_page_menu() method. Up to this point this shouldn’t seem like much of a threat. Sure, if I don’t have a menu WordPress can go ahead and generate a list of pages that I might have published. Unfortunately, this is where some communication-breakdown occurs and things get a bit messy.

Recall the generated HTML list previously shown, this is what wp_page_menu() generated for us in the absence of a user-defined menu. Like wp_nav_menu(), wp_page_menu() has its own set of internally-declared default arguments that will determine much of how the results will look and feel. We can see these defaults declared below:

$defaults = array(
  'sort_column' => 'menu_order, post_title', 
  'menu_class' => 'menu', 
  'echo' => true, 
  'link_before' => '', 
  'link_after' => ''
);

The only thing we’re interested in right now is the ‘menu_class’ which, by default, is set to “menu”. This is where the “menu” class comes from in the place of our “menu-header” class passed to wp_nav_menu(). This isn’t the light at the end of the tunnel, things get even messier from here.

While it’s nice of WordPress to generate a list for us in the absence of a menu, the integrity of our data breaks down in the process. When we call wp_nav_menu() and tell it to set the “container_class” to “menu-header”, the resulting call to wp_page_menu() completely ignores this request. Again, this isn’t the end of the mess, the wp_nav_menu() function also allows us to provide a ‘menu_class’, or a class which should be applied to the generated menu within the container. Suppose we did this:

<?php wp_nav_menu( array( 
  'container_class' => 'menu-header', 
  'menu_class' => 'foo', 
  'theme_location' => 'primary' 
) ); ?>

What we should expect to see from this is a menu that looks like the following:

<div class="menu-header">
  <ul class="foo">
    <!-- ... -->
  </ul>
</div>

This should be the result regardless if pages or custom menu items populate the UL. If no menu is present, and WordPress falls back on the wp_page_menu() function, what it generates is anything but expected:

<div class="foo">
  <ul>
    <!-- ... -->
  </ul>
</div>

Note how the “menu_class” is actually applied to the container, and the “container_class” of “menu-header” is entirely abandoned. This isn’t what we asked for.

If we turn around and create a menu called “Sample Menu”, and set it to be displayed in the “primary” location, what we are presented with is the following:

<div class="menu-header">
  <ul id="menu-sample-menu" class="foo">
    <!-- ... -->
  </ul>
</div>

Notice how it gets the container class correct, and the menu class correct when we actually have a menu for it to display.

I’m hoping this problem will be resolved in future versions of WordPress for the sanity of those creating themes. Not for them alone, but for the reputation of WordPress as a whole too. If its own internal communication isn’t consistent, it makes for a very bad testimony when those of us out in the real world are attempting to act as evangelists for the wonderful platform.

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.

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.

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.