<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>danwebb.net - Rails</title>
  <id>tag:danwebb.net,2011:mephisto/rails</id>
  <generator version="0.7.3" uri="http://mephistoblog.com">Mephisto Noh-Varr</generator>
  <link href="http://danwebb.net/feed/rails/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://danwebb.net/rails" rel="alternate" type="text/html"/>
  <updated>2011-02-10T05:53:35Z</updated>
  <entry xml:base="http://danwebb.net">
    <author>
      <name>dan</name>
    </author>
    <id>tag:danwebb.net,2011-02-10:7578</id>
    <published>2011-02-10T05:51:00Z</published>
    <updated>2011-02-10T05:53:35Z</updated>
    <category term="JavaScript"/>
    <category term="Rails"/>
    <category term="design"/>
    <category term="javascript"/>
    <category term="metaprogramming"/>
    <category term="programming"/>
    <link href="http://danwebb.net/2011/2/10/writing-a-new-library-sketch-it-out-first" rel="alternate" type="text/html"/>
    <title>Writing a new library? Sketch it out first</title>
<content type="html">
            &lt;p&gt;So you&#8217;re embarking on writing a new library. You might dive right in to the code and work straight on solving the problem or you might take a more considered approach and start thinking about how to model the problem, what classes and methods you need to create, how they interact and so on.  However, rather than doing that why not start with sketching out not how the library works but how you would like it to be used.  I think you&#8217;ll see pretty positive results if you try it.&lt;/p&gt;


	&lt;p&gt;Usability isn&#8217;t just for designers.  If you want your co-workers or other developers to use and be productive with this code your creating its got to be as simple and fun to use as your user interfaces.  Your library&#8217;s &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; &lt;em&gt;is&lt;/em&gt; a user interface.  History has shown that libraries and open source projects that put their &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; design up front are far more successful than their competitors.  Take jQuery for instance, you can bet that when &lt;a href=&quot;http://ejohn.org&quot;&gt;John&lt;/a&gt; sat down to create jQuery he wasn&#8217;t thinking &#8220;How do I animate &lt;span class=&quot;caps&quot;&gt;CSS&lt;/span&gt; style?&#8221; or &#8220;How do I create and event system?&#8221; his main concern was how he wanted jQuery to be used.  At least initially, the internals of jQuery were a mish mash of various libraries that came before it.  What actually powered the explose growth of jQuery was the revolutionary &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; concepts it introduced: Method chaining, Selector-focussed &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;, simple plug in interface and so on.  Other success stories like Ruby on Rails shared a similar focus on &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; design.&lt;/p&gt;


	&lt;p&gt;So, how do you write your code in such a way that it will make programmers happy and propell you into internet stardom? When you start out writing a new library or feature, start with a sketch.  Cast aside any ideas that you might have already have about the implementation details and try to also cast aside any technical constraints and just start writing how you&#8217;d like your code to be used.  Let&#8217;s take a &lt;span class=&quot;caps&quot;&gt;DOM&lt;/span&gt; builder, for example.  Mashing strings (or indeed using the terribly designed &lt;span class=&quot;caps&quot;&gt;W3C DOM API&lt;/span&gt;) is no fun in JavaScript.  If you were taking an implementation first approach you might start with an &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt;-style data structure describing your &lt;span class=&quot;caps&quot;&gt;DOM&lt;/span&gt; fragment or maybe even consider a set of objects that map to the various types of elements and this may well be how you implement it under the hood but put that aside for now. How would your code look when using the library?  Here&#8217;s my first pass:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;var fragment = build(
  div({ id: 'contact' },
    ul(
      li('Email: whatever@thing.com'),
      li('Twitter: ', a({ href: 'http://twitter.com/danwrong' }, '@danwrong')) 
    ) 
  )
);&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Come up with the simplest, most aesthetically pleasing &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; you can and keep itterating on it until you&#8217;ve weeded out all the complexity you can.  If certain arguments are optional or have a sensible defaults then make sure that the developer doesn&#8217;t have to worry about them unless they need to, is your library similar to any other library?  If it is maybe its worth adopting the conventions of that library so it acts in a way that other developers expect it to.  Developers dislike like reading documentation as much as your site&#8217;s users dislike read help pages.  Strive for an &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; so simple that you can describe it in a few sentences.&lt;/p&gt;


	&lt;p&gt;Once you are happy with your sketch start building it out. You might need a little meta programming magic to realise the UI you are going for and that&#8217;s fine but use with caution.  You need to weigh up whether the magic you are adding is going to make your code act in a way that is unpredictable to developers used to working with the language in question or if it will prevent developers from using their existing knowledge of the language to solve problems with your code.  If you smell badness then leave the magic behind. In our example above we need to do quite a bit of work with the function arguments in order to support variable amounts of child nodes and to allow optional attribute hashes. In this case I&#8217;d make the call that this doesn&#8217;t add any extra confusion to the code so I&#8217;m happy to go with that.&lt;/p&gt;


	&lt;p&gt;Also, at this point consider how the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; you are trying to design will impact real world pratical issues.  For instance, in the example above it I would need to create functions for all &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; tags on the global namespace.  Am I happy with my library a defining a global function called a()?  No. Time to scale back on that idea a little.&lt;/p&gt;


	&lt;p&gt;Finally, when it comes to the implementation ensure that the architecture is sound and don&#8217;t try to couple the under the hood implementation with the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; design to a degree that it&#8217;ll make the quality of the library suffer.  I often view the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; as a simple, pretty veneer over the top of a well crafted solution.  Don&#8217;t hide the raw internals, make them accessable alongside the simple &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;.  That way if the developer is on the beaten track they get a simple &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; but if they have specific needs they can delve right in and get stuff done.&lt;/p&gt;


	&lt;p&gt;So yeah, next time you write some code.  Think about sketching out the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; first rather than leaving it as an after thought.  Your colleagues will thank you.&lt;/p&gt;


	&lt;p&gt;I&#8217;d love to speak more about this at &lt;a href=&quot;http://2011.jsconf.us&quot;&gt;JSConf&lt;/a&gt;.  The competition is very hot but here&#8217;s &lt;a href=&quot;http://2011.jsconf.us/#/proposal/c7bf7fec8a0afceeabf584d143d16862&quot;&gt;my proposal&lt;/a&gt; if your interested. If it&#8217;s picked I&#8217;ll go in to detail on some great and poor examples of &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; design and also show off some nice techniques for bringing your &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; sketches to life.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://danwebb.net">
    <author>
      <name>dan</name>
    </author>
    <id>tag:danwebb.net,2010-05-26:3501</id>
    <published>2010-05-26T06:37:00Z</published>
    <updated>2010-05-26T13:25:10Z</updated>
    <category term="JavaScript"/>
    <category term="Projects"/>
    <category term="Rails"/>
    <category term="experiments"/>
    <category term="javascript"/>
    <category term="oembed"/>
    <category term="rails"/>
    <category term="twaudio"/>
    <link href="http://danwebb.net/2010/5/26/added-oembed-and-embeddable-player-to-twaud-io" rel="alternate" type="text/html"/>
    <title>Added OEmbed and Embeddable Player to twaud.io</title>
<content type="html">
            &lt;p&gt;I&#8217;ve just added &lt;a href=&quot;http://oembed.org&quot;&gt;OEmbed&lt;/a&gt; to &lt;a href=&quot;http://twaud.io&quot;&gt;twaud.io&lt;/a&gt; for fun and profit.  I&#8217;d not really looked into it until &lt;a href=&quot;http://dustindiaz.com&quot;&gt;Dustin&lt;/a&gt; and &lt;a href=&quot;http://twitter.com/dsa&quot;&gt;Russ&lt;/a&gt; pointed out and I really like the idea although it seems a bit under done at the moment (You can only have &#8216;image&#8217;, &#8216;video&#8217; or &#8216;rich&#8217; as media types.  What about audio?).  I&#8217;ve been meaning to implement an embeddable player for twaud.io for a long time so I decided to add them in.&lt;/p&gt;


	&lt;p&gt;The OEmbed endpoint is:&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;http://twaud.io/oembed.{format}&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;It supports &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt;, XML and &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt;-P (if you provide a callback parameter to a json request).  For example:&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;http://twaud.io/oembed.json?url=http%3A%2F%2Ftwaud.io%2FYf&#38;callback=myCallback&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;Returns this:&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;myCallback({
  &quot;height&quot;:&quot;65&quot;,
  &quot;provider_url&quot;:&quot;http://twaud.io&quot;,
  &quot;title&quot;:&quot;Little mix of all the dubstep tunes I've been listening to lately: WRONG BEAT&quot;,
  &quot;type&quot;:&quot;rich&quot;,
  &quot;html&quot;:&quot;&amp;lt;iframe allowtransparency='true' frameborder='0' scrolling='no' src='http://twaud.io/embed/Yf' style='width: 395px;  height: 65px; border: none;'&amp;gt;&amp;lt;/iframe&amp;gt;\n&quot;,
  &quot;audio_type&quot;:&quot;audio/mpeg&quot;,
  &quot;audio_url&quot;:&quot;http://twaud.io/audio/Yf&quot;,
  &quot;width&quot;:&quot;395&quot;,
  &quot;author_name&quot;:&quot;danwrong&quot;,
  &quot;version&quot;:&quot;1.0&quot;,
  &quot;author_url&quot;:&quot;http://twitter.com/danwrong&quot;,
  &quot;provider_name&quot;:&quot;twaud.io&quot; 
});&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;The &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; property contains a snippet of &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; that renders the player:&lt;/p&gt;


&lt;p&gt;&amp;lt;iframe src=&quot;http://twaud.io/embed/Yf&quot;&gt;&amp;lt;/iframe&gt;&lt;/p&gt;

	&lt;p&gt;All very beta at the moment but give it a try.  Also, check the short dubstep mix I did a while back.  Will post a longer one soon.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://danwebb.net">
    <author>
      <name>dan</name>
    </author>
    <id>tag:danwebb.net,2009-05-20:3360</id>
    <published>2009-05-20T13:29:00Z</published>
    <updated>2009-05-20T14:04:45Z</updated>
    <category term="Projects"/>
    <category term="Rails"/>
    <category term="massive robot"/>
    <category term="oauth"/>
    <category term="rails"/>
    <category term="twaudio"/>
    <category term="twitter"/>
    <link href="http://danwebb.net/2009/5/20/massive-robot-launches-twaud-io" rel="alternate" type="text/html"/>
    <title>Massive Robot launches twaud.io</title>
<content type="html">
            &lt;p&gt;Well, it&#8217;s been a bloody long while again since I&#8217;ve posted here and I suppose you&#8217;ve all unsubscribed me now.  To be honest, I wouldn&#8217;t blame you.&lt;/p&gt;


	&lt;p&gt;However, silence here does not mean that I&#8217;ve been sitting on my arse doing nothing.  In fact, the reality is very much to the contrary.  Loads of stuff has been going on but there are two new pieces of news.  Firstly, I&#8217;ve renamed and rebranded my company.  We are now &lt;a href=&quot;http://www.massiverobot.co.uk&quot;&gt;Massive Robot&lt;/a&gt; and we are available for consultancy and development work so if you have anything in mind then please contact us.  &lt;a href=&quot;http://josephmckernan.co.uk&quot;&gt;Joe&lt;/a&gt; has done the branding and it&#8217;s something I&#8217;m really pleased with.&lt;/p&gt;


	&lt;p&gt;Check the business cards&#8230;&lt;/p&gt;


	&lt;p&gt;&lt;img title=&quot;Massive Robot Business Cards&quot; src=&quot;http://www.danwebb.net/assets/2009/5/20/6640430.jpg&quot; alt=&quot;Massive Robot Business Cards&quot; /&gt;&lt;/p&gt;


&lt;p&gt;Along with those is a &lt;a href=&quot;http://massiverobot.co.uk&quot;&gt;new site&lt;/a&gt; and a T-shirt.  The final and most important Massive Robot branding will be the kicks.  I&#8217;m working on those at the moment.&lt;/p&gt;

	&lt;p&gt;&lt;img title=&quot;twaud.io&quot; src=&quot;http://twaud.io/images/logo.png?1242825321&quot; alt=&quot;twaud.io&quot; /&gt;&lt;/p&gt;


&lt;p&gt;This week launched &lt;a href=&quot;http://twaud.io&quot;&gt;twaud.io&lt;/a&gt;, Massive Robot&#8217;s new service.  The idea is simple &#8211; it&#8217;s like &lt;a href=&quot;http://twitpic.com&quot;&gt;twitpic&lt;/a&gt; but for audio.  Go to the site or use the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; to upload your audio and you get a page with a short &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; and a player for your followers to listen to it.  This is just the start and we are working on a whole load of new features for it so follow &lt;a href=&quot;http://twitter.com/twaudio&quot;&gt;@twaudio&lt;/a&gt; to keep up to date.&lt;/p&gt;

	&lt;p&gt;The build of twaud.io has been an interesting and fun experience.  I was able to use Twitter&#8217;s new OAuth based login process via &lt;a href=&quot;http://github.com/mbleigh/twitter-auth/tree/master&quot;&gt;twitter_auth&lt;/a&gt; which I&#8217;d recommend wholeheartedly for as a foundation for Twitter applications, although I have hacked to allow for both OAuth (for the site) and username/password based (for the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;) authentication where normally you must choose one or the other.  It also uses S3&#8217;s direct uploading facility via &lt;a href=&quot;http://swfupload.org&quot;&gt;SWFUpload&lt;/a&gt; which was not easy to get going but has provided a really scalable system as the application stays completely out of the loop of the bulky upload process. I love the direction web development is moving in at the moment.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://danwebb.net">
    <author>
      <name>dan</name>
    </author>
    <id>tag:danwebb.net,2008-06-23:3342</id>
    <published>2008-06-23T22:56:00Z</published>
    <updated>2008-06-24T00:24:12Z</updated>
    <category term="Events"/>
    <category term="JavaScript"/>
    <category term="Low Pro"/>
    <category term="Misc"/>
    <category term="Rails"/>
    <category term="boring"/>
    <category term="bullshit"/>
    <category term="chitchat"/>
    <category term="donotread"/>
    <category term="events"/>
    <category term="general"/>
    <category term="lowpro"/>
    <category term="prattle"/>
    <category term="rack"/>
    <category term="rails"/>
    <category term="reproduction"/>
    <category term="speaking"/>
    <category term="work"/>
    <link href="http://danwebb.net/2008/6/23/it-s-been-a-long-time" rel="alternate" type="text/html"/>
    <title>It's Been A Long Time...</title>
<content type="html">
            &lt;p&gt;But I&#8217;ve not just been sitting on my arse playing &lt;span class=&quot;caps&quot;&gt;GTA IV&lt;/span&gt;, oh no.  Well, not all the time anyway.  The reason I&#8217;ve not posted anything (or been particularly active on the web in general) is that I&#8217;ve been damn busy.  Most importantly, Catherine kindly gave birth to our first son, &lt;a href=&quot;http://flickr.com/photos/danwebb/2361976989/&quot;&gt;Max&lt;/a&gt;, back in March which has been quite a change and sapped a lot of my hacking time.  I have to say though, despite the horror stories that many veteran parents like to feed you, our experience has only been good.  In fact, not good, great.  I recommend this reproducing lark.&lt;/p&gt;


	&lt;p&gt;Secondly, I&#8217;ve been hacking away nearly full time on one of my favourite projects to date, &lt;a href=&quot;http://peoplesmusicstore.com&quot;&gt;Peoples Music Store&lt;/a&gt; with &lt;span class=&quot;caps&quot;&gt;LRUG&lt;/span&gt; stalwart and renowned anarchist, &lt;a href=&quot;http://abscond.org&quot;&gt;James &#8216;Bringing London To Its Very Knees&#8217; Darling&lt;/a&gt; which is maturing nicely under private beta as we speak.  Peoples Music Store is a great idea from some of the guys behind &lt;a href=&quot;http://bleep.com&quot;&gt;bleep.com&lt;/a&gt; whereby users can construct and customise their very own download store from the music they love then get free music themselves if people buy from their store.  It&#8217;s a great way to both promote and show off you&#8217;re own music taste or in depth genre knowledge and find new music from stores you trust while getting some free digital swag along the way.  I&#8217;m probably not explaining it well so just drop me a line if you want and invite and the site will explain itself.  Public launch is coming in a month or so.&lt;/p&gt;


	&lt;p&gt;Building Peoples Music Store has been a great learning experience.  We run the site on a cloud computing platform and from content ingestion to audio preview delivery to application servers to download packaging and delivery everything has been designed to scale horizontally &#8211; and I&#8217;m pretty proud of it.  Thin, Rack, Sphinx, God, Starling and a whole load more cool open source gear is all running in there. I really need to get to blogging some of what I&#8217;ve discovered about working with &lt;a href=&quot;http://rack.rubyforge.org/&quot;&gt;Rack&lt;/a&gt;.  It simply is the dog&#8217;s bollocks.&lt;/p&gt;


	&lt;p&gt;So, enough of the excuses.  What&#8217;s on the horizon?&lt;/p&gt;


	&lt;h3&gt;Speaking and Conferences&lt;/h3&gt;


	&lt;p&gt;I&#8217;ve taken some time of speaking and conferencing in general so as to spend lots of time with Catherine and Max but come September I&#8217;m restarting the conference trail.  Firstly, I&#8217;m doing a presentation and a tutorial (with &lt;a href=&quot;http://jlaine.net&quot;&gt;Jarkko Laine&lt;/a&gt;) at RailsConf Europe all about JavaScript related Rails stuff and I&#8217;m likely to have a slot at &lt;a href=&quot;http://vivabit.com/atmediaajax&quot;&gt;@media Ajax&lt;/a&gt; as well.  Also, I&#8217;ll be heading to &lt;a href=&quot;http://2008.dconstruct.org&quot;&gt;dConstruct&lt;/a&gt; as is the tradition.&lt;/p&gt;


	&lt;h3&gt;Hacking and Open Source Business&lt;/h3&gt;


	&lt;p&gt;Although I&#8217;ve not commited to Low Pro or Low Pro JQ for a good while now they are both very much alive.  I&#8217;ve simply not come across anything that I&#8217;ve felt the need to add for a while.  If you have any suggestions or patches do let me know.  I&#8217;ve actually got time to commit them at the moment.  Another little project that I&#8217;m hoping to get off the ground is called &lt;strong&gt;Evil&lt;/strong&gt; which is going to contain lots of Merb/Rack goodness.  The first by-product of which is the &lt;a href=&quot;http://github.com/danwrong/merb_openid&quot;&gt;merb_openid&lt;/a&gt; gem for consuming OpenID in Merb apps (it&#8217;s still not quite production ready though so don&#8217;t go using it just yet).  I&#8217;ll let you know what Evil actually does when (or if) I actually get something working.&lt;/p&gt;


	&lt;p&gt;So, that&#8217;s all for now.  Just a bit of a status report.  I promise I&#8217;ll get some useful content written that you actually care about very soon.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://danwebb.net">
    <author>
      <name>dan</name>
    </author>
    <id>tag:danwebb.net,2008-01-02:2869</id>
    <published>2008-01-02T12:35:00Z</published>
    <updated>2008-01-02T14:07:11Z</updated>
    <category term="Rails"/>
    <category term="argh"/>
    <category term="ruby"/>
    <category term="stupid"/>
    <link href="http://danwebb.net/2008/1/2/how-good-is-this" rel="alternate" type="text/html"/>
    <title>How Good Is This?</title>
<content type="html">
            &lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&amp;gt;&amp;gt; a = 79.99 * 100
=&amp;gt; 7999.0
&amp;gt;&amp;gt; a.floor
=&amp;gt; 7998
&amp;gt;&amp;gt; b = 7999.0
=&amp;gt; 7999.0
&amp;gt;&amp;gt; b.floor
=&amp;gt; 7999&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;I&#8217;ll tell you.  &lt;strong&gt;It&#8217;s not good.&lt;/strong&gt;  I hate floating point calculations.  Happy new year!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://danwebb.net">
    <author>
      <name>dan</name>
    </author>
    <id>tag:danwebb.net,2007-06-16:2064</id>
    <published>2007-06-16T15:19:00Z</published>
    <updated>2007-06-17T03:29:15Z</updated>
    <category term="JavaScript"/>
    <category term="Low Pro"/>
    <category term="Projects"/>
    <category term="Rails"/>
    <category term="javascript"/>
    <category term="lengthy"/>
    <category term="lowpro"/>
    <category term="plugins"/>
    <category term="ujs4rails"/>
    <link href="http://danwebb.net/2007/6/16/the-state-and-future-of-the-ujs-plugin" rel="alternate" type="text/html"/>
    <title>The State (And Future) Of The UJS Plugin</title>
<summary type="html">&lt;p&gt;Over the past few weeks loads of people have been asking me about what&#8217;s going on the &lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt; plugin.  It&#8217;s obviously fallen in to disrepair so people, understandably, have been concerned.  There has been a reason for this aside from the fact that I am a lazy barsteward (which of course I am, but that&#8217;s beside the point).  Here is a letter I&#8217;ve just written to the &lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt; mailing list that I&#8217;d thought I&#8217;d post here to try to get a little more feedback.  It&#8217;s a little bit long but bear with me&#8230;&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;Over the past few weeks loads of people have been asking me about what&#8217;s going on the &lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt; plugin.  It&#8217;s obviously fallen in to disrepair so people, understandably, have been concerned.  There has been a reason for this aside from the fact that I am a lazy barsteward (which of course I am, but that&#8217;s beside the point).  Here is a letter I&#8217;ve just written to the &lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt; mailing list that I&#8217;d thought I&#8217;d post here to try to get a little more feedback.  It&#8217;s a little bit long but bear with me&#8230;&lt;/p&gt;
&lt;p&gt;I&#8217;ve been chatting to Luke and users of &lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt; about what to do with it and still haven&#8217;t quiet decided hence the lack of news but below is a rundown of where we are at on the whole thing.  However, this is definitely personal opinion and doesn&#8217;t necessarily represent Luke&#8217;s opinion on the matter.&lt;/p&gt;


	&lt;p&gt;Essentially, the status is that, of late, I personally have not used &lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt; at all and have found a much better process by using Low Pro on its own without all the Ruby scaffolding of the &lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt; plugin.  Secondarily, after talking to lots of developers at RailsConf it seems that the &lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt; plugin has failed to truly achieve it&#8217;s main goal which is to get Rails developers to write JavaScript using progressive enhancement.  Many people seem to mainly use the plugin to get their JavaScript in to a separate file which is actually not even essential to progressive enhancement and I think this is a failing in the design of &lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt; itself.  To achieve progressive enhancement you really need to think of JavaScript as a separate layer on top of a working &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; application but &lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt; lets you get away with keeping behavior in your views and hence leads many developers to think in the same way as they did before but think they are unobtrusive because they don&#8217;t see any JavaScript in their &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; &#8211; which is obviously not what we wanted to achieve.  While many people can and do successfully use &lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt; for progressive enhancement even more seem not to &#8211; &lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt; has not been the &#8216;angel on your shoulder&#8217; that I originally wanted it to be.&lt;/p&gt;


	&lt;p&gt;On top of this, the method by which the generated JavaScript is kept in the session has many limitations which myself and Luke have been aware of from the start.  It&#8217;s not generally a good idea to keep this much information in the session (in fact, normally I never store more than a user ID if I can help it) and while acceptable for light to medium use it does have an upper limit depending on the type of session storage you are using.  Rails edge now uses cookies to store session info by default which have a very very low limit which will cripple &lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt; completely.  We have considered other alternatives such as some kind of file based storage but every time it just strikes me as too much scaffolding just to allow developers to put behavior in their view files which, as a said above, I&#8217;ve come to believe is a really bad idea anyway.&lt;/p&gt;


	&lt;p&gt;One of the things that I do personally like and something that has received the most positive feedback are the behavior helpers (the make_*) stuff which essentially encapsulate common tasks with sensible defaults in a very Rails like way.  It&#8217;s a real time saver and the conventions provided mean that the best path (such as using this.href for the Ajax url) is the easiest.  Recently, I&#8217;ve come to do this in my own projects via Low Pro and it&#8217;s behavior &#8216;classes&#8217; (although they need a better name!).  Now via Low Pro I can write stuff like:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;Event.addBehavior({
  '.product a.description' : Remote.Link({ update : 'product_description' }),
  '.product' : Draggable({ revert : true }),
  '#basket' : Droppable
});&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;I really like this and am slowly building up a library (which you can see if you look at the &lt;a href=&quot;http://svn.danwebb.net/external/lowpro/trunk/behaviors/&quot;&gt;Low Pro trunk&lt;/a&gt;) of common behaviors.  There&#8217;s a date picker, a drag/drop implementation and the remote stuff I&#8217;ve illustrated above.  I&#8217;m planning on writing autocompleters and in-place editors as behaviors as well.  But behaviors have proven really easy to write and I love them as a tool for building site specific components.  In fact, as I&#8217;ve worked with Low Pro it&#8217;s become apparent to me that behaviors are by far the killer feature which is interesting as they were just an experiment I hacked together one day without much thought.&lt;/p&gt;


	&lt;p&gt;So what to do?  Well, there&#8217;s two ways to go as far as I can see.  The first is to shut down development on &lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt; completely (or hand it over to another party if anyone is interested) and go on to promote the techniques of implementing progressive enhancement using Low Pro that I&#8217;ve found to be so successful recently.  This could possibly be via the UJS4Rails site or through my own site &#8211; I&#8217;m not sure which would be a better platform right now.&lt;/p&gt;


	&lt;p&gt;The other would be to re-think the &lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt; plugin totally and go for some kind of 2.0 release that would take a completely different tack.  However, all of the ideas for this I&#8217;ve thought of or heard so far don&#8217;t really compel me to write them.  I think to work on this myself I&#8217;d need to be sure that I&#8217;d want to use it and so far this is not the case but any ideas and feedback are very welcome so please do drop me a mail or feedback on this list.&lt;/p&gt;


	&lt;p&gt;Either way, we need to make fixes to the current plugin to make it work with Rails 1.2.3 which I&#8217;ve been working on recently but I&#8217;d love patches if you&#8217;ve already solved these issues yourself (which it appears many of you have).&lt;/p&gt;


	&lt;p&gt;So yes, that&#8217;s it. Let me know what you think, I&#8217;d appreciate any feedback you have.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://danwebb.net">
    <author>
      <name>dan</name>
    </author>
    <id>tag:danwebb.net,2007-05-21:1911</id>
    <published>2007-05-21T18:14:00Z</published>
    <updated>2007-05-23T15:20:00Z</updated>
    <category term="Events"/>
    <category term="JavaScript"/>
    <category term="Rails"/>
    <category term="events"/>
    <category term="presentation"/>
    <category term="rails"/>
    <category term="railsconf"/>
    <link href="http://danwebb.net/2007/5/21/railsconf-is-over-one-down-one-to-go" rel="alternate" type="text/html"/>
    <title>RailsConf Is Over: One Down, One To Go</title>
<summary type="html">&lt;p&gt;&lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;UPDATE&lt;/span&gt;&lt;/strong&gt;: The RailsConf version of the slides are &lt;a href=&quot;http://www.slideshare.net/danwrong/the-mysteries-of-javascriptfu-railsconf-ediition/2&quot;&gt;over at SlideShare&lt;/a&gt;.  The versions of the presentation I&#8217;ll be doing at @media San Fancisco and @media London will be considerably different but the kung-fu foolishness will remain intact.&lt;/p&gt;


	&lt;p&gt;RailsConf 2007 is over and I have to say it was considerably better than the previous year.  Rather than last year&#8217;s overwhelmingly self-congratulatory tone (&#8220;Aren&#8217;t we clever! We use Rails!&#8221; Accompanied by much clapping, standing ovations and general whooping) it was a much more down to business affair and although it was really big (1600 people) it was friendly.&lt;/p&gt;


	&lt;p&gt;So what was the big news this year?  Firstly, I got the feeling that everyone was bracing themselves for &#8220;the enterprise&#8221; with JRuby going strong and Sun looming over the proceedings.  It seems that everyone&#8217;s got a new Rails &lt;span class=&quot;caps&quot;&gt;IDE&lt;/span&gt; on the way out and the exhibition hall was full of people hawking their wares and pretty much everyone I met was a full time Rails professional.  I suppose the up side of this injection of big money into Rails is the free beer but aside from that I think the transition is going to be uneasy.  Java and &lt;span class=&quot;caps&quot;&gt;J2EE&lt;/span&gt; are great for getting huge amounts of programmers to write huge things because inevitably some of those programmers are going to be shit and Java and &lt;span class=&quot;caps&quot;&gt;J2EE&lt;/span&gt; provide a strict framework by which you can&#8217;t go too wrong.  However, Ruby on Rails is great for getting small amounts of really good programmers to churn out software quickly but doesn&#8217;t provide a rigid safety net which means a bad (or even not really good programmer) can basically bring an application to it&#8217;s knees.  In fact, I&#8217;ve seen some terrible code in Rails apps recently&#8230;stuff that would make &lt;a href=&quot;http://therailsway.com&quot;&gt;Koz and Jamis&lt;/a&gt; turn white.  Rails dev shops really need to watch for this.  Quality control, people!&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;&lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;UPDATE&lt;/span&gt;&lt;/strong&gt;: The RailsConf version of the slides are &lt;a href=&quot;http://www.slideshare.net/danwrong/the-mysteries-of-javascriptfu-railsconf-ediition/2&quot;&gt;over at SlideShare&lt;/a&gt;.  The versions of the presentation I&#8217;ll be doing at @media San Fancisco and @media London will be considerably different but the kung-fu foolishness will remain intact.&lt;/p&gt;


	&lt;p&gt;RailsConf 2007 is over and I have to say it was considerably better than the previous year.  Rather than last year&#8217;s overwhelmingly self-congratulatory tone (&#8220;Aren&#8217;t we clever! We use Rails!&#8221; Accompanied by much clapping, standing ovations and general whooping) it was a much more down to business affair and although it was really big (1600 people) it was friendly.&lt;/p&gt;


	&lt;p&gt;So what was the big news this year?  Firstly, I got the feeling that everyone was bracing themselves for &#8220;the enterprise&#8221; with JRuby going strong and Sun looming over the proceedings.  It seems that everyone&#8217;s got a new Rails &lt;span class=&quot;caps&quot;&gt;IDE&lt;/span&gt; on the way out and the exhibition hall was full of people hawking their wares and pretty much everyone I met was a full time Rails professional.  I suppose the up side of this injection of big money into Rails is the free beer but aside from that I think the transition is going to be uneasy.  Java and &lt;span class=&quot;caps&quot;&gt;J2EE&lt;/span&gt; are great for getting huge amounts of programmers to write huge things because inevitably some of those programmers are going to be shit and Java and &lt;span class=&quot;caps&quot;&gt;J2EE&lt;/span&gt; provide a strict framework by which you can&#8217;t go too wrong.  However, Ruby on Rails is great for getting small amounts of really good programmers to churn out software quickly but doesn&#8217;t provide a rigid safety net which means a bad (or even not really good programmer) can basically bring an application to it&#8217;s knees.  In fact, I&#8217;ve seen some terrible code in Rails apps recently&#8230;stuff that would make &lt;a href=&quot;http://therailsway.com&quot;&gt;Koz and Jamis&lt;/a&gt; turn white.  Rails dev shops really need to watch for this.  Quality control, people!&lt;/p&gt;
&lt;p&gt;Secondly, there was lots of buzz about &lt;a href=&quot;http://merb.rubyforge.org&quot;&gt;Merb&lt;/a&gt; which is really promising and in my opinion is starting to feel more like Rails 2.0 that Rails 2.0 is shaping up to be.  It&#8217;s got all the really useful stuff that I use day to day in Rails and none of the stuff I don&#8217;t use.  Better still all of the core features are really well implemented and feel really cruft-free (I read and understood the Merb source in about 2 hours).  This makes it fast as well.  &lt;a href=&quot;http://brainspl.at&quot;&gt;Ezra&lt;/a&gt; seems committed to keeping the core pretty lean and providing most extra functionality as gems rather than plugins which seems extremely sensible.  Plugins are simple are now suffering from a lot of the problems that gems have already solved (load order, dependencies, version control etc).&lt;/p&gt;


	&lt;p&gt;Finally, I was impressed with &lt;span class=&quot;caps&quot;&gt;DHH&lt;/span&gt;&#8217;s keynote. He must be under large amounts of pressure to deliver the next new big feature but regardless his keynote was low-key and considered.  There&#8217;s no big stuff on the way but what is coming is consolidating the core ideas of Rails, providing more sensible defaults, more support for &lt;span class=&quot;caps&quot;&gt;REST&lt;/span&gt; and it sounds like some of the JavaScript helpers are being pulled to plugins (or at least some of them)....nice one!&lt;/p&gt;


	&lt;p&gt;On the social side it was great.  Portland is a cool place and of course we had &lt;a href=&quot;http://robbyonrails.com&quot;&gt;Robby&lt;/a&gt; and the &lt;a href=&quot;http://planetargon.com&quot;&gt;Planet Argon&lt;/a&gt; crew to show us around and they did a great job.  I think I managed to meet up with nearly everyone I wanted to, the highlight being lunch with &lt;a href=&quot;http://sam.conio.net&quot;&gt;Sam&lt;/a&gt;, &lt;a href=&quot;http://mir.aculo.us/&quot;&gt;Thomas&lt;/a&gt; and Seth and some chat about Prototype which has got me pretty enthused about contributing again.  I even met the &lt;a href=&quot;http://railsenvy.com&quot;&gt;Rails Envy&lt;/a&gt; guy who is Ruby On Rails&#8230;rock on.  There was a &lt;a href=&quot;http://extra-action.com&quot;&gt;mad burlesque breakbeat marching band&lt;/a&gt; in the conference center at one point as well&#8230;.got to like that.  It was quite a Ruby moment when a guy in hot pants with a huge flag tried to dry hump Rich Kilmer.  Poor dude.&lt;/p&gt;


	&lt;p&gt;My presentation, The Mysteries Of JavaScript-Fu, went down reasonably well from what I could tell (apparently, I was not slagged off on &lt;span class=&quot;caps&quot;&gt;IRC&lt;/span&gt;&#8230;miracle!) and I&#8217;ll be putting the slides up as soon as I get a vaguely working wireless connection (I&#8217;ll update this post with the link).  But Dr James&#8217; presentation on plugins was a work of art.  While my presentation involved me talking in a fake kung-fu voice, &lt;a href=&quot;http://interblah.net&quot;&gt;James&lt;/a&gt; had a gothic horror thing going on.  Stupid voices from the Brits!&lt;/p&gt;


	&lt;p&gt;My only regret is that Zed Shaw won the &lt;a href=&quot;http://flickr.com/photos/johnnunemaker/507220981/&quot;&gt;Rails Pimp Cup&lt;/a&gt; ....that was main to be in my possession, damn it!&lt;/p&gt;


	&lt;p&gt;Now to get on a plane to San Francisco for @media America and a lot of footwear purchases.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://danwebb.net">
    <author>
      <name>dan</name>
    </author>
    <id>tag:danwebb.net,2007-05-15:1866</id>
    <published>2007-05-15T23:10:00Z</published>
    <updated>2007-05-15T23:46:18Z</updated>
    <category term="Events"/>
    <category term="JavaScript"/>
    <category term="Rails"/>
    <category term="atmedia"/>
    <category term="eventwax"/>
    <category term="javascript"/>
    <category term="lowpro"/>
    <category term="railsconf"/>
    <category term="travel"/>
    <link href="http://danwebb.net/2007/5/15/off-to-railsconf-and-media-america" rel="alternate" type="text/html"/>
    <title>Off To RailsConf and @media America</title>
<content type="html">
            &lt;p&gt;Just breaking radio silence briefly to say that I&#8217;m off to the states (again) to speak at &lt;a href=&quot;http://conferences.oreillynet.com/rails/&quot;&gt;RailsConf&lt;/a&gt; in Portland 17th-20th then on to &lt;a href=&quot;http://www.vivabit.com/atmedia2007/america/&quot;&gt;@media America&lt;/a&gt; in San Francisco for the 21st-28th.  I&#8217;m going to be doing presentations both called &#8216;The Mysteries Of JavaScript-Fu&#8217;, both with an old skool kung fu theme but quite different aside from that.  If you are around in either of these places or have any tips on good skate and sneaker stores then drop me a line&#8230;.I&#8217;m always up for a couple of cold ones or/and sneaker shopping missions.&lt;/p&gt;


	&lt;p&gt;When I get I&#8217;ll be working a load more on Low Pro and blogging more about it.  It&#8217;s developing quickly at the moment as Prototype picks up momentum and it&#8217;s getting some damn good features.  In the meantime, you could always check out the &lt;a href=&quot;http://svn.danwebb.net/external/lowpro/trunk&quot;&gt;trunk&lt;/a&gt; and see the new features that have already gone in.  Build the trunk release then try as a sneak preview:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;$('an_element').wrap('&amp;lt;strong&amp;gt;');&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Also, look out for a major new set of features for &lt;a href=&quot;http://eventwax.com&quot;&gt;Event Wax&lt;/a&gt; scheduled for release round about the time of @media London.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://danwebb.net">
    <author>
      <name>dan</name>
    </author>
    <id>tag:danwebb.net,2007-04-16:1669</id>
    <published>2007-04-16T10:08:00Z</published>
    <updated>2007-05-20T00:32:06Z</updated>
    <category term="JavaScript"/>
    <category term="Low Pro"/>
    <category term="Rails"/>
    <category term="javascript"/>
    <category term="lowpro"/>
    <link href="http://danwebb.net/2007/4/16/low-pro-0-4-released" rel="alternate" type="text/html"/>
    <title>Low Pro 0.4 Released</title>
<content type="html">
            &lt;p&gt;I&#8217;m back from India and just dropping a quick note to say that Low Pro 0.4 is out.  There are a few new features (which I&#8217;ll go into later) but essentially this is a bug fix / optimisation release and has many changes that help it work well with the &lt;a href=&quot;http://prototypejs.org/download&quot; title=&quot;1.5.1 RC2&quot;&gt;latest version of Prototype&lt;/a&gt;.  Most of this has been backing out parts of Low Pro that have been implemented or otherwise bettered in Prototype now which is great and I expect to see more of this happening soon.  There&#8217;s some good work going on with events at the moment and &lt;span class=&quot;caps&quot;&gt;DOM&lt;/span&gt; ready support is planned to go in soon.&lt;/p&gt;


	&lt;p&gt;One feature of Low Pro I have been using heavily myself are Behaviour classes.  Behaviour classes allow you to attach behaviour to elements in an object orientated way.  Each element gets it&#8217;s own instance of the behaviour which means that it can retain state through its lifetime without using expandos or creating nasty circular references that cause memory leaks (well, of course, you still can but it lessens the chances).  I intend to write a lot more about behaviour classes shortly but in the meantime have &lt;a href=&quot;http://svn.danwebb.net/external/lowpro/trunk/behaviours/draggable.js&quot;&gt;a peek at the Draggable behaviour in &lt;span class=&quot;caps&quot;&gt;SVN&lt;/span&gt;&lt;/a&gt; it turns out that it&#8217;s a really neat way to write components.&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://svn.danwebb.net/external/lowpro/tags/rel-0.4/dist/&quot;&gt;Download Low Pro 0.4&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://danwebb.net">
    <author>
      <name>dan</name>
    </author>
    <id>tag:danwebb.net,2007-02-27:1207</id>
    <published>2007-02-27T01:37:00Z</published>
    <updated>2007-03-02T10:22:24Z</updated>
    <category term="Rails"/>
    <category term="noshit"/>
    <category term="openid"/>
    <category term="rails"/>
    <category term="ruby"/>
    <category term="tutorial"/>
    <link href="http://danwebb.net/2007/2/27/the-no-shit-guide-to-supporting-openid-in-your-applications" rel="alternate" type="text/html"/>
    <title>The No Shit Guide To Supporting OpenID In Your Applications</title>
<summary type="html">&lt;p&gt;OpenID, with the superhuman effort of &lt;a href=&quot;http://simonwillison.net&quot;&gt;Mr Willison&lt;/a&gt; is taking the world by storm and I am amoungst the masses leaping onto the bandwagon.  Simon has done an &lt;a href=&quot;http://simonwillison.net/2006/Dec/19/openid&quot;&gt;excellent post&lt;/a&gt; and &lt;a href=&quot;http://simonwillison.net/2006/Dec/22/screencast/&quot;&gt;screencast&lt;/a&gt; detailing the whys and what-fors of OpenID so I thought I&#8217;d have a bash at applying the same no-bullshit approach to the other side of the coin, supporting (or as the official terminology puts it consuming) OpenID in your applications.  With this post I&#8217;m going to blast through the absolute essentials you need to get started so if you need more general background on OpenID check out Simon&#8217;s stuff first.  The examples, as you might except will be using Ruby on Rails but all of the concepts are applicable across platforms. So, without further ado, grab yourself a beer and we&#8217;ll begin&#8230;&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;OpenID, with the superhuman effort of &lt;a href=&quot;http://simonwillison.net&quot;&gt;Mr Willison&lt;/a&gt; is taking the world by storm and I am amoungst the masses leaping onto the bandwagon.  Simon has done an &lt;a href=&quot;http://simonwillison.net/2006/Dec/19/openid&quot;&gt;excellent post&lt;/a&gt; and &lt;a href=&quot;http://simonwillison.net/2006/Dec/22/screencast/&quot;&gt;screencast&lt;/a&gt; detailing the whys and what-fors of OpenID so I thought I&#8217;d have a bash at applying the same no-bullshit approach to the other side of the coin, supporting (or as the official terminology puts it consuming) OpenID in your applications.  With this post I&#8217;m going to blast through the absolute essentials you need to get started so if you need more general background on OpenID check out Simon&#8217;s stuff first.  The examples, as you might except will be using Ruby on Rails but all of the concepts are applicable across platforms. So, without further ado, grab yourself a beer and we&#8217;ll begin&#8230;&lt;/p&gt;
&lt;h3&gt;Overview of the authentication process&lt;/h3&gt;


	&lt;p&gt;When consuming OpenID what you are trying to do is ask the user for their OpenID (which is a &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;) then ascertain from their OpenID server that they actually own this OpenID.  Once you know that they own the OpenID you can then wack it in the session (and use it as a really lightweight means of identifying users between visits) or key it in with your own application specific account data if you need more power.  This article is going to take you up to and including verifying the user&#8217;s OpenID.  What you do with it is left to your imagination.&lt;/p&gt;


	&lt;p&gt;On a more granular level the verification process breaks down into these steps:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Get the user to give you their OpenID &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;.&lt;/li&gt;
		&lt;li&gt;&#8216;Begin&#8217; the verification process whereby your OpenID library of choice will work out the users OpenID server and, if successful, provide you with a redirect &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;.&lt;/li&gt;
		&lt;li&gt;Redirect the user to the given redirect &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;.  You specify a return &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; within this &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;.&lt;/li&gt;
		&lt;li&gt;The user goes to their OpenID server, logs in and authorises your site&#8217;s verification request and is then redirected back to your return &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;.&lt;/li&gt;
		&lt;li&gt;Your server &#8216;completes&#8217; the verification request and, if successful, confirms that this user owns this OpenID. The end.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;So that&#8217;s essentially it.  Some of the details of the transactions between your server, the user&#8217;s delegates and the OpenID are pretty complex but fortunately for us there are lots of good libraries for most platforms that mean you don&#8217;t need to bugger about with the crypotography and stuff.  Woo hoo.  For these examples we are going to use &lt;a href=&quot;http://www.openidenabled.com/openid/libraries/ruby/&quot;&gt;the ruby-openid gem&lt;/a&gt; but you can &lt;a href=&quot;http://www.openidenabled.com/openid/libraries/&quot;&gt;choose your own&lt;/a&gt;.  Also note that East Media have a &lt;a href=&quot;http://identity.eastmedia.com/identity/show/Consumer+Plugin&quot;&gt;OpenID Consumer plugin for Rails&lt;/a&gt; that wraps even more detail with some generators but it&#8217;s good to understand the concepts before you let something write your code for you.&lt;/p&gt;


	&lt;h3&gt;Get your library sorted&lt;/h3&gt;


	&lt;p&gt;That&#8217;s easy.  For us Rubyists its:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;$ sudo gem install ruby-openid -y&lt;/code&gt;&lt;/pre&gt;

	&lt;h3&gt;Create your OpenID consuming controller&lt;/h3&gt;


	&lt;p&gt;We are going to try to be as RESTy as possible here so we&#8217;ll create a singleton resource called openid.  In routes.rb:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;map.resource :openid, :member =&amp;gt; { :complete =&amp;gt; :get }&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Then we&#8217;ll set up a simple controller.  Firstly, we&#8217;ll need to require the ruby-openid gem here.  We are also going to need a method that gives us an OpenID consumer object which is the single most complex part of this whole thing (and it isn&#8217;t complex). First, here&#8217;s the skeleton:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;require_gem 'ruby-openid'

class OpenidController &amp;lt; ApplicationController

  def new
    # TODO: show a form requesting the user's OpenID
  end

  def create
    # TODO: begin the OpenID verification process
  end

  def complete
    # TODO: omplete the OpenID verification process
  end

  protected

    def openid_consumer
      @openid_consumer ||= OpenID::Consumer.new(session,      
        OpenID::FilesystemStore.new(&amp;quot;#{RAILS_ROOT}/tmp/openid&amp;quot;))
    end

end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The OpenID::Consumer constructor takes two arguments, the first one should be a hash like object that holds session data.  That&#8217;s always going to be session for Rails.  The second one takes a file store object which is used to store state information for the verification process.  There&#8217;s lots (including an ActiveRecord store) but for many apps the filesystem store is fine.&lt;/p&gt;


	&lt;h3&gt;Getting the user&#8217;s OpenID&lt;/h3&gt;


	&lt;p&gt;The new action just needs to show a simple form posting the OpenID to the create action:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&amp;lt;% form_tag openid_path do %&amp;gt;
  &amp;lt;%= text_field_tag 'openid_url' %&amp;gt; &amp;lt;%= submit_tag 'Login' %&amp;gt;
&amp;lt;% end %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Note that it&#8217;s convention to call the field openid_url so browsers will autocomplete nicely.  They also recommend that you embed the OpenID logo in the form field.  &lt;a href=&quot;http://openid.net/login-bg.gif&quot;&gt;Get the logo&lt;/a&gt; then try some &lt;span class=&quot;caps&quot;&gt;CSS&lt;/span&gt; like this:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;css&quot;&gt;#openid_url {
  background: url(/images/login-bg.gif) no-repeat #FFF 5px;
  padding-left: 25px;
}&lt;/code&gt;&lt;/pre&gt;

	&lt;h3&gt;Beginning the verification&lt;/h3&gt;


	&lt;p&gt;The create action is going to be responsible for kicking off the process:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def create
  openid_url = params[:openid_url]
  response = openid_consumer.begin openid_url

  if response.status == OpenID::SUCCESS
    redirect_url = response.redirect_url(home_url, complete_openid_url)
    redirect_to redirect_url
    return
  end

  flash[:error] = &amp;quot;Couldn't find an OpenID for that URL&amp;quot;
  render :action =&amp;gt; :new
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;We simply get the OpenID and pass it to the begin method of our consumer object to get a response.  We then handle the status of the response which can have a number of states.  For this super simple example we are just going to look for success but in a production app you&#8217;ll need to handle error states more usefully.&lt;/p&gt;


	&lt;p&gt;If the response was successful we call redirect_url passing the trust root and the return &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;.  The return &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; is simply our complete action.  The trust root is normally the homepage &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; of your site. We then redirect the user to the resulting &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; where the user logs in to their OpenID server, authorises your verification request and is (normally) redirected to return &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; you provided.&lt;/p&gt;


	&lt;h3&gt;Completing the verification&lt;/h3&gt;


	&lt;p&gt;When the user is redirected back to your application the server will append information about the response in the query string which the OpenID library will unpack:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def complete
  response = openid_consumer.complete params

  if response.status == OpenID::SUCCESS
    session[:openid] = response.identity_url
    # the user is now logged in with OpenID!
    redirect_to home_url
    return
  end

  flash[:error] = 'Could not log on with your OpenID'
  redirect_to new_openid_url
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;After passing the params hash containing all the info that the OpenID server sent us to the complete method we are given a response status to handle.  Again for production apps more states should be handled but here, if the complete was successful we have completed the process.  Here we just store the identity_url given in the session but at this point we could also do something like:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;session[:user] = User.find_by_openid_url(response.identity_url)&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Which would grab the users local account data based on the OpenID.  Easy as pasty.  However, there&#8217;s a few more bits and bobs you might want to know about.&lt;/p&gt;


	&lt;h3&gt;Simple Registration Extension (SReg)&lt;/h3&gt;


	&lt;p&gt;SReg is a basic means by which you can request additional information about the user from their OpenID server which you might normally use to prefill account details or other form fields.  The information you can request access to is &lt;a href=&quot;http://openid.net/specs/openid-simple-registration-extension-1_0.html#response_format&quot;&gt;in the spec&lt;/a&gt; but there&#8217;s not much there at the moment.  It&#8217;s still kind of useful.  To request this information you need to add parameters to the redirect &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; which is of course handled for you by your library.  Revisiting the create action, we just add a call to add_extension_arg:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def create
  openid_url = params[:openid_url]
  response = openid_consumer.begin openid_url

  if response.status == OpenID::SUCCESS
   response.add_extension_arg('sreg','required','email') # &amp;lt;== here...
   response.add_extension_arg('sreg','optional','nickname,gender') # &amp;lt;== ...and here
   redirect_url = response.redirect_url(home_url, complete_openid_url)
   redirect_to redirect_url
   return
  end

  flash[:error] = &amp;quot;Couldn't find an OpenID for that URL&amp;quot;
  render :action =&amp;gt; :new
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Then in the complete action, extract the returned information:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def complete
  response = openid_consumer.complete params

  if response.status == OpenID::SUCCESS
   session[:openid] = response.identity_url
   # the user is now logged in with OpenID!
   @registration_info = response.extension_response('sreg') # &amp;lt;= { 'name' =&amp;gt; 'Dan Webb', etc... }
   redirect_to home_url
   return
  end

  flash[:error] = 'Could not log on with your OpenID'
  redirect_to new_openid_url
end&lt;/code&gt;&lt;/pre&gt;

	&lt;h3&gt;Immediate mode&lt;/h3&gt;


	&lt;p&gt;Immediate mode allows you to attempt to verify the user without them leaving your site at all.  This is normally possible if, during the first time you attempt to verify a user, they choose to always allow you to verify them and offers a slightly more streamlined login experience.&lt;/p&gt;


	&lt;p&gt;To implement this we first pass an extra argument to redirect_url:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def create
  openid_url = params[:openid_url]
  response = openid_consumer.begin openid_url

  if response.status == OpenID::SUCCESS
   redirect_url = response.redirect_url(home_url, complete_openid_url, true) # &amp;lt;== here
   redirect_to redirect_url
   return
  end

  flash[:error] = &amp;quot;Couldn't find an OpenID for that URL&amp;quot;
  render :action =&amp;gt; :new
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Then ensure that our complete action handles the OpenID::SETUP_NEEDED status by redirecting them to the OpenID server&#8217;s setup page:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def complete
  response = openid_consumer.complete params

  case response.status
  when OpenID::SUCCESS
    session[:openid] = response.identity_url
    redirect_to home_url
    return
  when OpenID::SETUP_NEEDED
    redirect_to response.setup_url # &amp;lt;== here!
    return
  end

  flash[:error] = 'Could not log on with your OpenID'
  redirect_to new_openid_url
end&lt;/code&gt;&lt;/pre&gt;

	&lt;h3&gt;Fin&lt;/h3&gt;


	&lt;p&gt;So that&#8217;s it.  All you need to know to start getting OpenID going in your web applications.  You&#8217;ve got no excuse now.  In fact, neither have I&#8230;&lt;/p&gt;


	&lt;p&gt;Any corrections, questions or further wisdom are very welcome.  I&#8217;m no expert on OpenID, I&#8217;ve literally just picked all this up from reading &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; docs, specs and source code and thought it would be good to share.  let me know what you think.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://danwebb.net">
    <author>
      <name>dan</name>
    </author>
    <id>tag:danwebb.net,2007-01-31:1064</id>
    <published>2007-01-31T16:57:00Z</published>
    <updated>2007-02-03T12:05:45Z</updated>
    <category term="Events"/>
    <category term="Misc"/>
    <category term="Projects"/>
    <category term="Rails"/>
    <category term="barcamp"/>
    <category term="eventwax"/>
    <category term="fridaycities"/>
    <category term="mephisto"/>
    <category term="projects"/>
    <link href="http://danwebb.net/2007/1/31/coding-like-a-bitch-mephisto-plugins-upgraded-and-fridaycities-eventwax-beta-biznizz" rel="alternate" type="text/html"/>
    <title>Coding Like A Bitch: Mephisto Plugins Upgraded and Fridaycities/EventWax Beta Biznizz</title>
<content type="html">
            &lt;p&gt;Just a quick note to say that I&#8217;ve just upgraded to the newest version of Mephisto which has forced me to update my &lt;a href=&quot;http://svn.danwebb.net/external/rails/plugins/&quot;&gt;Mephisto plugins&lt;/a&gt; to work with the new updates to Liquid.  Sorry for being slack on that.  I&#8217;ve had a ton of email about it but hadn&#8217;t had the chance to fix these since my new venture into the freelance world has started.&lt;/p&gt;


	&lt;p&gt;In unrelated news, most of my coding effort has been going into a site called &lt;a href=&quot;http://london.fridaycities.com&quot;&gt;Fridaycities&lt;/a&gt; which is a cool site where Londoners ask questions and get insider info about all things London-ish.  It&#8217;s great to browse around&#8230;Apparently there&#8217;s an &lt;a href=&quot;http://london.fridaycities.com/knowledge/food-and-drink/conversations/138&quot;&gt;Elvis Chinese restaurant on Old Kent Rd&lt;/a&gt; and a &lt;a href=&quot;http://london.fridaycities.com/knowledge/places/conversations/692&quot;&gt;naked disco in Vauxhall&lt;/a&gt;.  Who&#8217;d a thunk it?  It&#8217;s still in very early stages at the moment but the FC people have got big plans and myself and &lt;a href=&quot;http://iamrice.org&quot;&gt;Mr Tanner&lt;/a&gt; are beavering away on it as we speak.  It&#8217;s invite only but you can check out the posts without registering so go have a squizz.&lt;/p&gt;


	&lt;p&gt;Finally, EventWax has been going great guns.  It&#8217;s great to see a load of events running on there including &lt;a href=&quot;http://www.vivabit.com/atmedia2007&quot;&gt;@media2007&lt;/a&gt; and &lt;a href=&quot;http://barcamp.org/BarCampLondon2&quot;&gt;BarCampLondon2&lt;/a&gt;.  We been collecting lots of feedback and slowly introducing features but there&#8217;s going to be some cool changes in the near future so keep an eye out there.&lt;/p&gt;


	&lt;p&gt;Finally, I&#8217;m stacking up a few patches for Prototype and Rails that I need to finish up.  Hopefully I&#8217;ll get chance to do that soon.  Writing patches for Rails is weird.  I tend to find myself spending 20 seconds on getting the patch done and 3 hours trying to bash tests together.  Does anyone else find writing tests for the Rails core a bit of a pain in the arse?&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://danwebb.net">
    <author>
      <name>dan</name>
    </author>
    <id>tag:danwebb.net,2006-11-24:307</id>
    <published>2006-11-24T16:32:00Z</published>
    <updated>2007-01-30T17:43:07Z</updated>
    <category term="JavaScript"/>
    <category term="Rails"/>
    <category term="hippy"/>
    <category term="javascript"/>
    <category term="liberal"/>
    <category term="minusr"/>
    <category term="nufters"/>
    <category term="plugins"/>
    <category term="rails"/>
    <category term="rjs"/>
    <link href="http://danwebb.net/2006/11/24/minusmor-released" rel="alternate" type="text/html"/>
    <title>MinusMOR Released!</title>
<content type="html">
            &lt;p&gt;Okay then you bunch of wusses.  Here&#8217;s your goddamn liberal, namby-pamby, let&#8217;s sit on the fence version of MinusR that doesn&#8217;t override anything and provides your JavaScript with embedded Ruby templates as the .ejs extension so it works alongside the normal .rjs templates.  Live and let live.  Let&#8217;s all hold hands and be nice to each other&#8230;.&lt;/p&gt;


	&lt;p&gt;Damn you, you hippies!&lt;/p&gt;


	&lt;p&gt;It&#8217;s in my &lt;a href=&quot;http://svn.danwebb.net/external/rails/plugins/minus_mor/trunk&quot;&gt;&lt;span class=&quot;caps&quot;&gt;SVN&lt;/span&gt; repos&lt;/a&gt; but you can still get at MinusR if you are feeling hardcore.  &lt;del&gt;I must admit that the whole thing does smell better than the original version.  It turns out that  changing the default behaviour of respond_to for different types has got easier since last time I looked as well.  Go core team! It was also easier to test which normally indicates a sweeter smell of code.&lt;/del&gt; In the end it required more monkey patching that MinusR to get it to work correctly.  It turns out that .rjs templates trigger a few hardcoded special cases to template handling and to get .ejs files to act the same required patching these hardcoded bits which is a shame.  It looked like it was going to be nice and clean.&lt;/p&gt;


	&lt;p&gt;Now I&#8217;ve gone out of the way to make this version especially for you people you &lt;span class=&quot;caps&quot;&gt;MUST&lt;/span&gt; use it.  I&#8217;ll be checking&#8230;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://danwebb.net">
    <author>
      <name>dan</name>
    </author>
    <id>tag:danwebb.net,2006-11-17:246</id>
    <published>2006-11-17T11:39:00Z</published>
    <updated>2007-01-30T17:42:42Z</updated>
    <category term="JavaScript"/>
    <category term="Rails"/>
    <link href="http://danwebb.net/2006/11/17/rjs-minus-r" rel="alternate" type="text/html"/>
    <title>RJS Minus R</title>
<content type="html">
            &lt;p&gt;&lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;UPDATE&lt;/span&gt;&lt;/strong&gt;: I&#8217;ve released a happy-clappy, touch feely version that doesn&#8217;t override .rjs and instead gives you the .ejs extension.  It&#8217;s called &lt;a href=&quot;/2006/11/24/minusmor-released&quot;&gt;MinusMOR&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;I like &lt;span class=&quot;caps&quot;&gt;RJS&lt;/span&gt; and it&#8217;s approach of sending executable JavaScript responses back to Ajax requests.  It seems ugly but it&#8217;s actually a life saver for making really complex UI updates easily and once I got to using it in real projects it definitely saved me vast amounts of time for anything more than trivial.  The thing is that if I did want to do anything more than trivial (as in a simple conditional statement) the whole &#8216;write Ruby generate JavaScript&#8217; thing fell down and I ended up writing these nasty Ruby-JavaScript Frankenstein&#8217;s monsters as I&#8217;m sure many of you have:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;page &amp;lt;&amp;lt; 'if (someClientSideVariable) {'
page['a'].replace_html :partial =&gt; 'thing'
page &amp;lt;&amp;lt; '} else {'
page['b'].replace_html :partial =&gt; 'thong'
page &amp;lt;&amp;lt; '}'&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Why do I need to write the &lt;span class=&quot;caps&quot;&gt;RJS&lt;/span&gt; templates in this ugly style?  When &lt;span class=&quot;caps&quot;&gt;RJS&lt;/span&gt; first came out I was quite impressed with the Ruby to JavaScript translation stuff but it&#8217;s limitations (and that of lots of other similar attempts at &#8216;compiling down to JavaScript&#8217; like Google Web Toolkit) shine through after the lightest of uses.  Now, in that example above, I know I could make it cleaner so it&#8217;s not quite fair but still for me (or anyone else that can write JS) it&#8217;s just another hurdle to jump through and, in my experience, it&#8217;s never been long before I&#8217;ve needed to resort to the old &lt;code&gt;page &amp;lt;&amp;lt;&lt;/code&gt; business.  Also, why bother learning another &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; when you already know Prototype? Or, for that matter, what if you don&#8217;t want to use Prototype but do want to use &lt;span class=&quot;caps&quot;&gt;RJS&lt;/span&gt;&#8230;.&lt;/p&gt;


	&lt;p&gt;With this in mind, I&#8217;ve written a tiny weeny plugin to help out.  It&#8217;s called &lt;a href=&quot;http://svn.danwebb.net/external/rails/plugins/minus_r/trunk/&quot;&gt;MinusR&lt;/a&gt; and it simply changes .rjs templates so you can write JavaScript and use &lt;span class=&quot;caps&quot;&gt;ERB&lt;/span&gt; in them:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;if (someClientSideVariable) {
  $('a').update(&amp;lt;%=js render(:partial =&gt; 'thing') %&amp;gt;);
} else {
  $('b').update(&amp;lt;%=js render(:partial =&gt; 'thong') %&amp;gt;);
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;MinusR gives you the js helper that calls to_json on any value passed to it so you can drop nicely escaped and formatted data into your script as before.  Everyone&#8217;s a winner.  Well, not quite, I could be going out on a limb here but I really think this is the better way.  Go on, give it a go.  A bit of javaScript won&#8217;t hurt you&#8230;.&lt;/p&gt;


	&lt;p&gt;The only problem to solve now is to get it highlighting nicely in Textmate&#8230;.anyone?&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;UPDATE&lt;/span&gt;&lt;/strong&gt;: &lt;a href=&quot;http://www.lukeredpath.co.uk&quot;&gt;Luke&lt;/a&gt; has &lt;a href=&quot;http://www.lukeredpath.co.uk/2006/11/17/rjs-templates-without-the-r&quot;&gt;written a little bit&lt;/a&gt; about Minus R.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://danwebb.net">
    <author>
      <name>dan</name>
    </author>
    <id>tag:danwebb.net,2006-11-09:223</id>
    <published>2006-11-09T11:05:00Z</published>
    <updated>2007-01-10T20:26:07Z</updated>
    <category term="JavaScript"/>
    <category term="Projects"/>
    <category term="Rails"/>
    <category term="eventwax"/>
    <category term="javascript"/>
    <category term="rails"/>
    <category term="ujs"/>
    <category term="unobtrusive"/>
    <link href="http://danwebb.net/2006/11/9/event-wax-is-the-first-production-ujs-application" rel="alternate" type="text/html"/>
    <title>Event Wax Is The First Production UJS Application</title>
<summary type="html">&lt;p&gt;&lt;img title=&quot;Event Wax&quot; src=&quot;http://www.danwebb.net/assets/2006/11/9/event_wax_logo.png&quot; alt=&quot;Event Wax&quot; /&gt; &lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;UPDATE&lt;/span&gt;&lt;/strong&gt;: It appears that &lt;a href=&quot;http://events.zaadz.com/&quot;&gt;Zaadz event section&lt;/a&gt; beat us to it as the first production &lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt; app.  Damn!  Excellent work though.&lt;/p&gt;


	&lt;p&gt;Last week we quietly snuck &lt;a href=&quot;http://www.eventwax.com&quot;&gt;Event Wax&lt;/a&gt; into production but now, at last, we are ready to shout about it.  It&#8217;s the result of several months work and a whole load of experience running &lt;a href=&quot;http://www.vivabit.com/atmedia2007&quot;&gt;@media&lt;/a&gt; and is something we&#8217;re pretty proud of.  Event Wax is a web-based application that allows event organisers to easily provide registration, payment and management facilities for attendees.  An early prototype of the application was used to manage the 800 delegates for &lt;a href=&quot;http://www.vivabit.com/atmedia2006&quot;&gt;@media 2006&lt;/a&gt; to great success but since then we&#8217;ve been refining and improving it and its turned into a pretty nifty application.  So now it&#8217;s out in the open I thought I&#8217;d speak a little bit about some of its technical aspects.&lt;/p&gt;


	&lt;p&gt;One of the biggest highlights for me is that it&#8217;s, to my knowledge, the first production application using the &lt;a href=&quot;http://www.ujs4rails.com&quot;&gt;&lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt; Plugin&lt;/a&gt;.  Much of the development of the plugin has grown up alongside this and some of &lt;a href=&quot;http://www.agileevolved.com&quot;&gt;Agile Evolved&#8217;s&lt;/a&gt; applications and it&#8217;s come a long way in a few months from a fairly simple plugin to something very capable of handling pretty intensive Ajax stuff.  In this post I&#8217;ll take one of those features and talk about some of the thinking behind its implementation.  That feature is&#8230;&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;&lt;img title=&quot;Event Wax&quot; src=&quot;http://www.danwebb.net/assets/2006/11/9/event_wax_logo.png&quot; alt=&quot;Event Wax&quot; /&gt; &lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;UPDATE&lt;/span&gt;&lt;/strong&gt;: It appears that &lt;a href=&quot;http://events.zaadz.com/&quot;&gt;Zaadz event section&lt;/a&gt; beat us to it as the first production &lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt; app.  Damn!  Excellent work though.&lt;/p&gt;


	&lt;p&gt;Last week we quietly snuck &lt;a href=&quot;http://www.eventwax.com&quot;&gt;Event Wax&lt;/a&gt; into production but now, at last, we are ready to shout about it.  It&#8217;s the result of several months work and a whole load of experience running &lt;a href=&quot;http://www.vivabit.com/atmedia2007&quot;&gt;@media&lt;/a&gt; and is something we&#8217;re pretty proud of.  Event Wax is a web-based application that allows event organisers to easily provide registration, payment and management facilities for attendees.  An early prototype of the application was used to manage the 800 delegates for &lt;a href=&quot;http://www.vivabit.com/atmedia2006&quot;&gt;@media 2006&lt;/a&gt; to great success but since then we&#8217;ve been refining and improving it and its turned into a pretty nifty application.  So now it&#8217;s out in the open I thought I&#8217;d speak a little bit about some of its technical aspects.&lt;/p&gt;


	&lt;p&gt;One of the biggest highlights for me is that it&#8217;s, to my knowledge, the first production application using the &lt;a href=&quot;http://www.ujs4rails.com&quot;&gt;&lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt; Plugin&lt;/a&gt;.  Much of the development of the plugin has grown up alongside this and some of &lt;a href=&quot;http://www.agileevolved.com&quot;&gt;Agile Evolved&#8217;s&lt;/a&gt; applications and it&#8217;s come a long way in a few months from a fairly simple plugin to something very capable of handling pretty intensive Ajax stuff.  In this post I&#8217;ll take one of those features and talk about some of the thinking behind its implementation.  That feature is&#8230;&lt;/p&gt;
&lt;h3&gt;The In-Line Help System&lt;/h3&gt;


	&lt;p&gt;&lt;img title=&quot;Screenshot showing the open help sidebar&quot; src=&quot;http://www.danwebb.net/assets/2006/11/9/Picture-1.jpg&quot; alt=&quot;Screenshot showing the open help sidebar&quot; /&gt; One of my favourite features in Event Wax is the help sidebar in the admin area.  The interface itself is kept pretty clean but if you need help on a particular page you can just open the help which shows the relevant help page.  This way we avoid filling the screen with prompts and help content that will get in the way of experienced users but still give new users plenty of help if they need it.&lt;/p&gt;


	&lt;p&gt;The help content is in fact taken from the help site which resides at &lt;a href=&quot;http://www.eventwax.com/help/&quot;&gt;eventwax.com/help&lt;/a&gt; but is re-purposed and pulled into the help sidebar via Ajax.  This way we have a searchable, printable plain &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; version of the documentation for users to refer to if needed but are able to provide context sensitive help to users as they use the application.  Of course, this is all implemented unobtrusively and still provides users with a decent experience if for some reason JavaScript isn&#8217;t behaving.  Here&#8217;s how:&lt;/p&gt;


	&lt;p&gt;Firstly, we define the inline help link and a div to hold the help content:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&amp;lt;a href=&quot;/help/your_account/your_event/the_attendees_tab&quot; id=&quot;hlink&quot;&amp;gt;&amp;lt;span&amp;gt;Help&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;

&amp;lt;!-- code omitted for clarity --&amp;gt;

&amp;lt;div id=&quot;help&quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Notice that the href of the link is pointing to the location of &lt;a href=&quot;http://www.eventwax.com/help/your_account/your_event/the_attendees_tab&quot;&gt;that particular help page&lt;/a&gt; in the regular site so as it stands now our help link will just send us through to the correct documentation.  In order to pop up the content in a side bar I&#8217;ve implemented a help script that&#8217;s responsible for opening and closing the sidebar by applying a class to the help div and triggering an Ajax.Updater request to fill it with content.  I&#8217;m not going to show that here but you can &lt;a href=&quot;http://www.eventwax.com/javascripts/admin.js&quot;&gt;check it out if you like&lt;/a&gt;.  Essentially this gives us Help.show(url), Help.hide() and Help.toggle(url) to play with.&lt;/p&gt;


	&lt;p&gt;Now we can use &lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt; to apply some behaviour and make our sidebar come alive:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&amp;lt;% apply_behaviour '#hlink:click', 'Help.toggle(this.href); return false;' %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This catches the help links click event and instead triggers the sidebar to open and close.  We call Help.toggle() to open the sidebar passing in the href of the link as the content to get to place in the help div.  At this point, it&#8217;s all pretty much working but there&#8217;s one snag: there are links inside the help content and we want them to change the sidebar rather than link normally.  Time for some more &lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt;:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&amp;lt;% apply_behaviour '#help a:click', 'Help.open(this.href); return false;' %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;We hijack the click events of all the links inside the help div and make them call Help.open() with their href instead of their default behaviour which causes them to open within the sidebar.  Sorted.&lt;/p&gt;


	&lt;p&gt;There&#8217;s a final problem to solve.  The normal help content is going to need to be inside a full &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; document with a header and footer while the help content in the sidebar doesn&#8217;t need any of that.  We solve this with a bit of Rails magic.  The Help controller that displays the help pages looks like this:&lt;/p&gt;


&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class HelpController &amp;lt; ApplicationController

  # displays a page of help given the path
  def page
    # page finding code ommitted for clarity
    respond_to do |type|
      type.html { render :file =&gt; page, :layout =&gt; :help }
      type.js { render :file =&gt; page, :layout =&gt; false }
    end
  end

end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This means that requests for help pages via Ajax get no layout and just get the html content and normal requests get the whole page, doctype, html tag and all.  As you can see it would be easy to dispense these pages in lots of other formats if we need to.&lt;/p&gt;


	&lt;p&gt;So that&#8217;s that&#8230;As you can see, it&#8217;s really quite simple to get some impressive features working unobtrusively, especially with Rails and &lt;span class=&quot;caps&quot;&gt;UJS&lt;/span&gt;.  In coming posts I&#8217;ll highlight how I went about implementing some of the other features of Event Wax but in the meantime &lt;a href=&quot;http://www.eventwax.com&quot;&gt;register&lt;/a&gt; and check out the application and plan an event while you&#8217;re at it.  Get it while it&#8217;s free!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://danwebb.net">
    <author>
      <name>dan</name>
    </author>
    <id>tag:danwebb.net,2006-09-18:105</id>
    <published>2006-09-18T09:50:00Z</published>
    <updated>2006-09-18T10:00:48Z</updated>
    <category term="Events"/>
    <category term="JavaScript"/>
    <category term="Rails"/>
    <category term="exampleapp"/>
    <category term="railsconf"/>
    <category term="slides"/>
    <category term="ujs"/>
    <link href="http://danwebb.net/2006/9/18/railsconf-presentation-slides-and-example-code" rel="alternate" type="text/html"/>
    <title>RailsConf Presentation Slides and Example Code</title>
<content type="html">
            &lt;p&gt;As promised, here are the slides and example code from my RailsConf presentation.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;/railsconf2006/ujs_railsconf.pdf&quot;&gt;Presentation Slides&lt;/a&gt; (PDF)&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;/railsconf2006/ujs_shopping.zip&quot;&gt;Example Application&lt;/a&gt; (ZIP)&lt;/li&gt;
	&lt;/ul&gt;
          </content>  </entry>
</feed>
