The WebApp Wizard Web development made magical

4Mar/123

Web development process, from end to end

Just a little post I wanted to write for a long time. Even if it is mainly aimed at beginner web developers, I think it could be interesting for more experienced ones to read on too. I don't pretend to be one of these kick-ass developers we see out there, but just an average one who loves his job, and do it as well as I can, yet not perfectly. So here is a quick honest overview of an average web development process and the tools that come with it, with its advantages and drawbacks.

The IDE

Maybe one of the most important tools, as we are using it a great part of our time. I used a few of them, from the most simple ones to the most advanced ones. After having used notepad, a few fancy visual editors, a few awesome and simple editors like TextMate and Zend Studio, I think I kind of made up my mind with Aptana.

First, the default theme looks great and has been a real relief for my eyes. At first, I wondered why this dark background was used, I felt it like a regression: we used to type light characters on dark backgrounds a long time ago, and then we started writing with black characters on white background. Just like we do with a pen and paper, that seemed kind of logical to me. But when we think about it, this is just stupid. A dark background doesn't emit as much light as a light one, so it puts really less strain on the eyes. So I'm definitely convinced by this default theme.

Then, even if they are not always perfect, available bundles to help with auto-completion or documentation work quite well, and suit my needs. Plus, there are some little bonuses like Capistrano integration that made me adopt it.

The only thing I regret from Zend Studio is the PHPUnit / Code coverage / Debug integration. That was really great. But Aptana will reintegrate debug support someday, I hope.

And last but not least, it is freely available.

There are also really great editors like TextMate, but honestly, I didn't have the courage yet to learn how to use these properly. Just know that it embeds tons of shortcuts and features that saves you time and effort though.

Minification

A key aspect of web development, as many of us know, consists in reducing the number of HTTP request our pages make, and in reducing the weight we transfer over the wire. I became aware of this relatively recently, and since I have spent quite a lot of time trying to resolve this issue. Reducing the number and weight of our requests helps a lot in producing fast responding pages, which is crucial for users with a slow Internet connection, but also counts for users with a good broadband connection.

Combining and minifying our files is good, but we don't want it to slow down or clutter up our development process. Ideally, this should be taken care of automatically. And after trying a few ways to do that minification process more or less manually, I recently stumbled upon the ideal solution for me, which I recently talked about. Assetic is so good not only because it takes care of combining and minifying your files, but also because it allows you to use all sorts of filters like Less, Sass, or virtually anything that could come to your mind. Moreover, it facilitates caching AND leaves no room for out of date cache. But I'll talk about this in the next paragraph.

Caching

Caching is also very important. I can't make my mind about this question: what is the most important part? Minifying or caching? After all, if our caching is right, our non-minification will only hurt us the first time the user hits the page. Once all the files are in the cache, magnification doesn't matter anymore.

So I consider caching at the same level of importance as minification. Once again, Assetic helped me a lot with this. But whatever the tool you use, the key is the key. Nope, this sentence has no mistake in it.

The most basic cache associates a key with a content, and updates the content related to a key, when necessary. The problem with this is that the client can't know directly if its cache is up to date or not. It has to ask the server "hey, is this cache still good or do I need to update it?". If it doesn't do this, it can lead to out of date cache entries, which can be more or less of an issue, depending on the context. So we can't have the best performance and best reliability with this kind of cache.

Another approach to this is to update not the value of a cache entry, but rather the key. When the client finds a key (filename) it doesn't know about, it will be forced to ask the content to the server. As long as the content doesn't change, the key won't change. But as soon as the content is modified, a new key/value pair is created, leaving the old key/value pair or deleting it. One one hand, we have a single key with multiple values over time, and on the other hand, we have a multiple keys over time, with only one value each. So the evolution of the cache is not a problem anymore. In other words, you have to version your filenames. You can do it manually, or you can use a tool like Assetic take care of this for you. It allows you to always serve fresh content, with maximum caching capabilities as the client doesn't have to ask if the cached entry is ok or not. Be careful though, adding a version number in the query string isn't always a good idea, as some proxies rely only on the filename to determine whether to download the file or serve it from its cache. So the best option is to change the filename itself.

Deploying

The last important step is how you deploy your app. Like many people, I started with some basic FTP upload, but as soon as you start working on more serious applications, you probably need something more reliable and more automated. That's why I began writing deployment scripts to help me out. The main problem when we do this manually is we are humans, so we are prone to error and to forget things. How many times did I have to put the server configuration file back in place, as it was erased by my development one which I just committed by mistake? I don't know, nut what I know for sure is "too many times". A script is more reliable for this, but, when this script is written by one human, it is also prone to error. The difference is that once the error is spotted and corrected, it is for good.

But we can do better: a deployment script that is written and used by many humans, therefore reducing the error risk. Not to mention this script will also probably have more features, which can be good too. That's the case with Capistrano, a really great deployment tool I started using last year. It not only takes care of deploying an app from a repository, it also versions it and supports a nice rollback feature in case something went wrong. Another really nice thing is that it allows you to store your users files outside of your code, and create symlinks automatically to ensure everything works as if the files where right under your code's tree.

To sum up

This was a quick post despite its length, and it covers a few topics just on the surface, but the aim was not to dive too deeply in these. It is more meant to give a few leads to follow and make your own opinion about what tools to use or not to use. I could also have talked about testing, but I am still not using this as a real part of my development process, sadly. I tend to use them more and more, but I don't think I am ready to really talk about this right now. A lot of other people will do this way better than me out there.

I just wanted to share the principle I run with, hoping it will help somebody, as I know I've searched for a long time before finding my way of doing these things.

Happy coding!

15Feb/114

Form submit confirmation, fast and easy

Following some demands, I recently released a new version of Fast Confirm, to make it more easy to implement when dealing, among others, with form submission.

But in the hurry, I forgot to include some features that I developed earlier, thinking "I'll put that online soon". And I didn't. So here there are, the missing features that some of you wanted. With version 2.1.0, you can now tell your confirm boxes that you want them to be unique, just by setting a boolean on invocation.

There is another little thing that I wanted to introduce alongside with the better event handling. Since version 2.0.0, you can simply bind FC to a form submit event, with the "eventToBind" parameter. There is a little problem with that.

Typically, a form will look like :

<form action="action.php" method="post">
   Username: <input type="text" name="username" />
   Email: <input type="text" name="email" />
   <input type="submit" value="Create user" />
</form>

So what happens when the confirm box opens? It opens pointing on the form. That makes no sense. A form is usually not a visual element. You will more likely want the confirm box to be opened on the submit button, or maybe on a fieldset, or even on a input field. But directly on the form tag? No way. Or at least, that would not be very frequent.

So I added the "targetElement" parameter. It simply is a selector that allows you to specify on which element, within the form, you want the confirm box to open. For example, a ":submit" selector will simply make the confirm box open on the submit button of the binded form.

Have a look at the demos!

14Dec/108

Javascript variable declaration and hoisting

Do you know what JS hoisting is? If you do, I guess you already declare your variables properly. But if you don't, I am pretty sure you can still improve your code a little bit, and make it much more reliable.

If you already experienced some strange variable behavior, like a variable's value being unexpectedly changed or not changed, this post is for you.

Let's see how JS handles variables through a few examples.

JavaScript variables scoping

First, let's have a look at how JS variables are scoped. One may think that JS is a C-like language. And yes, the syntax is quite C-ish. But the language works quite differently. And yes, variable scoping is really different from what you may see in C-like languages.

Most languages use block-level scoping. JS doesn't. It uses function-level scoping. You should keep this in mind at all times, as it is probably one of the greatest sources of confusion for newcomers.

So what happens if we execute this piece of code?

(function() {
  var a = 10;

  if (true) {
    var a = 35;
  }

  alert(a);
})();

Yes, it alerts 35. The same kind of program written in C would output 10 (provided you really re-declare your variable inside your block).

Well that's the first surprise. And not the last, nor the least.

JavaScript variables declaration

Well, let's see what happens when we declare a variable.

Let's take the following code:

var a = 10;
alert(a);

(function() {
  alert(a);
  var a = 200;
  alert('a now contains: ' + a);
})();

What do we have here? The first alert says "10", as we could expect. But the second one alerts "undefined". Why on earth would a be undefined? Try to remove the "var a = 200;" line. The second alert says "10" again? Right. So this declaration / initialization line has something to do with this strange behavior. No matter where you declare a variable in your function, this variable will be declared anywhere in this function. What about the initialization? It stays right where you wrote it.

Eventually, JavaScript hoisting

Wow wow wow... What's that? Do you mean JS doesn't care about how I write my code? Not really. In fact, the previous piece of code will be interpreted like so:

var a = 10;
alert(a);

(function() {
  var a;
  alert(a);
  a = 200;
  alert('a now contains: ' + a);
})();

In fact, all the variable declarations, but not the initializations, are put at the top of your function. This is commonly called hoisting.

Note that this works with all declarations. Even the functions declarations. Be careful though, as the variable-like defined functions will only see their name hoisted (as we saw in the previous example with variable a), but not their body. "Traditionally" declared functions will be entirely hoisted (name and body). Here is a little example you can run to understand this phenomenon:

(function() {
  f1(); // Will run OK
  f2(); // Will throw an error

  f1() {
    alert("I'm in function f1");
  }

  var f2 = function() {
    alert("I'm in function f2, but I will never run before the f2 initialization...");
  };
})();

That may seem quite surprising, but that's how JS works. I can't say if that's a good thing or a bad thing, honestly, I don't see any advantage or drawback. It's just another way to work. As it pushes us to keep a clean code, with all vars declared at the top, it may be a good thing.

Speaking of code quality, your code won't pass JSLint (when you select "the good parts") if you don't declare all your variables at once in each function.

But what should I do then?

This is why you should always declare your variables at the top of your functions. You'll have no bad surprises since you respect this rule.

I hope this post was useful, and that it will help you achieve a better code quality.

2Nov/100

A new way to paginate

Hi.

Just a little post to tell you I released a new jQuery plugin, Universal Paginate.

It simply allows you to paginate any content, and is not limited to a type of list or table. You want to paginate simple paragraphs? Universal Paginate is here for you. A table? UP is here for you too! Any kind of list (dl, ul, ol)? UP is here, again.

It supports natively some advanced features like remote Ajax JSON datasources, jQuery Templates syntax, on-the-fly changing of the number of elements to display on one page, etc.

Check it out!

2Sep/100

jQuery plugins I never (OK, rarely) code without

Yes, another "X essential jQuery plugins". But this one focuses on utilities that will make your life easier, and not necessarily the user's one. It's not about shinny UIs here, but just about useful utilities. From time to time, it's also good to think about ourselves. :-)

Well, no more talking, let's go straight to the point.

Livequery

Definitely a must-have. Ever had to re-bind some event handlers when doing dynamic DOM injection? Well, throw away your aspirin and download this plugin. It will save you some time, headaches, and performance. I can already hear: "why not simply using jQuery.live()?". Because Livequery supports a larger number of event types (but it tends to be less and less true) and allows to bind handlers on element creation and removal as well.

ClassLike

Ever wanted to store some data on DOM elements? Well, there is jQuery.data() when you want to attach data to your DOM elements from your JS code. For all other cases, there is ClassLike. ClassLike allows you to easily match and retrieve parts of classnames with regexps. You could have, for example, elements wearing the class "colnumber-X" where X is a number. And you want to get this number out of the classname. Well, ClassLike does it for you with a simple regexp.

jTemplates

jTemplates is not the kind of plugin you will need in every project, but it is still so useful that it deserved his place here. Basically, it's like Smarty, but in JS. Very useful for writing widgets, with live refreshing for example.

Form

How can I not mention the Form plugin? It simply allows you to control your form submissions, do some verifications before submitting, and more.

jQueryUI

Quite a heavy plugin, but really useful, from animations to advanced controls, dialogs, sliders... A must-have too. I won't go any further with this one, everybody knows about it.

Of course, there is no need to blindly add these plugins to your pages, but I think they solve frequent problems, and they deserve, at least, a try. You may just love them. :-)