prettyprint

Friday, 14 February 2014

Widget based architecture - Mobile Web

In my attempt to share knowledge I would like to show you a very simple, framework agnostic, way of building highly responsive re-usable components for mobile ready websites. Mobile in this age is a default, and sorry but if you don't think that way you are already out of the game.

Widget based architecture is a concept, or a set of very simplistic rules that make all the difference. And the really cool part is that full responsiveness can be achieved using only CSS and HTML. Without the use of, learning curve heavy, third party APIs.

Blog posts with lots of text and low information are boring, so let's go into the juice. The concept is simple, let's assume that for any component of a web page that you develop you have the following rules:

  1. Any top level component that you build is a widget (has the class widget in the html)
  2. A widget is always 100% width, it doesn't matter if it is dropped in a 100px wide or a 100000px wide place. It will always center it self and gracefully addapt to the provided width.
  3. (Who controls the width then?) A widget may have children widgets, and as he knows what kind of children he has, the parent widget will override the percentage width of it's children.

So a widget is pretty much the following square, and consider the .widget notation as the class within your html (rule 1):


<div class="widget widgetName">
      ... content of your widget ...
</div>

Let's go into an example, let's imagine that you want to have a responsive component that shows three elements side by side on wider screens and on smaller ones you want only two elements per row:


The parent widget knows he has three children. These children have no idea where they are so they just take 100% of the container (rule 2). The parent though, wants them to show side by side in groups of three, so he overwrites their width (rule 3), and set's them as floaters. Which generates this CSS:

.widget.parentWidget > .widget { width: 33%; float: left; }

So the parent doesn't really care what kind of children it has, the only thing he cares is that they are widgets so they will gracefully adapt to the shorter width. Although the parent can be designed to work with certain .widget types, and in this case it can overwrite some of their "visual design" properties. i.e.:

.widget.parentWidget > .widget.specificWidget { 
 background-color: purple; 
}

What about the responsiveness? Well... the parentWidget also knows that it will be used as top level widget and wants to have some breakpoints. If he is nested somewhere, that is not his call. Its parent (grandpaWidget) will have the responsibility of overwriting its breakpoints. So the parentWidget will set breakpoints for his children as he currently sees them:

@media (max-width: 780px) {
 .widget.parentWidget > .widget { width: 50%; }
}

The parentWidget is 100% of it's container, so if the window re-sizes it will also re-size the parentWidget. This will allow us to have a responsive structure with one step.: 




This base structure allows you to place any widget wherever you want, they will always adapt. We can then iterate on it by having each widget as an atomic component that accepts a view model. Each view model containing the data to populate the widget, allowing the base webpage to not really care what kind or what order of widgets it is receiving. But that is complex enough to build another blog post, so I'll leave it for later.

I hope this helped build a base understanding of the flexibility that Widget based architecture allows you. Now, go build widgets ;)










Sunday, 22 December 2013

How to build LESS pathways with browser detection

Someone told me I should write more, so here is a new post after a bunch of months.

During the past half year I have been working on building highly optimized responsive front ends. It has been an HTML + CSS intensive project that aimed at building a collection of specialized widgets, which could be easily re-used.

The team I was working with developed some very cool new techniques. I am going to share here one of them here. Which is how to build LESS pathways that generate distinct CSS files for different browsers/device environments.

For this example lets assume that we have two distinct device targets. Mobile and Desktop devices. The detection of the user-agent is not part of this article. There are so many good libraries that it would be pointless. We'll also pretend to be building a blog interface.

Since each widget should be modular and independent. Let's split them into separate files, create a 'sharedVariables.less' file which will include colors, gutter widths and other stuff, then build a main.less file that includes them all:

less/
 - main.less
 - sharedVariables.less
 - widgets/
  - navigationWidget.less
  - blogArticleWidget.less
  - commentBlockWidget.less
  - commentWidget.less


The CSS generated from the main.less would normally be the file to import in the HTML and the less would look something like this:

@import "sharedVariables.less";

@import "widgets/navigationWidget.less";
@import "widgets/blogArticleWidget.less";
@import "widgets/commentBlockWidget.less";
@import "widgets/commentWidget.less";

And in the HTML:

<link type="text/css" rel="stylesheet" href="/css/main.css" />

This would generate a single css file that is applied to any device, but it is not what we want. Anyone who has faced web development has found the need to apply small CSS tweaks to target certain devices or even specific browsers (i.e.: IE8). So an interesting way to solve this would be to import specific CSS files that would include only the CSS needed for that target.

Using some pseudo-templating code:

$if target == DESKTOP:
 <link type="text/css" rel="stylesheet" href="/css/devices/desktop.css" />
$else if target == MOBILE:
 <link type="text/css" rel="stylesheet" href="/css/devices/mobile.css" />

This is actually easy to do using less mixins. Mixins can be triggered depending on states of variables. So if we have a certain widget which needs to have different properties on mobile and desktop, we can use them. This is how they look like:

.widget.navigationWidget {
 
 (...) /* other code */

 .adaptative-section() when (@mobile) {
  background: @mobileBackground;  
 }
   
 .adaptative-section() when (@desktop) {   
  background: @desktopBackground
 }
 .adaptative-section;
}

You probably noticed the variables @mobile and @desktop, and so far we have no reference to where they are defined. Let's change the structure of our .less files, and add two more files "mobile.less" and "desktop.less" under a 'devices' folder. These will be the files which will generate the CSS that we use to import.

less/
 - main.less
 - sharedVariables.less
 - devices/
  - mobile.less
  - desktop.less
 - widgets/
  - navigationWidget.less
  - blogArticleWidget.less
  - commentBlockWidget.less
  - commentWidget.less

We can now have our 'mobile.less' file looking like this:

@desktop: false;
@mobile: true;

@import "../main.less";

and the desktop one:
@desktop: true;
@mobile: false;

@import "../main.less";

By importing these two files directly into the CSS generation we can build CSS files that contain only the CSS required for each specific device.

Hope this is usefull. Leave a comment if it helped you.


Friday, 22 February 2013

jQuery conference 2013 Europe Vienna review (part 1)


So the jQuery conference Europe 2013 in Vienna (Austria) has started. We were welcomed by Richard D. Worth which is a board member of the jQuery team. Followed by an introduction to how to build jQueryUI plugins to take advantage of the new WidgetFactory. I’m going to focus this post on the hot topics of the first presentation.

jQuery is now 7 years old, Richard pointed out that 55.7% of all webpages now use jQuery, and if you exclude from this group pages that don’t use JavaScript then it is used in an astonishing 90.7% of all webpages!

Part of the news is that jQuery 1.9.1 is out and it now supports a load more of stuff, such as CSS3 selectors, except those that would demand too much event handling. It was also noted that apparently there are lots of sites that link to the “newest” jQuery out there and  when jQuery 1.9 became the latest one thousands of sites got instantly broken.

Some breaking news that popped out: jQuery is going to DROP SUPPORT FOR OLDS INTERNET EXPLORER (6,7 and 8) !!! in it’s 2.0 (big applause from the audience).  It should be noted however that IE9 and IE10 are much more standards compliant so they will be automatically supported.

It was also presented the new jQuery membership (which will go on beta soon). Member ship will be available for both companies and individuals. Companies get website recognition, conference benefits and some other perks. Individual members will also get a bunch of annual gifts depending on the contribution, although everybody always gets something just by being there.  These include: stickers, buttons, tshirts, hoodies, bags, you always get something different. If you are interested in participating shoot an email to be a beta tester: membership@jquery.org

I’ll try to post more about the conference (or acquired knowledge later). Follow me on facebook (more active) or google plus (less active) for more updates and photos.

Wednesday, 30 January 2013

How to write maintainable javascript (or die trying) part I

I think I finally got it! After years of doing experiments I finally found the secret formula for maintainable javascript. I would like to share it, as well as invite you to peer review it.

(Edit from 2014 Meanwhile my coding style dramatically evolved from this, I'm keeping this post here more as a legacy reference)

When I began working with JavaScript The first thing I did was learning jQuery and watch the David Crawford's video Javascript the Good Parts. Afterwards I started a project which was a Ganttchart web app. If you dare to inspect it you will see the most messy JavaScript ever written. Meanwhile I kept working on doing other front end stuff, never dropping jQuery but always trying to improve my code style.

I don't want to bug you with the full story so I'll just cut to the chase. Following are the issues that most commonly occur when developing front end stuff: (This article addresses some of them)
- Declaring lots of loose functions/variables in the same scope.
- Repeatedly querying the DOM for the same thing
- Overuse of JavaScript closures
- Cross dependencies everywhere
- Using the DOM as a place holder to store variables and states
- Doing mega selector chains in jQuery

Each one of these issues has a reason to exist, otherwise they would not happen. Remarkably when you find code that has one, you will easily find signs of the others. Typically declaring lots of loose functions is the first code smell. You can argue that you have them only doing a stateless thing in the interface like:
function selectFriends(firstName){ 
    $('div.friend').each(function(i,e){
        var names = $(e).attr('data-name').split(); 
        $(e).toggleClass(‘selected’, names[0]==firstName); 
    }); 
}

function removeFriends(firstName){ 
    $('div.friend').each(function(i,e){ 
        var names = $(e).attr('data-name').split(); 
        if(names[0]==firstName){ 
           $(e).remove(); 
        } 
    }); 
}

If you only have the first function, I will not complain that you should encapsulate it. But the moment you start adding more functionality things will get messy.

Lets Identify the main issues present in that code:
- Every time we want to select or remove friends we are querying the DOM
- Both functions are dependent on the string “div.friend”, so if you want to change this you would have to edit it everywhere. Imagine if you have many references… on different files!
- Duplicate code.

To address these issues, it is always a good idea to use a map, after all JavaScript is all about maps. So why not run some code before these functions are called, which should build a simple data structure to store our references? As we are only doing operations on the first name we can use those as keys. Afterwards we can then store a reference to the DOM as the paired value. As names are not unique lets use a list of DOM references, so we can store multiple ones.

With this in mind we can now refractor the above code into:
var friendNames = {};

$('div.friend').each(function(i,e){ 
    var name = $(e).attr('data-name').split(); 
    if (!friendNames[name[0]]){ 
        friendNames[name[0]] = [$(e)]; 
    } else { 
        friendNames[name[0]].push($(e)); 
    } 
});

function selectFriends(firstName){ 
    for(var i=0; i < friendNames[firstName].length; i++){ 
        friendNames[firstName][i].addClass('selected'); 
    } 
}

function removeFriends(firstName){ 
    for(var i=0; i < friendNames[firstName].length; i++){ 
        friendNames[firstName][i].remove(); 
    } 
    friendNames[firstName] = []; 
}

In this new code we are no longer querying the DOM every time we want to select or remove a friend. The logic behind each function is also much clearer.

But a new issue arises: we are still writing all the code in the global scope, which isn't nice. So we should encapsulate it into an object which explicitly dictates its functionality. I like to use singletons for interface controllers that specifically handle a single functionality in the interface. To do that I store a reference to itself in its prototype.

So our object would look like this:
function FriendHandler(){ 
    if(FriendHandler.prototype.singleton){ 
        return FriendHandler.prototype.singleton; 
    }

    if(!(this instanceOf FriendHandler)){
        return new FriendHandler();
    }

    FriendHandler.prototype.singleton = this;

    var NODES       = { friends : $('div.friends') },
        friendNames = {};

    NODES.friends.each(function(i,e){ 
        var name = $(e).attr('data-name').split(); 
        if (!friendNames[name[0]]){ 
            friendNames[name[0]] = [$(e)]; 
        } else { 
            friendNames[name[0]].push($(e)); 
        } 
    });

    this.selectFriends = function(firstName){ 
        for(var i=0; i < friendNames[firstName].length; i++){ 
            friendNames[firstName][i].addClass('selected'); 
        } 
    };

    this.removeFriends = function(firstName){ 
        for(var i=0; i < friendNames[firstName].length; i++){ 
            friendNames[firstName][i].remove(); 
        } 
        friendNames[firstName] = []; 
    };

    return this;
}

We now have a nice object with public functions which anyone can easily understand. Any coder who reads FriendHandler().selectFriends(‘Jonh’); will easily follow the logic flow and quickly understand what is happening. On a side note a friend of mine, to whom I requested a review of this article, made this cool jsFiddle with an example of the code above.





Some details:

In this last code there are still some issues, one of them is: what happens if new html shows up? It's very common to have an ajax call appending new friends. Then our object would contain an inconsistent representation of the DOM, in both the NODES.friends and in the friendNames map.

To solve the first problem, which consists in the jQuery object representing old HTML entries. This representation could contain elements which are no longer present in the DOM and miss new ones which where added later. I created a small jQuery plugin, so small that it fits in a gist on github (link), to allow easy updating of jQuery elements stored in variables. With this plugin we just need to call update() to have the an updated version of the DOM without having to run the selector again.
    NODES.friends.update();
Know that we know of a way to update the jQuery object which we have stored, it is only a matter of creating a function to update our map. We can this way add the following to our object:
function _update(){
    friendNames = {};

    NODES.friends.update().each(function(i,e){ 
        var name = $(e).attr('data-name').split(); 
        if (!friendNames[name[0]]){ 
            friendNames[name[0]] = [$(e)]; 
        } else { 
            friendNames[name[0]].push($(e)); 
        } 
    });
}

this.update = function(){
  _update();
};


I hope you have found this article both useful and enjoyable. I will eventually write part II where I want expose how to write event subscription systems based on Observers. Thank you for reading and if you have any questions or feed back please leave a comment and I'll be glad to reply.

Wednesday, 2 January 2013

The status of real estate investment in Portugal

Many of you look at countries under bailout, such as Portugal, and think that now is the time to make real estate investment in these countries. The real interjection to this idea is both a yes and a no. I have been for the past years interested in buying something myself. But with this being a lifelong investment and with a computer science background I wanted to be as pragmatic as possible. So I started my market research, where I ended up studying macroeconomics and financial markets as well. I would now like to share the results and conclusions with anyone who may find them useful.

To properly understand the Portuguese real estate, we should take into consideration that buying a house or apartment has always been the favourite investment of the general population. It is also important to know that unlike other western European countries, Portugal has a very high amount of emigrants. Lots of Portuguese live outside of the country where they work in higher return jobs piling up money for when they eventually return.

Traditionally the emigration scenario leads to “power buyers” who are able to buy one or more homes without requiring credit. These return after they retire or if the macroeconomic environment improves. It is well known that Portugal is currently in a deep recession, which encourages the opposite! Every month thousands of Portuguese leave the country, many of them highly skilled and trained workers. The first negative variable rests here, if they would stay in Portugal, these workers would drive economic growth and would have the best salaries the country has to offer, making them the ideal home buyers.

Another two interesting factors are the severe aging of Portuguese population during a burst of a real estate bubble. The active workers which could invest in homes are either already paying one or having their salaries shrunk to a point where they hardly have any available disposable income. While their counterparts, the young ones, are either unemployed, paid poorly or leaving the country. If this is associated to the housing market burst it can be easily seen that the aggregate supply highly exceeds the aggregate demand. Leading to thousands of unsold homes all over the country, which leads to higher competition and declining prices.

It is not possible to talk about real estate investment without also analysing the renting opportunities of owning a home. And to properly do this we should first look at risk factors and investment yield. A low risk investment normally has a full return on investment of around 20 years which is represented by an averaged 4% annual yield on the total value of the initial investment. At the moment a home being rented has the same or lower yield after you consider extra costs, such has maintenance, real estate tax and other expenses. The risk also increases if you consider the dangers of renting to a bad person, which might severely damage your property.

People normally say “so what? You can still sell your home for more money than you bought it”. This is sometimes true, but this also applies to all other investments you do: stock, debt, precious metals, you name it. If the aggregate demand doesn’t increase it is more likely you will sell it for the same price you bought it than to score a huge profit out of your sale.

On the other hand if you wish to buy an extra home for vacations in one of Portugal great beaches, the power to negotiate is on the side of those with money. And there are very good opportunities with people getting desperate to sell properties in order to get some cash or free themselves from debt. Banks doing massive auctions and even the state is selling properties with a success rate of only 12%.

All this will lead to a decline (i'm not taking inflation into account here) in real estate prices during the next years until it stabilizes. So there is still a long road until the prices stop dropping, and with an average selling time frame of 14 months you can find really good businesses if you are patient. But don’t expect to quickly monetize your investment if you are buying solely to get the yield and profit from it.