Saturday, February 8, 2014

Developer games - how do they work?

If you're going to a developer game you might wonder how they differ from other kind of programmer pastimes like Hackathons, Programming competitions, just having a beer, talking and so on.

My definition (and as far I can tell I was the one calling these things 'developer games' in the first place) is this; 

A developer game is a combination of a programming competition and a computer game, where the challenges focus on the practical and fun rather than on algorithmic obscurity.

There are some algorithmic challenges from time to time, sure, and they can be quite tricky too. But the core concept is to have a welcoming, inclusive, little bit crazy event which you can attend to have fun and maybe win some prizes, but it's totally up to you and your team.

OK, so that's the overall picture, how does it work in practice?

All my 'Escape from /dev/null' developer games have taken place with everyone in the same room, or at least building, so that it's easy to ask questions and to interact with other people during the event.

When you arrive in the morning, you get login details to the game system and a reserved place to sit with your team. Then comes a general presentation about game mechanics, rules and how to play it in general, and then the system opens and off you go.

To the right is a picture from the presentation at a game I did at Valtech in Stockholm a year back or so.

There are two different games, though; The outer game looks like something like this;

The red text icons are team markers so that everyone logged in to the system can see where all other teams are on the map.

All teams begin at the same (or similar) location and can choose different paths to traverse the game-board to (hopefully) be the first team to snag the prize and the final node.

The nodes are the numbered circles and each node contains a programming challenge. Some nodes also contain prizes, so that the first teams to reach a node get the prize it contains (until there are no more prizes left on that node).

You can also see which nodes the teams are solving at the moment (white arrows) or if they have submitted a solution to the judges (red arrows) and how many minutes they have spent solving the problem (yellow numbers). The above game is an old game I've taken up to take a screenshot of, so the minutes numbers are quite huge, which is not normally the case.

OK, so say that your team gets a challenge, what does one look like and how does it work? I won't show you an actual challenge, but I will say that the challenges are thematic and most of them revolve around using a live web-based API where the inner game can be accessed.

For example the inner game can be (and have been) a multi-user space simulation where the team build a system one challenge at a time which controls a starship which can explore solar system, mine them and repair or build new things. 


The current inner game scenario is a multi-user rogue-like dungeon crawler, however. If you have ever played games like rogue, nethack, angband and the like, you know more or less what to expect - except it's in realtime, so monster do move even when you are not.

So let say that your team have solved a particular challenge, using the web-based interface you will then send of a short message to the judges who will then stroll down to your table and check out your solution.

If they spot a mistake or something that you've forgotten to do, the decline the submission and you have to give it an extra go or they accept the submission and your team is moved to the node which challenge you solved and you're free to choose a new one.

To the right is a blurry picture (I am so not a photographer) of what it looks like on everybody's screen when a team win a prize on a node.

You get to name your teams as you sign up and these guys decided to call themselves NullReferenceException (and was randomly assigned team code A02).

Another team in the same recent game called themselves "; DROP TABLE INFORMATION_SCHEMA; --", which was very optimistic :) I'm running Couch on the node.js back-end.

But the judging part takes us to the question of how and why the developer games exist at all. To fly all over the world setting these things up (not to mention buying prizes) costs a bit of money, so all events need sponsors.

And the whole reason I started doing these events was that I was so frustrated and dissatisfied with how development branding works when it comes to programmers. A lot of the communication is often done by a non-programmer who can't really represent the company properly and tend to brush programmers the wrong way.

What I would like companies to do (who absolutely depend on programmers) is to have more laid-back communication between their programmers and the actual programmer communities, and any evaluation should be done as respectfully and nicely as possible - and the best way I could think of was to create a cool, geeky and unique kind of game where programmer (the judges from the sponsor) meet programmers (the attendees) in a natural way.

The judges check out how you code and you get a chance to ask them how it's really like at the company they work for - if you want to. Many people just show up for the game and isn't really interested of the sponsor at the moment, but in a year or two that may change, and now they know who to contact.


Also if you live in or near Seattle, the next game will have Hulu as a sponsor. More information can be found here; http://swdc.se/devnull/instance/devnull-hulu-2014/

That's all really. Please ask any question you'd like in the comments if there is anything more you'd like to know

Cheers,
PS

Monday, November 12, 2012

Full Frontal 2012


Except for Google I/O, I never go to large or corporate conferences anymore. Since years back, I have by pure luck (or by being interested in the right things) found this complete gems, like the JSConfs in different reincarnations and regions, but closely snug together with them in my heart is the Sharp family's Full Frontal in Brighton.

I was lucky enough to attend the very first one in 2009, just weeks after attending the first European JSConf in Berlin, being completely floored by Jake Archibald's deadpan, on-the-spot humor and Simon Willison's last talk who he had completely rewritten after seeing (as I did) Ryan Dahl present node.js for the first time at the previously mentioned JSConf. The energy and the passion of these guys completely floored me and I later found myself talking about them and the conf very often and for way too long.

The boring terms for the magic sauce of Full Frontal is probably 'meticulously curated', but I really think that's what it is. It's a one-day, one-track conference with just the best of everything. I don't like all talks at all times, but most, I do, and not a little.

I could go on about great moments from other years, but will instead just applaud this year's choices like Chris Wilson (above) who talked about his days creating the Mosaic browser and working on most versions of IE at Microsoft before joining Google two years ago. It was history. My own, incidentally, remembering downloading NCSA Mosaic from a local university FTP site and all things that have happened since.



But the speakers are one thing and the context and environment is another.  The event always takes place at the Duke of Yorks' picture house, and old cinema in the middle of Brighton. For me it's very much a Groundhog day experience, but in a nice way. The weather is always coldish but not like it would be in Sweden, there's always a war memorial celebration about and I always stay at the same hotel.

Also, my friends are there, new and old. There's lots of drinking (well, I am drinking anyway :) and gapping about important things (programming and SF&F). It's a very, very welcoming atmosphere (again very much like the JSConfs) with warm quirks like the sponsor Dharmafly who set up a rack with small potted plants to take home.

I was nearly unable to go this year since I've done so much flying to promote the Escape from /dev/null programming competition (it sounds slightly meaningless at the surface but is really cool when you know more - hence the need to fly about) and I'd like to thank my wife for letting me fly *again* to goof off at a wonderful conference with my pals. I love you.

Cheers,
PS

Thursday, June 7, 2012

Konsulttimpriser i Stockholm (SWE)

[ This post is in Swedish, so if you for some reason are interested in theories and statistics about what programmer consultants in Stockholm, Sweden gets paid, Google Translate is your friend. Normal service will continue shortly. ]

Uppdatering:

@raiha skrev en mycket bra artikel för en månad sedan som också ger exempel på konsultpriser både för designers och programmerare: http://raiha.me/2012/05/freelancing-rates-in-stockholm-are-you-high-or-low/

@matshenricson Har också skrivit en relaterad, bra artikel runt timpriser (bl.a.) redan 2010; http://blog.crisp.se/2010/10/20/matshenricson/konsultmarknaden_behver_inte_vara_en_market_for_lemons



Vad är ett korrekt timpris?

Förra veckan hade jag ett par olika mailkonversationer som direkt eller indirekt handlade om hur mycket det är rimligt att en konsult får i timmen för olika programmeringsuppdrag.

Det ena gällde en bekant med mycket god meritlista som hade tagit ett uppdrag hos ett välkänt svenskt internet-företag för i mitt tycke ganska lågt timpris (700:-)

Det andra gällde mig själv, då jag fick erbjudande om att göra ett kortare uppdrag innan sommaren åt ett företag där mina experkunskaper låg i fokus (OO JavaScript, HTML5 Canvas, mm) och mitt lägsta timpris (1000:-) visade sig vara på tok för högt. Noteras bör att jag har gått på detta i över ett år heltid och tar (och får betalt :) upp till 1400:-/tim för kortare uppdrag.

Jag har länge haft en känsla av att avsaknaden av transparens i prissättningen gör det möjligt för olika dunkla vrår att bildas, men det kunde ju lika gärna vara jag som bara råkar ha haft en otrolig tur.

Tiden ur led.

Rent objektivt sett har det aldrig varit svårare för företag att hitta rätt IT-kompetens, samtidigt som nästinpå samtliga företag blir mer och mer beroende av IT och sina system för att konkurera och i många fall finnas till överhuvudtaget.

Reflekteras detta i konsulttimprisens utveckling de senaste tio åren? Nej, inte vad det verkar med dessa få mätpunkter.

Jag inåg att det som behövdes var mer data, och gick raskt ut till alla mina kanaler och bad alla och envar att fylla i en snabb enkät jag hade skapar för ändamålet.

Enkäten var anonym och informationen menad att göras fritt tillgänglig. Google Docs dokumentet som tog emot all data kan nås och laddas ner här.

Allmänt om data.

Jag gjorde frågorna ganska snabbt och skulle så här i efterhand tagit mig mer tid att tänka över fälten. T.ex. finns det inget sätt att ange hur kvalifierad man själv är som konsult. Det är dessutom fritext i fältet som bekriver updpragets längd, vilket leder till en del handarbete vid jämförelser.

Det finns också en del outliers, som det heter på svengelska, bl.a. kodnamn "ereså" som glatt skriver in 200:- som timpris, vilket antingen måste anses som en anställd som med låg lön som konverterar denna lön till timmar, eller någon inköpare som försöker lägga in knasdata för att vikta till sin fördel.

Det finns också åt andra håller en "Tt" som utger sig för att kamma hem 1800:-/tim för ett SQL uppdrag. Jag har träffat en person som har tagit (och blivit betalad) 1800:-/tim en gång, men dom växer inte på träd, så risken är att även den mätpunkten är lite tossig. [Uppdatering: Morten Nielsen har bekräftat att TT både finns och faktiskt tjänar så mycket!]

Det var bara 129 personer som deltog i undersökningen den här gången (vara två är rekryterare som har mailat in exempel på för dom höga timpriser, som jag har lagt till längst ned), och jag vet inte hur pass statisktiskt signifikant mängden data är, men jag tycker en sak känns ganska klar;

Översiktlig analys.

Det finns ett A-lag och ett B-lag.  En stor grupp av konsulter harvar runt på 700-850, medan en annan grupp konsistent ligger över tusenlappen. Jag tror att uppdelningen i lag har mindre att göra med kompetensen hos konsulterna än hos inköparna.  D.v.s de företag som känner till sina behov mer exakt vet också vad det är värt. Linjearbete skall man inte köpa in konsulter till.

Sedan finns det de som antingen är gravt inkompetenta och/eller grundlurade som halkat under 700, vilket jag ser om en slags minimigräns om du skall ha konsultverksamhet överhuvudtaget.
Anlednignen till den mer eller mindre fixa gränsen är att det är punkten där det blir möjligt att båda ge en schysst lön, spara pension och lägga undan lite pengar till investeringar.

Under den ungefärliga punkten blir detta svårt och över den blir det plötsligt möjligt - lite grand som ångpunkten för vatten. Det blir en fasförändring.

För de inköpande företagen, däremot finns det ingen ångpunkt. Det är bara en linjär ökning eller minskning av konstnaderna, och det är därför debatten är såpass viktig.

Det innebär inte att jag tycker att 700:-/tim är en bra lön för alla konsulter, det innebär att jag tycker att det är en rimlig abslut minigräns ut till konsult. Där är ankaret. Frågan är sedan i nuvarande marknad inte hur lite en konsult kan ta betalt för att få jobbet utan hur mycket företaget är berett att betala konsulten för att anlita honom/henne.

Båda parter verkar tro att de tjäner på att underhålla och prata tyst om siffror, men i själva fallet är det precis tvärtom. Ju mer hemlikghetsmakeri, ju mer kan enskilda företag pressa folk eller företag utan kontaktnät alldeles galet.

Jaha, men vad sa siffrorna då?


Medelvärdet, rakt av på timpris för alla angivna siffror blev 860:-/tim, vilket faktiskt vekar avspegla rätt väl ett normalpris i B-ligan.

Annars är medelvärdet per kundtyp följande;


B2B         kr 817.30
Bank kr 875.68
Handel & Försäljning kr 827.00
Industri kr 925.41
Offentlig Verksamhet kr 849.00
Onlinetjänst mot konsumenter kr 836.46
Spel kr     kr 805.00
Annat kr 884.46

Din tur

Ta gärna siffrorna och gräv fram mer data, och kommentera gärna nedan i största allmänhet.

Mvh,
PS

Sunday, April 15, 2012

Escape from /dev/null

Everything began around summer last year, where I got the nth request from a company if I knew a good programmer who they could hire.

I generally think that everyone should start their own companies, to get as much control over their lives and income as possible, but what have become more clear over time is that most people prefer the illusory safety of an employment over the guaranteed ambiguity of self-reliance.

Even so, I wasn't really comfortable just handing over people or acquaintances to companies I sometimes knew very little about.

Getting paid almost made things worse, and I realized I had a problem with the employment process itself (not getting paid as such:).

How about instead of getting contacted by a person guaranteed not to be a programmer and who happily confuse Java and JavaScript, desperately trying to get you to come to an interview, one could create a meeting-place where the actual programmers of a sponsoring company meet and interact with other developers whom they might or might not be interested in hiring now, or in the future?

The idea of the Escape from /dev/null was born. Yes, the name is cheesy, no it has little or nothing to do with anything at all. I like it anyway :)

I wanted to create a game, where teams of players met in a ballroom where they got small programming challenges which got increasingly harder over time.

Each cleared challenge let them move one step ahead on a public game-board, projected on a screen.




The benefits for a sponsoring company are obvious;
  • The competition would be interesting and fun enough in itself, being an actual programmers competition where one win prizes and not a recruitment event.
  • Instead of letting a programmer (who have lots of other stuff on his or her plate) spending time on a first phone-screen, writing up the results of that and then get three or four programmers to dedicate another half-day each for on-site interviewing under what I would call 'hostile' condition, they dedicate one whole day to interact with other programmers under playful conditions which still show the extent of their skills.
  • The marketing emphasize the recurring event, not the sponsor, in the same way that a recurring conference does, thus reaching out to developers who would not at first consider the sponsoring company as an employer but which after getting to know and work with the programmers of the sponsor during a whole day might think otherwise afterwards.

Unlike a Hackathon, competitive or otherwise, the process of a /dev/null event is as follows:

Each team (this time we had two-person teams consisting of one front-end and one back-end person) has a similar starting point on a tactical map.

The map represents a 'node' in the AI system of an alien artifact which has captured the spaceship where the attendees reside as crew.

However, they are all trained system countermeasures specialists and know how to hack alien software.  Lucky for them, eh? The only way forward is to reach the central node before the attack drones outside manages to breach the hull, by fooling the AI using ancient programming techniques known as 'JavaScript' and 'Python'.

When the team chose their target node, they get a programming challenge. When they are done with the challenge they interact with the judges, who either send them back again or accepts their solution. They are then moved forward to their designated node and are free to choose a new destination.

Certain nodes also contain artifacts, which can bestow powers onto the team or just prizes. This team all artifacts was prizes but I have some ideas in that area for future events.

Since my co-organizer/Main sponsor this time was Spotify, we had a musically themed set of prizes.

The only thing we gave away at the start was that the team that managed to reach the final node first would get one SONOS Play 3 music system each. SONOS was also a sponsor of the competition (along with Brooklyn Lager).

The other prizes were kept secret until a team managed to win them, but ranged from concert tickets, custom-made Spotify headphones to decal and goodies Spotify bags.

I had great luck in getting my friend Robert Hancock, Pythonista extraordinaire to both create the Python-specific challenges for the event, bot also actually come to Stockholm and speak at the beginning of the event!

Always entertaining, full of stories and good humor, Bob did an excellent shortened version of his recent PyCon talk "Optimizing Performance with parallelism and Concurrency", which I felt really bad for giving such time-constraints.

Even for a non-Python programmer, it contained not only nuggets but heaps of gold, with lots of computer and systems history thrown in for good measures. Good times!

I had an audacious idea to provide each attendee and team member with his or her own version of the game-board and interface instead of just moving around the pieces, showing off my dojox.gfx animation skills in the process.

Since I had been late in finishing that part of the system, the fairly complex workflow needed do ask for a challenge, receive a unique (not the same one again, natch!:) challenge, send back a response, send it to one of the judges, wait for approval and finally get a success and automatic move to next node.. only almost worked.

After trying it for a couple of hours, we decided to go with the original plan and just print the challenges, which in the end led to much more interaction between attendees and judges. Everyone could still log on to the system and get team movement, map changes, et.c. in beautiful websocket realtime, but the workflow needs some rehauling.

Probably I'll set up a free online version of the system for smoke-testing when I have rewritten that part of the back-end.
All-in-all everyone was very elated and had a great time. I think that my plan with small, specific programming challenges that could be done on 15-60 minutes was indeed a good one, and let to a good flow and friendly competition between teams.

The Spotify judges were very professional and managed to adapt to changing game conditions without dropping a beat.

Having Rikard, André and Jonas from Spotify there as HR groovemasters helped a lot, playlisting the venue (Debaser Medis) to a good programming mood as well as making sure everything moved smoothly. Big thanks!!

The next planned /dev/null will happen in Amsterdam in the September/October timeframe, sponsor secret for the time being :)

Would you or your company want to be a sponsor for an Escape for /dev/null event? Contact me at psvensson@gmail.com and we'll work something out. The system itself will be available for licensing/whiteboxing when done, before summer.

If you are a recruiting organization that would like to offer /dev/null to your customers, there's a franchising option too :)


I leave you with an action picture of team C07, the jaw-dropping trailblazer winners of the game this time. Me and the Spotify judges threw everything we had at them, but they just barged through challenge after challenge like they were thin paper (or in the end, fairly chunky carton, but still..). Kudos!





Monday, January 2, 2012

Simple Scaffolding for a Dojo Ajax Toolkit application

I've been writing some simple exercises for workshop-style (or solo) training for Dojo Ajax Toolkit, focusing on the strength of Dojo - writing OO-JavaScript applications.



The first exercises is about using Dojo's (classical) require and simple namespacing to create simple widgets, but I've gotten repeated requests for a complete application skeleton - something I understand the need for and which would have helped me quite a bit some years ago as well.

Luckily now there are some.  The guys at Sitepen have written some excellent articles (with much better layout :) here and here which you should definitely check out as well.

My aim here, though is to give you a scaffolding which contains all the structure you need to get started. I've included Dojo 1.7.1  in the latest exercise, which might seems staggeringly stupid, but the reason is that this part of the exercises will go into building and testing, where you actually have to have a downloaded copy.

The exercises (definitely a work in progress) can be found here; https://github.com/psvensson/Dojo-Ajax-Toolkit-Free-Training and here is the Description file of today's app scaffolding sample.

-----


This exercise show how to make a simple scaffolding of an application in Dojo.
It is not an exercise per se, but shows both a simple CSS layout and how to split up separate parts of the app into subclasses.

This time we are referencing a local copy of Dojo 1.7.1, since subsequent exercises will use both the DOH testing system and the build system, both which are used from the Dojo 'util' folder
and relies on parts of Dojo to run.

I'm still using the old (pre-AMD) style of declaring classes, so Dojo will warn about some things.

The goal is to show in a series of exercises how to create a simple single-page app with Dojo which is:

 1. Object-oriented - splitting functionality across a small class-hierarchy and through a logical namespace
 2. Using a sensible box model CSS layout
 3. Turn-key, so you can just copy the structure and get going modifying stuff as you please.

The page sample.html require's just one class, which is the widget mycustom.MainApp

In the MainApp class, a template is declared which defines the uppermost layout of the application;



<div class="mycustom_box">
<div class="mycustom_top">
<div class="mycustom_left"  dojoType="mycustom.navigator.ui.MenuBar"></div>
<div class="mycustom_right" dojoType="mycustom.common.ui.LoginWidget"></div>
</div>
<div class="mycustom_center">
<div dojoType="mycustom.navigator.ui.ViewPort"></div>
</div>
<div class="mycustom_bottom">
Bottom area
</div>
</div>


The application has three visual parts; A top part which contain a menu widget and a login/out widget, a central part which contains a viewport which can switch between different views, and a bottom part which contain information and links.

Since these different parts are defined in their separate classes, with their separate template files, you get an automatic modularization that makes it less likely that different programmers
step on each others toes when working together (or just one making a 10K lines long file...)

This is a very, very simple scaffolding example which does nothing at all, but is a minimalistic proof of concept of how to start your own non-trivial Dojo application.

The namespace is divided into the main parts 'common' - for classes that can be reused and are hopefully generic, and 'navigator' - for classes that are specifically implementing the logic of this application.

I have called it 'navigator' because Internets. I have meant it to be a small app that let you navigate some space of stuff.

Saturday, September 24, 2011

How to build Large Web Applications, part I





I've been busy the last two years building fairly intricate web apps for my customers and while it's a fun job it's also by necessity not public in the same way an open-source project is. The only comments I get and discussion I'm involved in are generally from my customers, so it's a bit of a closed loop.

When I met Paul Irish in May this year in San Francisco he asked me,' But what do you actually do?', which was a fair question but took me by surprise. I'm mostly known for .. being that Swedish guy. With some luck people know I prefer Dojo as well, but I guess that's about it.

So what do I do? I build web apps as an independent consultant. Sure, I arrange conferences and user group meetings too, but that's where my beer comes from, so to speak.

This series of posts is both written to share and discuss what I feel are best practices around building large web apps, from a developer perspective, but also to let people know what I do. Possibly with the secretly evil intent of getting new customers if anything I write seems to be useful :)



Let's begin with defining what a large web app is.

A large web app (according to me, but please challenge and/or add to the list of items);


  1. Have composite views (showing both a static status area and a changing subview of items and lists, for example)
  2. Have widgets that are variants of each other.
  3. Have widgets that need to show up in dynamic configurations (e.g. a list of n, or each a always have a b except on Saturdays, ..)
  4. Initializes communication with the server or service and caches some or all information.
  5. Have widgets that need to change states, remember states and react to state changes in other widgets.


This list could go on and on, probably, but these are the most important things off the top of my head.
One of my customers had an existing, successful product that was built in .Net C#. It was a client-server system where the client had the following features;


  • Personal view of things going on, of various sorts.
  • List of personal things, arranged per time period in a tree structure, which showed a grid with the selected things.
  • Library of things of other people, arranged in a tree by both time period, user names and project names.
  • *very* complex search view where list of search queries could be build up dynamically and combined like date, project names but also other domain-specific (and visual) properties.
  • A thing editor which let the user compose a thing that was composed of various parts which could be dragged from a tab to the left and then changed according to their type and rearranged. There were parts like annotatable image, rich text, project reference, and so on.
  • Some of the parts needed access to the system clipboard for reading and writing, and some parts needed to start with and communicate with Excel. Several parts needed file access.
  • Lots of other, minor stuff.

And now, two years later, the Dojo/HTML5 version of the client have about 80% of the functionality of the old client (and some that it didn't) being sold to clients and everything. It's been quite a ride!

I realize that I both want to cover the story of the programs creation and 'how to make large web apps' at the same time. It probably is a bad idea, but let's anyway.

First of all, before digging into specific implementation I would like to talk about bare necessities. Stuff you just can't do without, stuff that if you are indeed left without it you will have to reinvent, poorly, and too late and botch things up completely. Yes, I have, and probably you too. But I didn't on this project(s) :)




Anyhoo, If we take the first list of things that define a large web app, the items leads to certain demands on your tooling and libraries of choice. First of all you need to have a clean widget abstraction to work with, one that clearly modularize your code and your markup. It also help tremendously if you have a widget lifecycle metaphor, which is handled for you and that you can plug in to when and if you need to.


Widget Abstraction



The widget abstraction should, at minimum do the following (lots of lists, sorry);


  1. Separate code and markup, so you have a separate file or string for the markup of the widget
  2. Make it possible to create widgets in classes that derive from each other, so you can have one grid baseclass, then a librarygrid that inherits from the basegrid, et.c.
  3. Completely hide id allocation to elements and sub-widgets. By this I mean that the abstraction need to let you use symbolic names inside the markup (
    ) that are then used inside the widget class in lieu of id lookups.
  4. Use markup replacement, so that parts of the markup is replaced with data in the widget class (
    ${foo}
    will be replaced with this.foo in the widget before the widget is placed in the DOM)
  5. Have a lifecycle so that when you create a widget, the widget "subsystem" / superclasses will call a number of functions on it that corresponds to the different event like a) init, b) before markup creation, c) after markup creation, d) before widget inserted into the DOM, et.c.


Dojo does all of this (as does several if it's peers (JavascriptMVC, Sproutcore, ExtJS, et.c.), but since the 'everything in a  box' approach is a conceptual hard-sell, people generally want to use smaller and separate libraries that does just one thing, but well.

A good, but a little bit dated list of a couple of markup libraries can be found here. But markup libraries (like Mustache.js) only solves one of the problems.



Dojo

I'm going to cover a bit how Dojo works here, but please let me know in the comments if you know about stand-alone libraries for these functions. i would think that some are probably part of a larger library's class-system, but still.

When I create a widget using Dojo, I create two files. One is the JavaScript class (obv) whic inherits from another custom widget or directly from dijit._Widget (widget subsystem) and dijit._Templated (markup replacement and symbolic element/subwidget naming). It could look like this;

In the directory "my/custom" the file "widget.js";

dojo.provide("my.custom.widget");
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.declare(""my.custom.widget", [dijit._Widget, dijit._Templated],
{
    templatePath: dojo.cache("my.custom", "widget.html"),
    username: "nisse",
    postCreate: function()    
  {       
    dojo.connect(this.mybutton, this, function(e)
    {
                       console.log("Someone pressed me button, eh?");        
              }    
            }
           });


The file "widget.html";



< div>
     < button dojoAttachPoint="mybutton" >${username}< button >
<div / >

The 'postCreate' function on a widget is called (if present) just before the widget is placed in the DOM, but after all markup replacement have been done. We now have markup that contains a div with a button in it, and the content of the button reads 'nisse', since that was what the class variable 'username' contained.

To use the widget you just have the following things in you code;

dojo.require("my.custom.widget");
...
var foo = new my.custom.widget();
// Not mentioning argument passing or automatic placement in page stuff. it's just a widget in the wind right now


There a re lots of other things you can do, like automatic event wiring, but I hope this small example is just enough to make you think 'Hmm.. that could actually be kind of useful'.

I am not really touching on the namespacing either, which is a simple things that have had ridiculous positive effects on the development speed and stability. We'll get to that later.

What the widget will look like in the actual page is something like this;

< div>
    <button id="mycustomwidget_0_mybutton">nisse</ button >
<div/ > 

What's actually in the id is not important, the important thing is that the id is never visible to you (unless you really want to, but you don't. Why would you? The only thing you need is to get a reference to the node in question (in this case, to attach an event handler to it).

Also, what may be less apparent, is that when you customer want another widget just like it beside the first, you don't have to worry about widget id lookup code, you know that you abstraction will handle those details and just create a new one and smack it up - no problem.

There are tons of more things I'd like to fit in here, but I have to clean the house while parts of the family is playing Deus Ex (the original) and others are off galivanting with horses.  Oh well..

Oh, right. I'll be doing a series of free, half-day Dojo-training events at Valtech in Sweden beginning the 13/10 2011. I'll post here (and on twitter etc) if you live nearby and want to learn the basics of creating custom Dojo widgets.

See you soon!


Saturday, April 9, 2011

Bad, hairy, dangerous and irresponsible node+now+couch example

What I feel is lacking many times when I want to learn a new piece of technology is smallest possible complete examples. I find many time how to interact with a new fancy database, or maybe how to communicate between client and server in a simpler, cooler way.

Very seldom do I find examples that do everything I need. What I want, ideally, when toying with a new piece of tech is the following;

1. Full instructions on how to set up any requirements, or at least pointers to good sources.
2. Example of client code, or at least how to get a basic web page up through or in parallel to this new something.
3. Example of how to call the service from whatever client should be used.
4. Example of how to take care of the client requests send on the server-side
5. Example on how to persist information and get it back again, even if that is not really part of the new tech.

What I like to convey, I think,  is that there is need for examples that give a newbie a fully working service for all examples, since even a very simple assumption can be to hard to grok if you are new to a certain scene.

In general I'd think it is better to have working, fully stand-alone examples that one does not understand one bit, than to have an example that is a partial service that is easy to understand. The newbie is a coder after all, and as long he or she have a working example that can be thrown rocks at, eventually he or she will figure the stuff out.

As it happens I've just manages to create (what I hope is) such a thing. What I wanted was to use the new now.js  socket.io client->server and server->client communications proxy.  It's really sweet since it makes JSON-RPC calls really simple. it's like this;

1. Your web page loads the now.js script from your now-powered node.js serverside JavaScript server.
2. The server-script on the node side adds any property to the global 'everyone.now. object.
3. JavaScript in your page gets any property changes propagated to a proxy object called just 'now' on the client.
4. If the properties are functions, the client can call them, and the function call will be executed on th server. No setup code, no nothing. Just call the bloody function, thanks.
5. If the client (your webpage JS code) adds a function of its own the server can call that.
6. This is what you really, really want.

If the browser doesn't support socket.io, a flash wrapper will be used, but all else remain equal.

But then again, you really would want to have some database running wouldn't you? On the server-side, I mean. Couchdb, for example.

What I just did was create a very small, not very clean example that uses now.js, couchdb and cradle on node and a small index.html file which load the now.js script and shows how to call functions exposed back and forth.

The code looks like this;

 var url = require("url");  
 var sys = require("sys");  
 var path = require("path");  
 var fs = require("fs");  
 var inspect = require('eyes').inspector({styles: {all: 'magenta'}});  
 var cradle = require("cradle");  
 cradle.setup({host: "127.0.0.1", port: 5984});  
 var conn = new(cradle.Connection)();  
 var db = conn.database("abc");  
 db.create();  
 var yourHttpServer = require('http').createServer(function(req, response)  
 {  
  /* Serve your static files */  
  var uri = url.parse(req.url).pathname;  
   var filename = path.join(process.cwd(), uri);  
   path.exists(filename, function(exists) {  
     if(!exists) {  
       response.writeHead(404, {"Content-Type": "text/plain"});  
       response.write("404 Not Found\n");  
       response.end();  
       return;  
     }  
     fs.readFile(filename, "binary", function(err, file) {  
       if(err) {  
         response.writeHead(500, {"Content-Type": "text/plain"});  
         response.write(err + "\n");  
         response.end();  
         return;  
       }  
       response.statusCode =200;  
       response.write(file, "binary");  
       response.end();  
     });  
     });  
 });  
 yourHttpServer.listen(8080);  
 var everyone = require("now").initialize(yourHttpServer);  
 everyone.now.msg = "Welcome to TEH wicked nowjs JSON-RPC";  
 everyone.now.foo = function(arg,cb)  
 {  
     sys.puts("Foo called.. arg and everyone.now is...\n");  
     inspect(arg);  
     inspect(everyone.now);  
     db.get('clientlog', function(err, doc)  
     {  
         inspect(doc);  
         if(!doc)  
         {  
             db.save('clientlog', {log: []});  
         }  
         else  
         {  
             var arr = doc.log || [];  
             inspect(arr);  
             arr.push({date: new Date(), message: arg});  
             doc.log = arr;  
             db.save('clientlog', doc,  
             function(err, res)  
             {  
             // Handle success  
                 sys.puts("Error after save was : "+err);  
             })  
         }  
     });  
     cb( "server callback yo!");  
 }  
 everyone.now.bar = function(arg)  
 {  
     sys.puts("now.js function 'bar' called from client. args are..");  
     inspect(arg);  
 }  



What you need to do to get this working is;


0. Don't have a lossy operating system.
1. Install couchdb and create a database named 'abc'
2. git clone node.js + npm;

git clone https://github.com/ry/node.git
./configure and make install first node, then npm

3. npm install cradle (couchdb helper library)
4. npm install now (that thing I just talked about, sheesh)
5. npm install eyes (logging/inspect library)
6. Unzip the nowtest example zipfile somwhere and do 'node nowtest.js'


Ta-daa! :)

Or possibly not, since I just slammed this together. It's bound to have ugly, warty, beer-guzzling bugs. Please tell me about them so I can update the code and links. Thx!