I'm going to invent new abbreviation now. Testing, Refactoring, Patterns or TRP. The holly trinity of any good programmer and I'm going to talk about this things today, because many young programmers "those days" don't get the sake of the things right.
First things first. Testing.
I'm pretty much sure that you've heard this, but I'll repeat, that there's no excuse to not use tests. I know, many people think that it takes quite a big overhead and so it's boring, etc. I myself used to think like that, but believe me, once you start testing you won't stop. Think about it, do you know anyone who used to be a good TDD adept and then gave it up? I don't know any.
There's an edge which you should step over in order to become a good programmer and it's testing. The first time it will disturb you and you'll feel annoyed but then you will like it. Remember there are the things which you should get used to.
But keep in mind, many people do write tests, they madly covers each line of the code with tests, then write tests for tests and still produce a crap. And there's a reason, you should not concentrate on the tests themselves and make any kind of cult on it. Testing have it's own meaning and this is not an abstract safety, that's an ability to make your code better. Yes sir, you may write a good bunches of tests on your code and feel yourself safe but if you don't make your code better then, you was just wasting your time writing the tests.
Tests provides you an ability to improve your code safely. Once you have written some tests you may change your code, make some research, try this and that, find new tricks and do it safely. And once something went wrong you can easily see where and how it happened. Tests will teach you to write better code, and once you'll start to change your code you'll came to the second part of TRP.
Refactoring.
And this is the knowledge about how to change your code. Mr. Fowler had written an excellent book on this and invented a good system of "bad smells", the system which will point you at problematic parts in your code.
Yes, you may learn refactoring without tests, but then you will only suffer and won't ever open for yourself a truly power of the instrument. Refactoring needs practice, you should do it over and over until you instinctively will avoid problematic code pieces.
Once you will becoming better and better in refactoring you'll came to understanding of bigger parts of code and then you'll need the P of TRP.
Software Design Patterns.
It is said that patterns are for architects and team leaders only. But not in really. Patterns are trusted and many times rechecked software design solutions. They tell you how good people do it.
Once you started to practice refactoring you will need patterns, to not change your code blindly. Having patterns in your mind you'll do refactoring more consciously and more important you will try to make your code more standard, more understable for another readers and yourself first.
And yes again. You may start learn patterns separately of testing and refactoring but it won't give you much, case you won't be able to use it effectively without an experience in code refactoring.
Conclusion
TRP - Testing, Refactoring, Patterns. Those three things are wired tightly in reality and each one helps two another. You cannot be seriously good in any of those separately and should grow them up all together.
And do not be religious about the things, remember only the quantity separates venom out of cure. Teach yourself to feel the measure and you'll be gold.
Friday, February 22, 2008
Tuesday, February 19, 2008
Firefox 3 tries
Have installed FF 3-beta (Gecko/2008021416 Firefox/3.0b3), what can I say? Looks promising, they have revised many gui stuffs, now it looks quite nicer. And yes, as they had been promising, now it works with Cairo and renders native gtk widgets. That's cool.
But unfortunately, just as it was with FF 0.9 -> 1.0, FF 1.0 -> 1.5, FF 1.5 -> 2.0, all my plugins screwed up. No firebug, not firefox-webdevelop, etc. 8(
By itself FF 3, looks quite stable, had no problems so far, no crashes etc.
That's it. Will waiting.
But unfortunately, just as it was with FF 0.9 -> 1.0, FF 1.0 -> 1.5, FF 1.5 -> 2.0, all my plugins screwed up. No firebug, not firefox-webdevelop, etc. 8(
By itself FF 3, looks quite stable, had no problems so far, no crashes etc.
That's it. Will waiting.
Monday, February 18, 2008
Charged php-mode recharge
PHP is like a gangsta-rap. Everyone know that it's a bullshit, but from time to time do it for living.
So, as I had to support one of my customers with an old php-project recently, I've done some fixes in the charged php-mode. There are only minor fixes of highlighting issues, like the broken methods calls highlighting, $this_ calls lack, etc.
Get It Here
So, as I had to support one of my customers with an old php-project recently, I've done some fixes in the charged php-mode. There are only minor fixes of highlighting issues, like the broken methods calls highlighting, $this_ calls lack, etc.
Get It Here
Thursday, February 14, 2008
discovery.com seems to have nice round hole in their security
I was trying to register on their forum and accidentally found myself logged in under another user.
How did I do so:
1) Hit the Login/Join button
2) Proceed to the registration form
3) Feel it as they wish to
4) Enter instead of the desired username a username of an existing user
5) Press submit.
That's it. I've received the confirmation email and found myself under the user which was registered several years ago and have some posts. I even managed to create a post and now having the discussion.
How did I do so:
1) Hit the Login/Join button
2) Proceed to the registration form
3) Feel it as they wish to
4) Enter instead of the desired username a username of an existing user
5) Press submit.
That's it. I've received the confirmation email and found myself under the user which was registered several years ago and have some posts. I even managed to create a post and now having the discussion.
Tuesday, February 12, 2008
Epiphany updates look well
Monday, February 11, 2008
Recursive Camelization
Felt myself not much well since wrote a non-recursive camelization example in the yesterday article. So, now I'm fixing the lack ;)
That's it.
String.prototype._camelize = function() {
var _pos = this.lastIndexOf('_'), suffix = this.substr(_pos+1);
return _pos < 1 ? this : this.substr(0, _pos)._camelize()
+ suffix.charAt(0).toUpperCase() + suffix.substr(1);
};
alert('_camelize_me_pleaze'._camelize());
That's it.
Sunday, February 10, 2008
Binded Callbacks with Prototype
This article is all about using of the functions binding in callbacks when you're coding with the Prototype JavaScript Library.
We all know, that Prototype have got the Ruby's Enumerable module port in JavaScript. The idea is pretty simple, you've got a method where you put your callback function and when an object iterates through its stuffs it calls the function. Like that
That's fine, but there's a problem. When you write code like that, each such callback function creates an own scope and when you try to write a code like below it won't work
it will say you that there's no double_item function, and that's right, case it won't look for the proc.double_item function, it will search for the double_item method in the scope of the function object which you've sent as the attribute into the .collect method. (Which in the case will be the window object).
For such cases in the Enumerable module of Prototype defined an ability to pass another, optional attribute which will represent the scope in which the callback function should be applied.
With such a change the code will work, and you'll get the [2,4,6] alert.
That's nice. But if say you're implementing your own function which accepts a callback, and you don't want to pass the scope attribute. Something like that.
How can you handle that? That's easy. Prototype defines an additional method .bind(scope_object) for the functions, which returns another function which has the same interface but will execute the original function in the correct scope. Say you may write it like this.
Looks prettier, but this is not all again. What if you need not just to bind an existing method, but to make some additional handling, like that
What if you want a dumn function, like you used to have it with blocks in Ruby? That's easy, and kinda beauty. You can do it with that trick.
That's simple and maybe strange looking but it's handy. You may bind your functions on fly, and this's a quite often case.
And if you look closer you'll see the idea is in calling construction like
This is probably a quite dummy example and I should make it recursive to feel myself like a true hacker, but it shows the idea. You may apply functions on fly just in the time of their creation. Browse the Prototype's source code and you'll find lots of such tricks in there.
We all know, that Prototype have got the Ruby's Enumerable module port in JavaScript. The idea is pretty simple, you've got a method where you put your callback function and when an object iterates through its stuffs it calls the function. Like that
var foo = function() {
var two = [1, 2, 3, 4].find(function(item) {
return item == 2;
})
};
That's fine, but there's a problem. When you write code like that, each such callback function creates an own scope and when you try to write a code like below it won't work
var proc = {
make_it_double: function(list) {
return list.collect(function(item) {
return this.double_item(item);
});
},
double_item: function(i) {
return i * 2;
}
};
alert(proc.make_it_double([1,2,3]));
it will say you that there's no double_item function, and that's right, case it won't look for the proc.double_item function, it will search for the double_item method in the scope of the function object which you've sent as the attribute into the .collect method. (Which in the case will be the window object).
For such cases in the Enumerable module of Prototype defined an ability to pass another, optional attribute which will represent the scope in which the callback function should be applied.
.................
return list.collect(function(item) {
return this.double_item(item);
}, this);
// ^
// +---- here it is
...................
With such a change the code will work, and you'll get the [2,4,6] alert.
That's nice. But if say you're implementing your own function which accepts a callback, and you don't want to pass the scope attribute. Something like that.
var my_proc = {
handle: function(elements, callback, something) {
.............................
for (var i=0; i < elements.length; i++) {
var something = callback(elements);
}
.............................
}
};
var my_starter = {
foo: function() {
my_proc.handle([1,2,3,4,5], function(item) {
return this.update(item);
},....);
},
update: function(item) {
return item * 2;
}
};
How can you handle that? That's easy. Prototype defines an additional method .bind(scope_object) for the functions, which returns another function which has the same interface but will execute the original function in the correct scope. Say you may write it like this.
................................
foo: function() {
my_proc.handle([1,2,3,4,5], this.update.bind(this),....);
},
................................
Looks prettier, but this is not all again. What if you need not just to bind an existing method, but to make some additional handling, like that
................................
foo: function() {
var something = 'foo';
my_proc.handle([1,2,3,4,5], function(item) {
return something == 'foo' ? this.update(item) : 'bla';
},....);
},
................................
What if you want a dumn function, like you used to have it with blocks in Ruby? That's easy, and kinda beauty. You can do it with that trick.
................................
foo: function() {
var something = 'foo';
my_proc.handle([1,2,3,4,5], (function(item) {
return something == 'foo' ? this.update(item) : 'bla';
}).bind(this),....);
// ^
// +------------ Here you go
},
................................
That's simple and maybe strange looking but it's handy. You may bind your functions on fly, and this's a quite often case.
And if you look closer you'll see the idea is in calling construction like
(function() {})
, and actually you may go further and use it more like in the functional programming style. Say like that.
var caMeL = (function(str) {
var parts = str.split('_'), camelized = parts.shift();
for (var i=0; i < parts.length; i++)
camelized += parts[i].charAt(0).toUpperCase + parts[i].substr(1);
return camelized;
})('ca_me_l');
This is probably a quite dummy example and I should make it recursive to feel myself like a true hacker, but it shows the idea. You may apply functions on fly just in the time of their creation. Browse the Prototype's source code and you'll find lots of such tricks in there.
So much Groovy in the air
As the GRails hit the version 1.0 last week, there are so much articles about Groovy began to appear, more and more.
And this is the only beginning, case there are so much java developers tired of java and I predict a big hype around those stuffs ;). I had some experience with Groovy and GRails several monthes ago, when GRails was at version 0.5 and 0.6, that's a quite complex feeling, and this is about them.
Groovy, byitself is a tiny little ray of light in the Java world. Seriously. I'm not a big Java guru, but in my opinion, Groovy is the best damn thing happened with Java. You probably won't have so much beauty and easy feeling like with Ruby and definitely you won't have this cool-hacker feeling like with Python, but anyway Groovy is a very, very good language. It's a bit strange experience at the beginning, you try use it like Ruby and actually mostly can't, then you usually use the Java native libraries and all the time falling back to the Java coding approach. But after some tries and fails, after some readings, you get the idea of Groovy and it becomes more or less handy.
There are some good ideas in Groovy, like the how do they define everything, the authors were definitely inspired by a functional programming practicies, and as result you may do your lovely FP-paradigm with Groovy very much, there are all those nice stuffs like functions and carrying and so one. But then you always can fallback to more usual OOP stuffs. And definitely you may allow yourself all those metaprogramming goods you always been missing in Java :)
But on the other hand, you'll be printing all the time [ instead of {. If in same Ruby, Python, JavaScript etc. You have a standard meaning of [] - for lists, {} - for hashes. Then in Groovy they have all in {}, lists and hashes. It's again more like lists and lists of pairs in functional programming. So what can I say? It's not much friendly for people with different experience, but let em have it.
GRails, as I mentioned, I tried it when it was at version 0.5 and 0.6, and later I've looked through the version 1.0-rc. That was a quite, quite raw stuff those time. The behaviour was not much stable, always had some stranges in it, and sure I was not such happy and productive live with the original Rails. I would say it's a rails for java-developers (in the bad meaning of the word).
Heck those guys even don't support their own java-world stuff maven. The domain model constructions, like it usually is in java-world, very abstract and keeps you as much far from database as it possible. (I don't know why, but most Java-developers afraid SQL just as a fire). You don't have normal REST-idelogy support, you do have a doubtfull rest-pluging, but grails by itself don't have anything in it like that. I don't like the project's configuration, include the routes configuration, it was made out of hands. The testing organisation is quite bad. The internalization layer is "as usual in Java",- read rubbish. Very poor (at last after Rails) builtin functionality. And the biggest sin is no documentation. Almost at all. There are couple of useless books about Grails of old versions and some miserable articles and that was all. Almost no correct API documentation, no tips, not triks. And one strange screencast how to install grials with a horrible german accent :)
The only thing I liked in GRails at the time was the tag-libs feature. This is almost the same feature which you have in JSP, but you can define the tag-libs in Groovy, similar to the Rails helpers. And that was implemented quite handy, with namespaces, with normal inner blocks handling, etc. That's what I would like to have in Rails instead of erb.
And this is the only beginning, case there are so much java developers tired of java and I predict a big hype around those stuffs ;). I had some experience with Groovy and GRails several monthes ago, when GRails was at version 0.5 and 0.6, that's a quite complex feeling, and this is about them.
Groovy, byitself is a tiny little ray of light in the Java world. Seriously. I'm not a big Java guru, but in my opinion, Groovy is the best damn thing happened with Java. You probably won't have so much beauty and easy feeling like with Ruby and definitely you won't have this cool-hacker feeling like with Python, but anyway Groovy is a very, very good language. It's a bit strange experience at the beginning, you try use it like Ruby and actually mostly can't, then you usually use the Java native libraries and all the time falling back to the Java coding approach. But after some tries and fails, after some readings, you get the idea of Groovy and it becomes more or less handy.
There are some good ideas in Groovy, like the how do they define everything, the authors were definitely inspired by a functional programming practicies, and as result you may do your lovely FP-paradigm with Groovy very much, there are all those nice stuffs like functions and carrying and so one. But then you always can fallback to more usual OOP stuffs. And definitely you may allow yourself all those metaprogramming goods you always been missing in Java :)
But on the other hand, you'll be printing all the time [ instead of {. If in same Ruby, Python, JavaScript etc. You have a standard meaning of [] - for lists, {} - for hashes. Then in Groovy they have all in {}, lists and hashes. It's again more like lists and lists of pairs in functional programming. So what can I say? It's not much friendly for people with different experience, but let em have it.
GRails, as I mentioned, I tried it when it was at version 0.5 and 0.6, and later I've looked through the version 1.0-rc. That was a quite, quite raw stuff those time. The behaviour was not much stable, always had some stranges in it, and sure I was not such happy and productive live with the original Rails. I would say it's a rails for java-developers (in the bad meaning of the word).
Heck those guys even don't support their own java-world stuff maven. The domain model constructions, like it usually is in java-world, very abstract and keeps you as much far from database as it possible. (I don't know why, but most Java-developers afraid SQL just as a fire). You don't have normal REST-idelogy support, you do have a doubtfull rest-pluging, but grails by itself don't have anything in it like that. I don't like the project's configuration, include the routes configuration, it was made out of hands. The testing organisation is quite bad. The internalization layer is "as usual in Java",- read rubbish. Very poor (at last after Rails) builtin functionality. And the biggest sin is no documentation. Almost at all. There are couple of useless books about Grails of old versions and some miserable articles and that was all. Almost no correct API documentation, no tips, not triks. And one strange screencast how to install grials with a horrible german accent :)
The only thing I liked in GRails at the time was the tag-libs feature. This is almost the same feature which you have in JSP, but you can define the tag-libs in Groovy, similar to the Rails helpers. And that was implemented quite handy, with namespaces, with normal inner blocks handling, etc. That's what I would like to have in Rails instead of erb.
Friday, February 8, 2008
TestCase is going to be a framework independent
Initially when I started TestCase I just needed some testing facility for my Prototype based code and I was not satisfied with the scriptaculous testing way. But now, it becomes obvious to me that the project is not uses Prototype much in really and I seems need to test some MooTools based code, and then some people are too excited about jQuery.
So, I've thought that it will good for us all to make the TestCase project framework independent and put all the frameworks related stuffs in plugins or something like that.
That's it. Watch out, TestCase 2.0 is on its way to every mind ;)
So, I've thought that it will good for us all to make the TestCase project framework independent and put all the frameworks related stuffs in plugins or something like that.
That's it. Watch out, TestCase 2.0 is on its way to every mind ;)
Thursday, February 7, 2008
Javish source code formatting for the php-mode
If you tried the php-mode on Emacs, you probably meet the situation that it follows the c-mode rules in the code formatting. And if then you're more OOP apologist you probably would prefer some more javish-looking source code. Good news is that you actually can get so. Emacs is a totally configurable thing.
Put the following code into your emacs config.
This will provide you a correct 4-spaces indentation for all of your constructions. If you prefer tabs instead of spaces, change
Put the following code into your emacs config.
(defun my-phpstuff ()
(c-set-style "awk")
(c-set-offset 'arglist-close 0)
(c-set-offset 'string 'c-lineup-dont-change)
(c-set-offset 'arglist-cont-nonempty '+)
(c-set-offset 'case-label '+)
(c-set-offset 'comment-intro 0)
(c-set-offset 'defun-close 0)
(c-set-offset 'cpp-macro 0)
(c-set-offset 'knr-argdecl 'c-lineup-dont-change)
(setq tab-width 4
c-basic-offset 4
c-hanging-semi&comma-criteria nil
indent-tabs-mode nil
c-cleanup-list '(scope-operator)
c-comment-only-line-offset '(0 . 0)
c-backslash-column 48
c-hanging-colons-alist nil
c-hanging-comment-starter-p nil
c-hanging-comment-ender-p nil
c-indent-comments-syntactically-p nil
c-tab-always-indent t
c-comment-continuation-stars "* "
c-label-minimum-indentation 1
defun-prompt-regexp nil
)
)
(add-hook 'php-mode-hook 'my-phpstuff)
This will provide you a correct 4-spaces indentation for all of your constructions. If you prefer tabs instead of spaces, change
indent-tabs-mode nil
to indent-tabs-mode t
and you'll have it.
Wednesday, February 6, 2008
Charged php-mode for Emacs and something more
Case the official maintainers of the php-mode seems to be busy people I public it here.
This is a charged php-mode for Emacs. I mean it's the freshest php-mode with some fixes/updates/improvements which I've written for myself and now I share with you.
It's based on the latest php-mode version 1.4.0-beta and contains all the original features and adds some new
1) Fixes in the code highlighting, especially in_the_underscored_functions
2) Added the php's built-in functions highlighting
3) Added the php-doc tags highlighting like @param @return, TODO, FIXME etc.
4) Added a hotkey and functionality to execute the current php-buffer with usual C-c C-c command
5) Added a hotkey and functionality to execute the current buffer with the phpunit util (C-c C-p C-u command)
6) Some another highlighting fixes/improvements
This is the screenshot (click to see the full version). Hope it's not too much beautiful to you ;)
Get it here
And as I mentioned there's more
There's another sweet stuff for php-editing which had to exists but somehow didn't. It's a php-electric mode. Similar to another -electric modes for emacs, it put some hot magic under your fingers and creates language constructions for you when you type.
Try, you will like it. It's simple but handy and have the following features
* autocompletion for the if/for/foreach etc blocks
* autocompletion for the classes/interfaces/functions
* autocompletion for paired symbols like [] () "" ''
You can get it here
Both files might be easily inserted into your system. Just put them where emacs can see them (say in ~/.emacs.d/) and insert into your emacs config couple of strings like that.
That's it have fun!
This is a charged php-mode for Emacs. I mean it's the freshest php-mode with some fixes/updates/improvements which I've written for myself and now I share with you.
It's based on the latest php-mode version 1.4.0-beta and contains all the original features and adds some new
1) Fixes in the code highlighting, especially in_the_underscored_functions
2) Added the php's built-in functions highlighting
3) Added the php-doc tags highlighting like @param @return, TODO, FIXME etc.
4) Added a hotkey and functionality to execute the current php-buffer with usual C-c C-c command
5) Added a hotkey and functionality to execute the current buffer with the phpunit util (C-c C-p C-u command)
6) Some another highlighting fixes/improvements
This is the screenshot (click to see the full version). Hope it's not too much beautiful to you ;)
Get it here
And as I mentioned there's more
There's another sweet stuff for php-editing which had to exists but somehow didn't. It's a php-electric mode. Similar to another -electric modes for emacs, it put some hot magic under your fingers and creates language constructions for you when you type.
Try, you will like it. It's simple but handy and have the following features
* autocompletion for the if/for/foreach etc blocks
* autocompletion for the classes/interfaces/functions
* autocompletion for paired symbols like [] () "" ''
You can get it here
Both files might be easily inserted into your system. Just put them where emacs can see them (say in ~/.emacs.d/) and insert into your emacs config couple of strings like that.
(require 'php-mode)
(require 'php-electric)
That's it have fun!
Tuesday, February 5, 2008
How to defragment your XFS partition
If one beautiful morning, you like me found yourself having performance problems with reading from your huge XFS partition, you probably will think about defragmentation for the partition (at last if you had former windows experience). And will be right, case XFS in difference of ReiserFS needs a defragmenation. So this is how you may do it.
First you'll need to install some packages.
On your ubuntu/debian/suse whatever if you use the apt-get utility, say this.
Under Gentoo, this
Then you'll need to check if your partition needs a defragmentation in really
Once you see a scary fragmentation factor, run the command for the optimization
That's it, now you may go have a drink, lift something heavy, play the guitar or pay an attention to your girlfriend. This whill take some time.
First you'll need to install some packages.
On your ubuntu/debian/suse whatever if you use the apt-get utility, say this.
# apt-get install xfsdump
Under Gentoo, this
# emerge xfsprogs xfsdump
Then you'll need to check if your partition needs a defragmentation in really
# xfs_db -r /dev/sda5
xfs_db> frag
actual 22222222, ideal 2342342, fragmentation factor 99.9%
xfs_db> quit
Once you see a scary fragmentation factor, run the command for the optimization
# xfs_fsr -v /dev/sda5
.......
That's it, now you may go have a drink, lift something heavy, play the guitar or pay an attention to your girlfriend. This whill take some time.
Sunday, February 3, 2008
Client-side MVC
I'm going to describe my view on the client-side development, today. Under client-side, instantly I mean a complex of html/css/javascript which represents the user's interface in the web applications.
In general there's nothing new, this's just a slightly different point of view on the stuffs, which I've worked out for myself and which helps me to implement more complex and controllable solutions.
What is MVC.
MVC is one of the most well known software-programming pattern, originally, as I know, described by GOF. This pattern describes a point of view on any programming application as on a system which contains three main parts Model, View and Controller. Which mean in general the application data, application look'n'feel, and application logic. And if you keep the parts separated and don't mix them, you're good boy(girl) and keeps the things safe.
If you had no idea what MVC is before reading the article, you'd better proceed to same wiki for more details before reading further.
Preface.
You can meet this pattern almost in any good server-side system. Say same Rails (and all the clones), Django, TurboGears. All the modern web-frameworks follow the MVC rules. They have got a domain model which tied to the database structure, controllers which handle the users requests, and html templates which in the case are the view.
But when the people come to the client-side development, they usualy screw everything up, and began to produce a holly merry mix of all they have. And if a system is complex enough they soon come to problems.
The idea.
Among that, the idea of MVC in client-side development is on a surface. That's simple:
Your html/xhtml markuping - is a model,
Your css layer - is a view and
Your javascript - is a controller.
Yes, that's imple, but interesting not that, interesting the inquests you may learn out of this point of view on the system. Instantly if you are following the MVC idea, you should keep the parts as much separated as it's possible. In our case that means the following.
1) The markuping rules
Keep your markuping as much simple and clean as possible. That means no style="" attributes. Use as much suitable tags as it possible. UI for lists, TABLE for real tables, DIV for page blocks, span for inline elements, H1.. for your titles, etc. Try to be as much closer to the original tags meaning as it's possible.
Look at your markuping like on a real data-model. Your nodes should tell for themselves. Try too keep it with a minimum of class and id attributes. Don't use <div class="title" if you may use <h2> tag, etc. Remember you may make it look just as you need later. And read that fucking html manual at last! 8) I bet you'll find many rarely used tags which may replace many of yours divs with classes.
Try to not think about how you'll paint it later. Just make it have a resonable structure and look without any stylesheets.
Try to insert as less images as it possible. Use the <img tag only if you need to input a real image, like a photo or a diagram. If you need an icon, or a background or a design element, make it with a <div tag.
The main idea of all those tries, is to make your markuping the way that you won't need to change a single tag on a further redesign. Even if you're not going to make any redesign, such approach may safe you lot of time when you'll write your css and javascript.
2) The CSS layer rules
Put in your css layer as much design related stuffs as it's possible. Look at your css as on a thing which represents the application view. Put all colors, background images, icons, hover effects etc, here. If you followed the rules from 1) and keep your tags deversified, you'll have lots of abilities to paint your application just as you need.
The main idea here is that css-layer may be simple overloaded by additional stylesheets. If you keep all your design stuffs separated and one day one of your customers will ask you for a special logo for him or for a lovely another icons bunch, you'll be easy to do so just adding the customer specified css file without touching any of the original files.
The images in stylesheets worth an a special word. You may meet many goods and bads about keeping images such as icons and logos in css. But my own experience says me that it's a good idea and for a simple reason. One day it may be jpeg, another png, then gif. Then the sizes of images may be different, etc. If you have the images described in the css-layer, you may change it from here, otherwise you'll have to change the markuping.
And one more point. Keep in your css layer view of different states of the things as well. You'll probably need to define some additiona classes to represent different states of page elements, do so. Do not leave the things on your javascript, this is a metter of view and should be described in css.
3) JavaScript rules
When you writting your javascript always keep in mind that this is your controller and you are implementing the logic. Try to not put in javascript any element style changes. If you call a .style attribute that usually means you behave wrong and mix the things. If you need to change an element view, use your classes system from the css layer, use the addClassName and removeClassName methods. If you don't have an appropriate class in your css layer, create it there. Even if it will contain only one string, in further it will allow you to keep the things clean and controllable. All styles are metter of the view part of the system, do not change them directly from javascript.
And stupid but important, choose good names for the ids and classes in your markuping the way they were talking for themselves in your javascript code and you could always easily understand what's going on.
A simple example
For example you're implementing a dynamic menu. Write a simple and plain structure, like this
--- html ---
Then describe your menu view in your css, include the hover effects and current menu element related states.
--- css ---
Then write some plain javascript which will handle the menu states by switching the classes.
--- javascript ---
This is a very dummy example, it won't probably impress you with the power of the principles, but it displays the idea. Having the stuffs separated you may change them independently. Say having a good css-classes system which covers all the view points, you may change your model structure, add new elements and you always have a pretty simple structure which easily understable. Having a good deversified and smart structured model, you may change your css and change make your view look like you need. Having a good API of css class-names you may concentrate on logic in your javascript not worring how it will look later.
So, that's it, hope you had some interesting reading.
In general there's nothing new, this's just a slightly different point of view on the stuffs, which I've worked out for myself and which helps me to implement more complex and controllable solutions.
What is MVC.
MVC is one of the most well known software-programming pattern, originally, as I know, described by GOF. This pattern describes a point of view on any programming application as on a system which contains three main parts Model, View and Controller. Which mean in general the application data, application look'n'feel, and application logic. And if you keep the parts separated and don't mix them, you're good boy(girl) and keeps the things safe.
If you had no idea what MVC is before reading the article, you'd better proceed to same wiki for more details before reading further.
Preface.
You can meet this pattern almost in any good server-side system. Say same Rails (and all the clones), Django, TurboGears. All the modern web-frameworks follow the MVC rules. They have got a domain model which tied to the database structure, controllers which handle the users requests, and html templates which in the case are the view.
But when the people come to the client-side development, they usualy screw everything up, and began to produce a holly merry mix of all they have. And if a system is complex enough they soon come to problems.
The idea.
Among that, the idea of MVC in client-side development is on a surface. That's simple:
Your html/xhtml markuping - is a model,
Your css layer - is a view and
Your javascript - is a controller.
Yes, that's imple, but interesting not that, interesting the inquests you may learn out of this point of view on the system. Instantly if you are following the MVC idea, you should keep the parts as much separated as it's possible. In our case that means the following.
1) The markuping rules
Keep your markuping as much simple and clean as possible. That means no style="" attributes. Use as much suitable tags as it possible. UI for lists, TABLE for real tables, DIV for page blocks, span for inline elements, H1.. for your titles, etc. Try to be as much closer to the original tags meaning as it's possible.
Look at your markuping like on a real data-model. Your nodes should tell for themselves. Try too keep it with a minimum of class and id attributes. Don't use <div class="title" if you may use <h2> tag, etc. Remember you may make it look just as you need later. And read that fucking html manual at last! 8) I bet you'll find many rarely used tags which may replace many of yours divs with classes.
Try to not think about how you'll paint it later. Just make it have a resonable structure and look without any stylesheets.
Try to insert as less images as it possible. Use the <img tag only if you need to input a real image, like a photo or a diagram. If you need an icon, or a background or a design element, make it with a <div tag.
The main idea of all those tries, is to make your markuping the way that you won't need to change a single tag on a further redesign. Even if you're not going to make any redesign, such approach may safe you lot of time when you'll write your css and javascript.
2) The CSS layer rules
Put in your css layer as much design related stuffs as it's possible. Look at your css as on a thing which represents the application view. Put all colors, background images, icons, hover effects etc, here. If you followed the rules from 1) and keep your tags deversified, you'll have lots of abilities to paint your application just as you need.
The main idea here is that css-layer may be simple overloaded by additional stylesheets. If you keep all your design stuffs separated and one day one of your customers will ask you for a special logo for him or for a lovely another icons bunch, you'll be easy to do so just adding the customer specified css file without touching any of the original files.
The images in stylesheets worth an a special word. You may meet many goods and bads about keeping images such as icons and logos in css. But my own experience says me that it's a good idea and for a simple reason. One day it may be jpeg, another png, then gif. Then the sizes of images may be different, etc. If you have the images described in the css-layer, you may change it from here, otherwise you'll have to change the markuping.
And one more point. Keep in your css layer view of different states of the things as well. You'll probably need to define some additiona classes to represent different states of page elements, do so. Do not leave the things on your javascript, this is a metter of view and should be described in css.
3) JavaScript rules
When you writting your javascript always keep in mind that this is your controller and you are implementing the logic. Try to not put in javascript any element style changes. If you call a .style attribute that usually means you behave wrong and mix the things. If you need to change an element view, use your classes system from the css layer, use the addClassName and removeClassName methods. If you don't have an appropriate class in your css layer, create it there. Even if it will contain only one string, in further it will allow you to keep the things clean and controllable. All styles are metter of the view part of the system, do not change them directly from javascript.
And stupid but important, choose good names for the ids and classes in your markuping the way they were talking for themselves in your javascript code and you could always easily understand what's going on.
A simple example
For example you're implementing a dynamic menu. Write a simple and plain structure, like this
--- html ---
<ul id="main-menu">
<li><a href="home">Home</a></li>
<li class="current">
<a href="http:work">Work</a>
<ul>
<li......
</ul>
</li>
<li>
<a href="hell">Hell</a>
<ul>
<li.......
</ul>
</li>
</ul>
Then describe your menu view in your css, include the hover effects and current menu element related states.
--- css ---
#main-menu {....}
#main-menu li {.....}
#main-menu li a {.....}
#main-menu li a:hover {.....}
#main-menu li ul { display: none; }
#main-menu li:hover ul { display: block; }
/* represents the menu state */
#main-menu li.current a {......}
#main-menu li.current a:hover {.....}
#main-menu li.current ul { display: inline; }
Then write some plain javascript which will handle the menu states by switching the classes.
--- javascript ---
var Menu = Class.create({
initialize: function(element) {
$(element).immidiateDescendants().each((function(li) {
li.observe('click', this.choose.bindAsEventListener(li));
}).bind(this));
},
choose: function(event, li) {
// removing the 'current' class from all the li elements
li.up('ul').immidiateDescendants().each(function(element) {
element.removeClassName('current');
});
// adding the 'current' class to the clicked element
li.addClassName('current');
}
});
var menu = new Menu('main-menu');
This is a very dummy example, it won't probably impress you with the power of the principles, but it displays the idea. Having the stuffs separated you may change them independently. Say having a good css-classes system which covers all the view points, you may change your model structure, add new elements and you always have a pretty simple structure which easily understable. Having a good deversified and smart structured model, you may change your css and change make your view look like you need. Having a good API of css class-names you may concentrate on logic in your javascript not worring how it will look later.
So, that's it, hope you had some interesting reading.
Subscribe to:
Posts (Atom)