Although jQuery gets faster with almost every release, there are a few things to remember when working with it. Scott Kosman posted a nice roundup on writing faster jQuery code on 24ways.org. Some of those tips are already in use in my day-to-day code, but not all of it.
I found a really interesting thing for, well, bootstrapping web projects: Twitter’s Bootstrap. One problem I have every time I start a project is the styling. That basic stuff, like typography, margins here, paddings there. Things that don’t really add up to what the project is actually about. It feels felt like wasting time. With Bootstrap, you have everything you need right there. A big bunch of CSS classes, from rather simple things like labels within the text flow up to a grid system and basic website layouts. It also implements LESS, a “dynamic stylesheet language”. I frankly haven’t looked into it yet, but it might be the right time now.
The only thing you need to do is download Bootstrap and use it as the base to start the project. Or, even simpler, just link their stylesheet in your <head/> (of course you won’t have the cool jQuery plugins that way).
The styles are like the ones you find at twitter.com, blue glow around focused text fields and the buttons look like the ones found at twitter. You may of course change these to fit the project, although I think it’s not really needed for small training or test projects.
They also offer some simple jQuery plugins such as modal windows, tabs, popovers or “twipsys”. I suggest you take a look at it, really useful stuff.
If you like the idea of having such bootstrap files, but Bootstrap takes it a little too far for your needs, check out the HTML5 Boilerplate. It offers a lot of cross-browser optimizations and implements a huge bunch of best practices for creating websites, but no default styles to the extend Bootstrap does.
I actually tried to combine both Bootstrap and the boilerplate, but I just began, so I have to see how it’ll work out.
In order to train my Java skills I started a little program called “note”. It was thought to be some note manager, with adding, editing, deleting, etc. notes. Since I don’t have any clue of swing or AWT it was started as a console program – and never left that stadium.
The only interesting thing, well the only thing which might be interesting, is that it’s implementing the MVC (Model View Controller) pattern. You are able to write controller classes und action methods inside these classes, just like you know it from good ol’ Zend Framework. note’s implementation of the console-MVC is much like that found in Zend_Tool. This means that you write your commands as follows:
add note "Test"
This command would call the action “add” on the controller “note”, passing a single parameter with the value “Test”. note reads this input, splits it by spaces and searches for a class called “note.Controllers.note” and instantiates it. Next thing is setting the arguments of the controller and calling the action on that newly instantiated object. This is all done via reflection.
The code is poorly to not at all commented. On the other hand it’s not that hard to understand what is going on. If you have any questions, feel free to ask. Furthermore I’m sure as hell that there is some stuff in that code which doesn’t make any sense, or could be made better. So feedback is welcomed.
The GitHub repository can be found here: https://github.com/patrickburke/note
UPDATE NO. 2:
Plugin page is now online!
Yay, my first jQuery post.
jQuery.inlineComplete is a plugin which auto completes your typing inside the input text field, just like you see it in Google Chrome’s Omnibar.
Currently, this isn’t even tested in other browsers than Firefox 4 RC1, but I want this to be usable in production sometime, so expect some updates.
Demo: http://patrickburke.de/jquery/inlinecomplete/
GitHub repository: https://github.com/patrickburke/jquery.inlineComplete
It’s licensed under the MIT license, which also can be found in the README.txt
Questions and criticism are welcomed!
UPDATE:
Hell, a lot of changes, take a look into GitHub to see all the details. Here’s the short version: You’re now able to have the terms loaded from a URL. The plugin now also makes use of the HTML5 data attribute to accept a list or source of terms. There are examples in the index.html. I’ve also uploaded them to the demo directory, so go ahead and try it out!
I’m also working on a reference and manual page, shoudn’t take too long until it’s finished.
How I got to do this?
I’m using Google’s Chrome browser for quite some time now, and one of my favorite features is the auto-completion inside the address bar.
For those not familiar with it: If you type “face” in the address bar, Chrome completes it with “book.com”, and by pressing enter, http://www.facebook.com is opened by Chrome. For that completion, Chrome uses terms which were typed in there previously by you.
Today I installed the latest beta of Firefox 4 (Beta 12), which is laking this extremely awesome feature.
I googled several hours to find an extension which enables that feature. The solution I found was the “browser.urlbar.autoFill” about:config setting of Firefox. With default settings, you have to type the visited URL of the website you want to open. Thus, you have to type “http://www.face” to get the completion for “http://www.facebook.com”, which is rather impractical. But by setting the “browser.urlbar.default.behavior” setting (also found under about:config) to “32″, Firefox restricts the completion to terms typed in previously by the user, just like our old pal Chrome. A reference of the available values for this option can be found on the mozillaZine sites.
browser.urlbar.autoFill = true
browser.urlbar.default.behavior = 32
Now, our little fox turns up completing “face” with “book.com”, thus perfectly recreating Chrome’s behaviour.
In order to replicate the search- in address bar feature, you can install the Omnibar Add-On for Firefox, it’s small and does it’s job.
One of my co-workers currently writes his own website based on the Zend Framework. He wanted to use view helpers inside of the content, just like you do in view scripts. But the thing with content nowadays is that it is stored inside a database. He came up with a pretty simple, yet somewhat brilliant solution.
Basically, he loads the content from database, saves them as a file and passes the path to that file directly to Zend_View::renderScript(), which in turn handles the content as if it were a view script.
class IndexController extends Custom_Controller_Action
{
/**
* Index action
*
* @return void
*/
public function indexAction()
{
// Content article
$conGUID = $this->getRequest()->setParam('con_guid', 'default');
// Category
$catGUID = $this->getRequest()->setParam('cat_guid', 'main');
// content action
$this->contentAction();
// Deactivate auto render, we will render in content action
$this->_helper->viewRenderer->setNoRender();
}
/**
* Show content article action
*
* @return void
*/
public function contentAction()
{
// Evaluate params
// Content article
$conGUID = $this->getRequest()->getParam('con_guid');
// Category
$catGUID = $this->getRequest()->getParam('cat_guid');
// Set loaded false
$loaded = false;
// Content article AND category requested
if ( $conGUID && $catGUID ) {
// Configure cache object
// Set cache frontend options
$frontendOptions = array(
'lifetime' => 7200 // save for 2 hours
);
// Get script path
$scriptPath = $this->view->getScriptPaths();
// Set cache backend options
$backendOptions = array(
'cache_dir' => $scriptPath[0].'index/cache/'
);
// Create Zend_Cache_Core object
$cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);
// If no cache available for this content page
if(!$cache->test('content_'.$conGUID)) {
// Load content article
$content = new Custom_Content_Page();
if ( $content->load($conGUID) ) {
// Content assigned to requested category?
if ( $content->c_guid === $catGUID && true === $content->isOnline() ) {
// Content loaded
$loaded = true;
}
}
// Not found or not online
if ( false === $blLoaded ) {
throw new Custom_Content_Exception('Cannot load content page. Invalid parameter specified ('.$conGUID.').');
} else {
// Save content in cache object
$cache->save($oContent->getContent(), 'content_'.$conGUID);
}
}
// Try to load cache file
if ( $result = $cache->load('content_'.$conGUID) ) {
// Get metatags if guid is set
$oMeta = new Custom_Content_Meta();
if ( $oMeta->load($conGUID) ) {
$this->view->oMeta = $oMeta;
}
// Assign content
$this->view->content = $result;
// @TODO: dynamic ftw
$this->renderScript('index/cache/zend_cache---content_'.$conGUID);
}
}
}
}
The code itself should be self-explanatory, though it’s commented pretty detailed. As you can see, this is a basic database caching mechanism, but instead of caching the final output of the content page which would be parsed by the browser, the code itself is cached and used as a view script. That way, the view helpers (and any other PHP code inside the content) are executed and produce the desired output. Of course without using include() directly or, even worse, eval().
In order to have a real cache, one would need to cache the final output of that rendering action, say, as a HTML file. In this case, Zend_Cache is just used because you can quite comfortably check for already stored files and then load or write them. Zend_File anyone?
Did you know that PHP’s in_array() is pretty lame? I didn’t.
Here is a german blog post about it (maybe Google translator does a good job?): http://www.phpgangsta.de/php-in_array-die-performance-bremse
He wanted to write a “Search-as-you-type” tool, which internally worked with in_array() to check for uniques in an array. With about 50.000 entries, this took about two freakin’ minutes. Using md5 hashes as array keys and isset() instead of in_array(), he was able to reduce the loadtime to about a second, which is quite an improvement.
if(isset($freakinBigArray[md5($val)])) {
// do something fancy...
}
Recently I ran over HeadJS. I never heard of such script loaders before. Although I read that Google offers a JavaScript interface to load scripts from their CDN, I didn’t think of reducing the page load time in the first place.
Today I checked back to the website just to see how things are going. In the download section there was a link posted by the author which explains why HeadJS (and another script loader called “ControlJS“) aren’t as great in (pre)loading JavaScripts as LAB.js is. Miraculously the post is written by the creator of the latter script loader :)
I read the whole post (really long indeed…) and setup a little test (hopefully Apple won’t mind me using their scripts :). When you open up the three pages while your browser cache is deactivated, you will notice that the loading of the HeadJS “enabled” site takes twice as long as the page using the conventional script tags. LAB.js is indeed the fastet of all three.
In your network tab of Firebug, you’ll also see that the scripts get loaded twice by HeadJS, just as Kyle Simpson (a.k.a. “getify”) predicted it.
Of course this is not a real world-simulating test, I just wanted to see what happens.
Nonetheless, and as I wrote in the comments, I’d rather prefer HeadJS because of the additional features it offers. The browser feature detection, HTML5 enabling, and so on. But things are looking good, Tero Piirainen said he would eventually merge all that “wisdom” into HeadJS. Then HeadJS would be nearly perfect.
By the way, why do the ControlJS and LAB.js sites look so ugly? Not that I’m much of a designer, but it doesn’t need to be that “pragmatic”, take a look at headjs.com.
I enrolled for a Java Certification (OCJP OCJA), which is quite cool. The problem now is that I have to learn Java, therefore I’m not able to update this blog as often as I would like to, let alone to write the Zend_OpenId based consumer and provider. That sucks. But I want to publish those (relatively unspectacular) classes and how they’re used, and I will do that some time in the future! I promise.
Hopefully I can write some Java related posts in the future too, at least I’m planning to do so. This could even aid in learning the new language.
I struggled really hard at getting in touch with OpenID, especially with Zend_OpenId. Let’s face it: The Zend documentation looks more like a Klingon manual on how to slice up a Kirk. But Zend_OpenId is not the point now.
This article is the first part of a little series on OpenID (since all programming blogs have series, I thought it’d be cool to have one too). This part is about explaining OpenID in general and how it works (in more detail, but language unspecific).
So, what is OpenID?
OpenID is an authentication technique. Authorization is not part of OpenID. Just a word or more about the difference: Authentication is about determining who you are. Authorization is about defining what you’re allowed to do. Both can be done separately. You don’t need to know the guy who is drinking YOUR Bacardi in order to disallow him to do so (yeah, really stupid example).
First, let’s define some terms:
OpenID Consumer
- This is a so called “OpenID enabled site”, a website which allows it’s visitors to authenticate with OpenID.
OpenID Provider
- The OpenID server. Here you register yourself to get an OpenID, such as google.com. The consumer also requests this website in order to authenticate the user, I’ll come to that further down.
OpenID
- The OpenID itself is the URI you get from the provider.
OpenID allows you to use an existing account to sign in to multiple websites, without needing to create new passwords.
This is what openid.net says about the technique. What one might think now is that you register yourself at openid.net and get some kind of identifier, such as an email address, which then has to be passed to the website you actually want to sign in to.
As for the principle of OpenID, this is correct. That is, you register at a website ( = OpenID Provider) and get an URI as an identifier. That one needs to be entered into an OpenID enabled site and voilà: You’re logged in. It’s that simple. Well, at least on this site, that is, the user site. Depending on the provider, you may also be asked whether you trust the website you want to sign in to.
There are several OpenID providers out there, a list of some more popular ones can be found on the OpenID website itself. If you have a Google account, (one of) your OpenID(s) is https://www.google.com/accounts/o8/id. Some more experienced users now might miss the unique part in the URL. That’s right. The identification of the user is not done with the URL itself, but by the website (or webapp) behind that URI.
A little more detail, please.
In the OpenID authentication process, there are two separate authentications taking place. The first one is the obvious one: The OpenID authentication. The user signs in to the OpenID enabled site by passing his OpenID in. Then, the user must authenticate at the OpenID provider. The second one for example is when you sign-in into your Google account. As I said, the identification is not done with the URL itself, it is done by having the user to authenticate to the provider. The second authentication usually won’t happen every time you sign-in with OpenID, but this depends on the provider.
Basically, OpenID is fairly simple. The consumer sends a request to the OpenID (Provider) with specific parameters which define what the consumer wants know from the provider. Then the provider asks if the user trusts the consumer and, if so, responds with a success message. What these parameters are will be described later on, but for now, this is enough. After the consumer received the success message, he will verify the message by sending a request back to the provider. The messages are encrypted with a key which is defined upon the first request of the consumer to the provider. With the verifying request, the consumer makes sure the key is correct and that the message is authentic.
Also, the consumer may ask for more informations about the user. The provider then asks the user whether he wants to give the consumer these informations and sends them back together with the successful authentication message. This is the “Simple Registration Extension”. What informations may be passed and most notably how to do that is described in a later article.
Ok, I think I didn’t forget anything important :)
Next time, I’ll write an OpenID Consumer based on Zend_OpenId (yes, I learned Klingon).