Archive for the ‘programming’ category

The Programmer’s Folly: Simple is best

November 24th, 2009

First, let me get this out in the open: I am not a marketer. I am not a content-organizer. I am a programmer. I like writing code, and I like creating new ways to do things. I like making things because it helps me see how they work — out-of-the-box-solutions bore me.

And that’s where I screw up

On Monday it was a national holiday here in Japan (勤労感謝の日) and I had about 4 hours to kill while the wife was out on her daily walk. I decided to work on my site — and what I needed more than anything was a nice heatmap to log user clicks.

I used the amazing ClickHeat which is a free heat-mapping application written in PHP. It works right out of the box, is amazingly configurable, and runs quickly thanks to it being written in clear PHP.

Wouldn’t this be great as a CakePHP Plugin!

This is where things start to get messy.

I love CakePHP. It makes development easy, is rather fast, and is highly extensible. So, I decided to wrap the ClickHeat application in a cake plugin, make it “easy to integrate” and put it in the CakePHP Bakery, instantly receiving fame, fortune and the accolades of my peers!

4 hours later

I had a mostly-working prototype that logged the data beautifully (although I couldn’t decide how to group the data on a dynamic site),  but didn’t have any of the nifty functions of the ClickHeat software such as sorting by date, admin panels, etc. because I hadn’t built those views yet. But I was hopeful!

Then my wife came home and I stopped programming for the day.

The next day, in 10 minutes

I decided to install ClickHeat on one of my corporate sites at work.

  1. Copy ClickHeat folder
  2. Set Cache & Log permissions
  3. Turn on Japanese Interface
  4. Done

10 minutes. In ten minutes I had accomplished what I couldn’t complete in 4 hours, because I was prepared to use an out-of-the-box solution instead of trying the be the programming bad-ass and integrate it with CakePHP.

So this morning, I copied the folder to my CakePHP dir, made one change to the .htaccess file:

RewriteRule    clickheat/(.*)   -   [L]

And now I have working heatmaps on my site. (I also put them on my wordpress blog, so that you can see them in action for yourself).

See the amazing Japanese Programming Heatmaps! (User: demo / Password: demo)

The final Score

So, what’s the final score?

Being a “bad-ass” programmer

  1. 4 Hours Development
  2. 1 extra hour of planning before sleep
  3. No Viewing Functionality
  4. Installation NOT user friendly
  5. Call time of 300ms per click for spinning up the cake processor
  6. Logging Works

Being a smart programmer

  1. 1 Change in my htaccess file
  2. 10 minutes to install/configure
  3. Call time of 150ms / click
  4. Not following “best practices” for cakephp

I think it’s pretty obvious what the best choice here is.

While I adore CakePHP and the things it lets you do simply by following convention — it’s very easy to get sucked into the “Best Practice” mindset, and waste a lot of time working on something that honestly doesn’t need to be tinkered with.

Don’t re-invent the wheel

It’s amazing how many times you can read that phrase and still find yourself re-inventing wheel after wheel after wheel. If you have a tool that does a job — use it. Do not worry about your fiddly code, and your “it’s not made here” mentality.

If the application is LACKING you can always edit it. But it makes no sense to start with something that does everything that you want, and then try to hack it apart just because you can. (Although I have to admit, it can be fun)

With those four hours, I could have

  • written 1 article for my site,
  • uploaded around 10 flashcard packs
  • added 2 tests to the site
  • read a book
  • played a lot of video games
  • watched a movie
  • watched four (4) episodes of Doctor Who or The Green Wing.

So Keith, this is a message to you:

  • Don’t be a tool
  • Use your time wisely
  • If something works, do NOT break it just because you want to see how it works.
  • (Eat your veggies — love mom)

CakePHP DebugKit: Take Back your Debugging

November 12th, 2009

Yet another foray into the WORD: The Subtitle blog posts; today we’re going to look at the amazing features of the CakePHP DebugKit.

The DebugKit is a standard plugin for CakePHP written by Mark Story. It provides a lot more information that the standard debugging features of cake (Errors, warnings, SQL Queries) and also keeps them in a nice contained collapsible icon at the top of your page so you don’t have to have error messages and sql queries appearing all over the page.

The Debug Kit Interface

DebugKit Icon

DebugKit Icon

Click the Cake icon at the top of your page, and it expands to all the tools you’ll need.

DebugKit Expanded

DebugKit Expanded

If you click any of the titles there, it shows you various debug information such as the current Session information, how the Request was processed, the SQL Log, a timer for all the functions that were called, currently accessible variables and the current memory usage.

DebugKit Variables View

DebugKit Variables View

DebugKit Timer View

DebugKit Timer View

All in all, an amazing amount of information. And best of all? It stays out of the way so your designs don’t get cluttered with debug information while you’re testing.

Installation

Installation is easy.

Download

Download the debug kit from ohloh. http://www.ohloh.net/p/cakephp-debugkit

Install

Place the DebugKig in the plugins folder of your application:

/app/plugins/debug_kit/[INSERT ME HERE]

Connect

Add the DebugKit Toolbar component to your app_controller, so it will be available to all your controllers.


// app_controller.php
var $components = array('DebugKit.Toolbar');

Then set the debug mode to at least 1.

Problems

DebugKit isn’t a perfect system (or maybe my understanding of it isn’t quite perfect). In any case, these are some problems I’ve had with DebugKit, but even they’re not enough to really gripe about.

Speed

DebugKit does seem to take a lot more processing power to run it than the standard Debug functions of cake.

This is easy to understand, though, as with the timers, reporters and everything, it’s doing quite a bit more than the standard Debug functions, and gives you a lot more information. I’ve had my dev-laptop exceed the 30sec execution time limit quite a few times while running DebugKit, but nothing like that has ever happened on my dev-server, so I doubt it’s anything major. It does make navigation a bit slower though, so when testing user flow, I would recommend turning it off by setting the Debug level to 0 for the duration of the session.

And remember, if you switch your debug to 0, then the DebugKit isn’t run at all, so there’s no worries about it eating precious resources on your live server.

Ajax Reporting

Ajax doesn't seem to be affected

Ajax doesn't seem to be affected

When you make a request with Ajax, the DebugKit doesn’t seem to get spun up like it should — which results in it reverting to the standard CakePHP reporting, which (while not bad) is definitely a grade down compared to the glory of DebugKit. It would have been nice to have the reporting fed into another icon inside the div that displays the ajax result, or something to that effect. Perhaps there is a way, and I just haven’t found it yet. Always a possibility.

Conclusion

Really, there isn’t much else to say except: why are you waiting? Go download this thing now!

Return of the FaceBox: Iframes!

October 19th, 2009

This article is a follow-up to my (oddly?) popular article Simple Modal Boxes: FaceBox with Prototype which, as the name implies, talks about how to get FaceBox ( the amazingly cool JQuery Facebox-like modal window) to work with the Prototype framework, and then releases that code under the MIT license.

Ippatsu's Flashcard FaceBox

Ippatsu's Flashcard FaceBox

Where things went wrong: IFrames

I was fairly forthcoming about it when I released version 1.1, but my FaceBox had a major problem: Loading full HTML pages (as opposed to html snippets) borked the system. It was a combination of the <head> and <body> tags along with all that excess Javascript and CSS being loaded into an inline div that pretty much did it in. IE6 would display it (poorly) while anything else just gave up and displayed an empty box.

So I fixed it.

Starting with version 1.2 you can set a facebox to load in an IFrame by simply adding the tag “iframe” to the rel tag of the link.

So
<a rel="facebox" href="mypage.html">My Page!</a>

becomes
<a rel="facebox iframe" href="http://google.com">Google</a>

and now you’re cooking with crisco. The page will be loaded in an IFrame, and any links will be self-contained within that iframe unless you specifically break out of it.

Breaking backwards compatibility

So, I am a big believer in backwards compatibility, but unfortunately adding the iframe option, along with my desire to adhere to better HTML coding practices has made me break backwards compatibility with version 1.1.

But wait!

It’s simple to change over, and you can change over almost all your code with a simple search/replace! So let’s get to it!

New way to handle classes

The old way of handing classes was to simply put all the classes you wanted to use after a hyphen after the facebox tag, like so:

<a href="mypage.html" rel="facebox-class1 class2">My Classy Page!</a>

This brings about the problem that now “iframe” is just thought of as a class. (It’s also not very contained, and rather messy). So I changed to to be more self-contained by putting the classes in square brackets []:

The new Code

<a href="mypage.html" rel="facebox[class1 class2]">My Classy Page!</a>

Now you know exactly what is a class, and what is not, and it’s easier to use it in conjunction with the IFrames option above.

<a href="http://google.com" rel="facebox[class1 class2] iframe">This loads google in its own classy iframe</a>

Simple as pie.

New way to handle styles

Originally, my way to handle styles (useful for setting the height and width of a Facebox for a single message or page) was to put the data in the rev tag and just pass that through to the FaceBox. However, with the new class syntax, I had a chance to change the way that the styling works.

Also, the rev tag is used to describe how the current document applies to the link, so it really isn’t a good place to put the data syntactically. It’s much better to put it in the rel tag along with the class information.

The new code

So where you used to use the rev tag:
<a href="mypage.html" rel="facebox" rev="width: 500px; height: 300px">My Stylish Page!</a>

You'll now use curly brackets in the rel tag:
<a href="mypage.html" rel="facebox{width: 500px; height: 300px}">My Stylish Page!</a>

And we can combine that with the iframes and classes above, to further customize our facebox

Class and Style
<a href="mypage.html" rel="facebox[class1 class2]{width: 500px; height: 300px}">My Classy Stylish Page!</a>

Iframe Class and Style
<a href="http://google.com" rel="facebox[class1 class2]{width: 500px; height: 300px} iframe">This loads google in its own classy and stylish iframe</a>

Download the code

You can download the code right here! It’s Open sourced under the MIT License.

If you find any problems or bugs, feel free to drop me a comment!

Download FaceBox v 1.2 (Open sourced under the MIT License)

Simple Modal Boxes: FaceBox with Prototype

August 28th, 2009
alertI’ve updated my code with a newer version: Version 1.2 which includes such awesome things as full IFrame support and better support for classes and styles! You can check out the Article, or just download the code from here! The way the code is used has been changed, so be sure to read the README!

This article will teach you how to:

Open facebook-styled modal windows in both alert box and full ajax-styled version, using the FaceBox modal window script and Prototype.

I wanted my signup page for Ippatsu, an online Japanese learning application, to use a modal window for the sign up dialog. This allows me to use most of the visible area for copywriting, while not requiring a page transition to load the signup form.
You can also create modal windows like these with Prototype and the OSS code I’m releasing below.

Ippatsu's Flashcard FaceBox

Ippatsu's Flashcard FaceBox

A little history

Originally these modal boxes were used mainly for photogalleries and whatnot, and took up the entire screen with a cool faded out background and had a lot of animations. Probably the nicest and most well known was PhatFusion’s lightbox and multibox which are written on the MooTools javascript library.

As time went on, people wanted simpler boxes that did away with all the animation and crap and so extremely simple boxes like Particletree’s Lightbox Gone Wild which is a simple box with no animation over a 70% black border. It’s small, simple and gives a rather nice effect.

So what’s the problem?

Well, the problem with animation should be obvious: It’s slow and can be jerky on certain browsers. Definately not something you want to use for a UI Element.

And the issue with the background is that when you have your entire site blacked out, while you gain focus on the window you’ve just put up, it’s not very useful for information that you want to give the user without preventing them from seeing the rest of your site. In other words, we want a Modal Window instead of a lightbox type thing.

So Bring on the Modal Windows!

As far as this discussion is concerned, I’m going to be ignoring the windows-like full modal windows that allow dragging and dropping and whatnot, and only focus on simple Modal Boxes that can be used to display data. In particular, FaceBox.

Get to the Code Already

Ok, so FaceBox is a JQuery based modal window that is pretty much copied from the facebook site where they use it to display small bits of ajax text. It is amazing. You can get it at http://famspam.com/facebox . However, it only works with JQuery, whose existance I was not aware of at the time of creating my site, so I had to find a Prototype version.

FaceBox Prototype in google gave me a couple of good links, the most popular being Phill Burrows’ blog in which he ported FaceBox from JQuery to Prototype. Unfortunately, the post (and code) is rather old, and did not work on the newest version of Prototype that I was using (1.6.0.3).

Eventually I came to two guys who took Phill Burrow’s code and updated it: Robert Gaal and Scott Davis. Both seem very nice, but I was having some problems with the slightly older Robert Gaal version, and so decided to go with JetViper’s version, as it also proposed to have class support.

Unfortunately there were a few large problems with the FaceBox code as it as written:

  1. The code did not support class definitions of the FaceBox like it purported to (because of a coding error)
  2. There was no way to set the size of the FaceBox from code
  3. If the page being loaded was really long (such as having cakephp debug information) the window would stretch to fit all the contents height-wise, without scrolling
  4. No iframe support, so loading a page with javascript borked the load.
  5. No Close on Escape button

So I dug into the code and made some changes, and was able to fix problems 1-3 and 5 (and am still working on 4). The entirety of the code can be downloaded at the bottom of this page.

Fixing the classes

Looking at the original .js (line 175), you can see that Scott’s code says that you can add a class to the FaceBox content by changing the rel tag in the link to “facebox[.my_class]”

// support for rel="facebox[.inline_popup]" syntax, to add a class
var klass = elem.rel.match(/facebox\[\.(\w+)\]/);
if (klass) klass = klass[1];

Unfortunately, due to the way that FaceBox searches for FaceBox-enabled links, it will not recognize “facebox[.my_class]” as a FaceBox, as it looks for a direct match with rel=facebox.

So, I fixed that bug by changing line 93 in the watchClickEvents from

$$('a[rel=facebox]').each .....

to

$$('a[rel|=facebox]').each .....

The |= selector is a CSS Selector (valid in prototype) that allows you to define that The attribute’s exact value is “facebox” or starts with the word “facebox” and is immediately followed by “-”, so it would be “facebox-”. You can read more about Attribute Selectors at Smashing Magazine’s Taming Advanced CSS Selectors. It’s an amazing read. You can also learn about ~= (whitespace seperated) ^= (starts with) $= (ends with) and *= (contains) all of which are valid types of CSS selectors.

But wait, you say! How does “facebox-” translated to “facebox[.my_class]“?!?

It doesn’t.

I find facebox[.my_class] to be really unwieldy, so I changed it to facebox-my_class. This way, you can also put additional rel data in the link if you need, as long as facebox comes first.
All of these are valid:

rel="facebox-my_class help"
rel="facebox-my_class"
rel="facebox"

So, in light of this, we have to change the regex match in the click_handler from:

// support for rel="facebox[.inline_popup]" syntax, to add a class
var klass = elem.rel.match(/facebox\[\.(\w+)\]/);
if (klass) klass = klass[1];

to

// support for rel="facebox-inline_popup" syntax, to add a class
 var klass = elem.rel.match(/facebox\-(\w+)/);
 if (klass) klass = klass[1];

And then in your CSS to use the class:

#facebox_content.my_class{
 height: 300px;
 width: 500px;
 }

Done and done!

(As a smaller bug fix, I noticed that the original code never deletes previously added classes — only appends them, so I added this line to the reveal function to make sure that the classes were reset each time you opened a FaceBox

contentWrapper.className = 'content';

Stylize that Sucker!

So, problem 2 is that FaceBox has no way to stylize the lightwindow contents on a per-link basis — you have to define a whole new class for each type of lightwindow that you want. This in itself is not so bad, but it would be nice to have that slight extra amount of customizable power.

So, what I did is just add a “style” variable to each of the reveal/ajax/etc function calls, and had it append that style to the facebox_content div.

reveal    : function(data, klass, style){
....
//Set H/W or any other styles (also clears styles)
 contentWrapper.writeAttribute('style', style);
....

If you’re calling the lightbox from code, you just add whatever style attributes you want to the call

facebox.ajax('mypage.html', 'my_class', 'height:300px;width:400px;'

If you’re using the automatic calling from the rel tag, then you have to add a rev tag, and put your stylesheet in there. Anything you put in the rev tag will be copied to the style attribute of the contentWrapper

<a href="mypage.html" rel="facebox-my_class" rev="height:300px;width:400px">Link</a>

Simple as that!

(It should be noted however, that the height and width of the content_window does not take into account the borders, padding and footer of the FaceBox, so be sure to leave yourself a little margin of error)

No Scrollbars?!?

You still with me? It’s been long, I know, but just hang with me a little more. This is the last point.

So, as I said earlier, there’s a problem(?) with FaceBox wherein long content just makes the FaceBox longer until all the content is shown. As this system is made for display quick banners and small ajax pages and what not, it’s understandable that it would be left out, but why not put it in when it’s so damn simple?

So how do you do it?

//facebox.css
#facebox_content{
 overflow: auto;
 }

That’s it.

What this does is allows the FaceBox to extend to show all the content normally, but if you decided that the FaceBox needs a certain height (through a class or styling) then the FaceBox will be set to that height, and anything that goes over that height will be scrollable.

That Damn Simple.

In Conclusion

Not much of an “In Conclusion.” I’ve pretty much said all I want to say, so all there is left is to check out the codes~

If you find any problems or bugs, feel free to drop me a comment!

alertI’ve updated my code with a newer version: Version 1.2 which includes such awesome things as full IFrame support and better support for classes and styles! You can check out the Article, or just download the code from here! The way the code is used has been changed, so be sure to read the README!

Download FaceBox v 1.1 (Open sourced under the MIT License)