Saturday, August 14, 2010

Yahoo's culture vs. Google's culture

Two interesting articles I have read in the past week had to do with Yahoo's "hacker-centric" culture - or lack of. Two different views, one from Paul Graham's "What happened to Yahoo" post and the second from Ryan Grove's "What's happening at Yahoo!". Both were excellent reads and provide an interesting look into Yahoo's culture.

These articles got me interested in comparing both Yahoo! and Google, and see which is more a technology/software firm. I started out with the leadership team of both companies and counted how many engineers, scientists and mathematicians are in both. I could be wrong, but I'm considering a "hacker-centric" culture is composed of a high number of engineers, scientists and mathematicians. So I'll refer to these as "techies".

The results were pretty amazing. The higher that number is, the more "hacker-centric" that company is. Feel free to comment about this, if I'm being biased or overlooked something. One thing I did, but not on purpose was I double counted some members if they were in both the board of directors and VP lists, so the ratios are a little skewed, but still the difference is huge.

First insight was the very different leadership structure in both companies. The boards of directors for both are rather similar, nine members in Google's, ten in Yahoo!'s, roughly the same number of "techies"; four in Google's vs three in Yahoo. Nothing surprising here.

Monday, August 09, 2010

Daily Digest

Last night I came across this sweet web app called paper.ly that generates a newspaper of your Twitter feed daily. It comes with a pretty basic embed that displays a table of contents for your own personalized news paper that you can embed on your blog or website. The people I follow are mainly from the tech community in North America and the Toronto Twitter community. You'll find posts from the usual suspects like GigaOM, TechCrunch, Mashable, and Seth Godin. Also some local people like Alex Blom, Scott Stratten, Breanna Hughes and Joallore have appeared in my daily digest today. Anyway, if you are interested in seeing what the Twitter community I'm following is publishing on Twitter, feel free to bookmark this page.

Sunday, August 08, 2010

Matt Ridley: When ideas have sex

Just came across this fascinating video on TED. Needless to say that when technological ideas have sex we can end up with the Twitters, Facebooks, iPads, iPods, iPhones, etc. etc. Enjoy.
At TEDGlobal 2010, author Matt Ridley shows how, throughout history, the engine of human progress has been the meeting and mating of ideas to make new ideas. It's not important how clever individuals are, he says; what really matters is how smart the collective brain is.

Saturday, August 07, 2010

Stay on your toes, think proactively

I was coming back home today and while in the elevator the lady that just got on forgot to press her floor's button. She realized a little too late as we passed the 15th floor; her floor. She then press 17, but that too was too late, then she pressed 18, and again that was too late. She gave up and got off the 20th floor with someone else. At that point I was thinking, if she pressed 17 and 18 at the same time, she probably would have gotten off at the 18th floor. Anyway, no harm done when you miss your floor, I just thought its an interesting intro to this post.

When things don't go to plan, most start to think reactively, how do I get back on plan? We panic and try all sort of different things to reduce the damage - with little consideration to the consequences of our remediation. Ex. You are driving on the highway and tailgating the person in front. Breaks go on, and now you are forced to slam on the breaks to avoid a collision. Thinking proactively would mean you wouldn't have been tailgating the person ahead, it would mean you were aware of what is happening around you. Isn't that what you get taught at driving school? Defensive driving is proactive thinking.

Even when things go to plan, you can begin to think reactively. Task 1 is done, on to task 2, then task 3, and so on. Following your plan blindly is also reactive thinking. I also think the longer your actions have been in line with your plan, the worse the consequences of your reactions will be when things eventually don't go to plan.

So, shit happens and you can't do anything about it, but good leaders shine when shit hits the fan. Good leaders are proactive thinkers. People who think reactively, are good at following, they're bad at leading; and that is okay. Not everybody can lead, and not every leader can lead all the time. I've been in positions where I followed great leadership; proactive leadership. I have also been in ones with reactive leadership. Its very different, but both offer lessons to learn. Good leaders know when to step out of your way and let you run with it. Because reactive leaders are bad leaders, and they're good at following, they expect others to blindly follow them - blindly following someone isn't proactive thinking.

Proactive thinkers are Linchpins.

Thursday, July 29, 2010

@flipboard - my personal magazine

I haven't tried this yet, and I don't have an iPad still, however this video is just screaming at me to go buy an iPad just for this app. It's kind of like how Shazam and UrbanSpoon apps in the iPhone ads were the "kick over fence" for me.



I'm not all that interested about using it for Facebook, the use case that appeals to me the most is its Twitter integration. Twitter is a brilliant way to keep up on news in any field, on any topic, any event.



I'm not that interested in reading any individual's Twitter feed on the Flipboard. What I'm interested in is something like NewsMap however personalized like Flipboard. For this to work the way I think I'll find it useful, it needs to support Twitter lists, more than off my feed. Following 350 people is not easy, it stopped being easy at 25, and this is where TweetAgora came to the rescue. TweetAgora tackles this problem from one angle, identify the noise to amplify the signal. Its a very good angle. I tried a lot of Twitter clients for the iPhone and Mac, and honestly no other app tackles it as effectively as TweetAgora.

There is another angle, the angle that Flipboard could come at it, from what I have learned from Bretton MacLean it doesn't support that angle yet. When the characteristics of the noise are known, we can improve the signal to noise ratio, however if you don't know these characteristics, then you could reduce the actual signal. One of the great things about Twitter is that it opened my mind to all sorts of different topics that I didn't know I was interested in, I can miss them in my global feed, and I won't have them in my agoras because the characteristics are still unknown to me.

So here is the meat of this post. I'm thinking some sort of crazy mashup of Twitter lists, combined with Twitter lists of members on Twitter lists I follow. Ex. If I follow list A, and user 2 is on list A and they own list B, perhaps mashing up the content in list A and list B will bring to my attention new stuff for me to read when I look at the Flipboard magazine that contains list A. After all, the magazine's soul purpose is to show you something you didn't know, and kill time. : )

Anyway, congratulations to Mike McCue and the Flipboard team. All the best. I can't speak for the app itself, but the video is sick! Help me kill time more effectively.

Monday, July 19, 2010

Dojo templates & Google Maps InfoWindow

I have been building mashups using Google Maps since 2007 and one problem I had is passing in the content for these bubbles that show up when you click on a marker i.e. the InfoWindow. One big annoyance with it, is that you have to pass in the HTML content as a string when opening the marker. I don't like it because I have to intertwine HTML inside of JavaScript. So how can we make this better?

Dojo Templates


Dojo Templates is the number one reason I love this library, I like the PubSub mechanism I posted about last time but not as much as the templates.

Dojo Templates allow you to associate HTML template files with your widgets, that get instantiated when Dojo parses your page and constructs the widget, basically replacing the references to your widgets with the widget's markup in the HTML template file.

First: my infowindow.html template file

<div class="infoWindowContainer" dojoattachpoint="infoWindow">
<h1>${title}</h1>
</div>

Don't worry about that ${title} thing just yet, but I guess you already can see where I am going with this.

Second: my infowindow.js widget

dojo.declare(
"nael.widgets.infowindow",
[dijit._Widget, dijit._Templated],
{
templatePath: new dojo.moduleUrl('nael.templates', 'infowindow.html'),
constructor: function(){

}
}
);

In this example, my infowindow widget's constructor is empty.

Next we create the marker. Here we using dojo.forEach to loop over all the points that were returned with our AJAX response to fetch points. this.map is the object within this map controller that references the Google Map. (This is the same controller from the previous post on Dojo PubSub mechanism)

dojo.forEach(pois, dojo.hitch(this, function(p){
var marker = new google.maps.Marker({
position: new google.maps.LatLng(p.lat, p.lng),
map: this.map
});
var content = "<div class='infoWindow' dojoType='nael.widgets.infowindow' title='"+p.Pois.name+"'>
" ;
this.addInfoWindowToMarker(marker,content);
}));


The important part is the line where we add the content. Yes, we still need markup in there, but now its just a placeholder for the real markup. We can pass attributes like title into the placeholder for nael.widgets.infowindow. So anything that you want displayed in the info window becomes an attribute. This allows you to focus on content, and not worry about presentation just yet.

The last method we call addInfoWindowToMarker creates a Google maps listener on the marker and connects the info window to it. Note, that the info window here, is not the widget we created in the beginning. The one at the top is "nael's infowindow" and only serves the purpose of templating.

addInfoWindowToMarker: function(marker,content){
google.maps.event.addListener(marker, 'click', dojo.hitch(this, function(){
this.infoWindow.content = content;
this.infoWindow.maxWidth = 300;
this.infoWindow.open(this.map, marker);
}));
}


If you try the above, and click on the marker, the content will still be empty. Because this is a widget, it needs to be constructed. You need to tell Dojo when to parse the DOM to look for new widgets that you introduced since the last parse.


google.maps.event.addListener(this.infoWindow, "domready", dojo.hitch(this, function(){
dojo.parser.parse(this.mapCanvasNode.id);
}));


We don't want Dojo to go looking through the whole DOM for new widgets, we know where the widget was added. So we can just tell Dojo to look for widgets within the div referenced by the HTML id this.mapCanvasNode.id)

Finally, back to our infowindow.html template:

<div class="infoWindowContainer" dojoattachpoint="infoWindow">
<h1>${title}</h1>
</div>


We can now adjust the template as we please without trouble, and this sure is much cleaner than doing this like I used to for years.

var content = "<div class='infoWindowContainer'>";
content += "<h1>" + title + "</h1>";
content += "</div>";


Maybe one day Google Maps will support templating the HTML for InfoWindows internally, until then, I'm sticking to the above when I can.



The benefit of templating the InfoWindow becomes obvious when you are dealing with complex InfoWindows with functionality built into it such as sharing on social networks, embedded videos, AJAX requests, pictures, etc. All that stuff can be templated, and only the dynamic stuff that comes from the backend is passed through.

Of course, on top of being able to template your InfoWindow markup, it is much easier now to replace an InfoWindow with a version 2.0 of the InfoWindow. You just have to drop in the new and improved widget and template, then abide by the Pub Sub channels you have defined between the widget and the rest of the application.

Sunday, July 18, 2010

Dojo How To: Publish / Subscribe

I haven't been using Dojo for a very long time, just over a year now, but its time I blog about all the little great features I have learned.

One of the features I like the most in Dojo is the Publish / Subscribe mechanism. Its flexibility allows you to cleanly implement communication between different components like modules, widgets, portlets, etc.

Lets get down to business. Say I have two controllers, a map controller, and the main app controller. The map controller owns the map object in my application, in this case a Google Map object. The app controller owns the communication with the user, browser, AJAX, etc. When my app loads, I want the map to go right to the user's location. The map doesn't care where I get the coordinates from, it just needs the coordinates.


startup: function(){

//some other startup code

//subscribe to the event we will get back from the app when coordinates are available
dojo.subscribe("nael.controller.app.currentPosition", this, this.eventHandlers.updateMapCenter);

//when Im done starting up, yell to the app controller saying Im ready for coordinates
dojo.publish("nael.controller.app.requests",["getBrowserCoordinates"]);
},


So the map widget will initialize the Google Map I'm using, do some other stuff, and when it is done it will publish to the app controller's "nael.controller.app.requests" channel. The message it sends to the channel is an array of arguments. In this case it is the request ["getBrowserCoordinates"]. Your channel names can be anything, I just use the Dojo module path to that widget and end with a good description of the channel, i.e. "requests"

On to the app controller:

The startup function of the widget just subscribes to the required channels

startup: function(){
dojo.subscribe("nael.controller.app.requests",this,this.eventListener);
},


One event listener for the "nael.controller.app.requests" channel. Notice that the listener just passes it to the appropriate event handler, the one we passed in to the channel.

eventListener: function(event){
this.eventHandlers[event]();
},


Finally, the eventHandlers object which will contain all our actual event handlers. Here we have the "getBrowserCoordinates" handler which was the argument ["getBrowserCoordinates"] the map passed into the channel.

eventHandlers:{
getBrowserCoordinates: function(){
if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(function(position){
var coords = {lng:position.coords.longitude, lat:position.coords.latitude};

dojo.publish("nael.controller.app.currentPosition",[coords]);

}
);
}
},

Once the app controller receives the coordinates from the browser's geo location API, it publishes the coordinates to the "nael.controller.app.currentPosition" channel - which the map widget has subscribed to during its startup step. When the map receives that event, it tells the Google Map to re-center around the new point.

I'm doing it this way, to reduce the number of channels each module needs to listen to. I can easily bring the browser to its knees if I have a unique channel for each event I'm thinking of raising. Remember, kitchens get dirty one dish at a time. It makes sense to have one "requests" channel for the main app controller, (or every widget as a matter of fact) that all other components can just send requests to.

You may ask why I have a specific channel for the current position? I guess I could have done it similarly to the requests channel. However, I figured that all widgets will be asking the app controller for stuff, while not all widgets would need to know about the user's current position. If we have a "responses" channel that all widgets subscribed to, it could lead to a lot of unnecessary chatter amongst the widgets and too many event listeners. The second reason, is that the current position channel, may get pretty noisy if it is a mobile browser. Couple both reasons together, and you have a recipe for disaster

So why should you care about JavaScript Publish / Subscribe?


The same reason you would care about it for other technologies. Its a better and much more powerful interface between JavaScript modules. Without these channels and event listeners, you would have just called the getBrowserCoordinates method from the map, or worse, you would have called the GeoLocation API straight from the map. You don't have to use Dojo for this, other libraries also provide you with a pub sub mechanism, like YUI EventTarget. Other JavaScript libraries have it, or have plugins for it. Its a design pattern that makes sense.

Note: if you are still not using a JavaScript library for your web app development, you should seriously reconsider because you are wasting a lot of time re-inventing wheels and light bulbs.

Another example, say you need to add a new widget, instead of trying to figure out where you are all the right places to call a method in this widget from another, you just add the widget and subscribe to the event that is triggered. Change request done.

One final reason, Publish / Subscribe is an excellent way to build a mockup of application workflow. You can stub in some datsabase data and when the backend is ready, you just replace the stub module with the one that will listen to the right request channel, and publish to the right response channel. And as an added bonus, if you screw up the channels, nothing breaks, the messages just won't get passed and you won't see browser errors when functions aren't defined. It fails gracefully - which is important.