<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" version="2.0">
  <channel>
    <title>The Rich Web Experience</title>
    <link>http://therichwebexperience.com</link>
    <description>The Rich Web Experience</description>
    <item>
      <title>Tea leaf [Flickr]</title>
      <link>http://therichwebexperience.com/blog/aaron_gustafson/2012/01/tea_leaf_flickr_</link>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/people/aarongustafson/"&gt;Aaron Gustafson&lt;/a&gt; posted a photo:&lt;/p&gt;
	
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/aarongustafson/6776764157/" title="Tea leaf"&gt;&lt;img src="http://farm8.staticflickr.com/7143/6776764157_a709241120_m.jpg" width="240" height="240" alt="Tea leaf" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EasyReader/~4/sjEE5H8Bwbo" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 28 Jan 2012 11:01:00 CST</pubDate>
      <guid isPermaLink="true">tag:flickr.com,2005:/photo/6776764157</guid>
      <dc:creator>Aaron Gustafson</dc:creator>
    </item>
    <item>
      <title>The apparent results of meeting room boredom [Flickr]</title>
      <link>http://therichwebexperience.com/blog/aaron_gustafson/2012/01/the_apparent_results_of_meeting_room_boredom_flickr_</link>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/people/aarongustafson/"&gt;Aaron Gustafson&lt;/a&gt; posted a photo:&lt;/p&gt;
	
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/aarongustafson/6771638329/" title="The apparent results of meeting room boredom"&gt;&lt;img src="http://farm8.staticflickr.com/7010/6771638329_c1a6abb6a3_m.jpg" width="240" height="240" alt="The apparent results of meeting room boredom" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EasyReader/~4/Z82yBmu9YMg" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 27 Jan 2012 11:21:00 CST</pubDate>
      <guid isPermaLink="true">tag:flickr.com,2005:/photo/6771638329</guid>
      <dc:creator>Aaron Gustafson</dc:creator>
    </item>
    <item>
      <title>LinkedIn Etiquette</title>
      <link>http://therichwebexperience.com/blog/howard_lewis_ship/2012/01/linkedin_etiquette</link>
      <description>&lt;p&gt;I've used &lt;a href="http://linkedin.com"&gt;LinkedIn&lt;/a&gt; for many years now, long before I joined Facebook ... I liked the concept of never losing contact information with business contacts and technologist. It just seemed like a good idea (though I do sometimes wonder &lt;a href="http://www.youtube.com/watch?v=NcfXij6t4LA"&gt;if LinkedIn has any particular purpose&lt;/a&gt;).
&lt;p&gt;I tend to only connect with people I've met in person, or at least talked to on the phone.
&lt;p&gt;One thing that drives me crazy about LinkedIn is that you aren't forced to customize the message. As far as I'm concerned, the default message is like no message at all, and its a sign that you are just trolling for contacts. Just like you should always write a cover letter for a resume.
&lt;p&gt;So the first rule of LinkedIn is: &lt;strong&gt;always customize the message&lt;/strong&gt;. You chances of a connection go up significantly (at least with me) ... and with the default message, your chances drop down to near zero.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4110180-3214990755545065639?l=tapestryjava.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TapestryCentral/~4/7DjI04zp4n0" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 27 Jan 2012 10:07:08 CST</pubDate>
      <guid isPermaLink="true">tag:blogger.com,1999:blog-4110180.post-3214990755545065639</guid>
      <dc:creator>Howard Lewis Ship</dc:creator>
    </item>
    <item>
      <title>Tapestry Advantages</title>
      <link>http://therichwebexperience.com/blog/howard_lewis_ship/2012/01/tapestry_advantages</link>
      <description>&lt;p&gt;A summary of a &lt;a href="http://tapestry.1045711.n5.nabble.com/Stuts-VS-Tapestry-I-need-some-ammo-td5432282.html"&gt;discussion about the advantages of Tapestry over Struts&lt;/a&gt;:
&lt;ul&gt;
&lt;li&gt;Exceptional exception reporting&lt;/li&gt;
&lt;li&gt;Significantly less code&lt;/li&gt;
&lt;li&gt;Live class reloading&lt;/li&gt;
&lt;li&gt;Sensible defaults, especially for &lt;a href="http://en.wikipedia.org/wiki/SEO"&gt;SEO&lt;/a&gt;-friendly URLs&lt;/li&gt;
&lt;li&gt;Great community&lt;/li&gt;
&lt;li&gt;Flexibility and customizability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Interestingly, the quality of Tapestry's documentation was mentioned ... favorably! Between the revised &lt;a href="http://tapestry.apache.org"&gt;home page&lt;/a&gt;, and &lt;a href="http://jumpstart.doublenegative.com.au/home.html"&gt;Tapestry JumpStart&lt;/a&gt; (and &lt;a href="http://blog.tapestry5.de/index.php/2011/09/23/publishing-tapestry-5-in-action-book-on-my-own/"&gt;Igor's coming book&lt;/a&gt;), I think we're headed in the right direction in terms of documentation going from a liability to an asset.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4110180-3557656971524285189?l=tapestryjava.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TapestryCentral/~4/Rw7zKtUFgjI" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 26 Jan 2012 12:26:50 CST</pubDate>
      <guid isPermaLink="true">tag:blogger.com,1999:blog-4110180.post-3557656971524285189</guid>
      <dc:creator>Howard Lewis Ship</dc:creator>
    </item>
    <item>
      <title>Getting Around Entering a SSL Passphrase when Restarting Apache</title>
      <link>http://therichwebexperience.com/blog/mike_girouard/2012/01/getting_around_entering_a_ssl_passphrase_when_restarting_apache</link>
      <description>&lt;p&gt;Shame on me for not knowing this earlier.&lt;/p&gt;
&lt;pre&gt;sudo apachectl -k graceful&lt;/pre&gt;
&lt;p&gt;Reloads the Apache httpd gracefully by reloading configs only. This is hella useful if your server has SSL VHosts with passwords that you don&amp;#8217;t know.&lt;/p&gt;
&lt;p&gt;RedHat folks can do use &lt;code&gt;service&lt;/code&gt; too:&lt;/p&gt;
&lt;pre&gt;sudo -i service httpd graceful&lt;/pre&gt;
&lt;div style='clear:both'&gt;&lt;/div&gt;</description>
      <pubDate>Thu, 26 Jan 2012 11:23:00 CST</pubDate>
      <guid isPermaLink="true">http://www.lovemikeg.com/?p=420</guid>
      <dc:creator>Mike Girouard</dc:creator>
    </item>
    <item>
      <title>Github Ribbons in CSS</title>
      <link>http://therichwebexperience.com/blog/terry_ryan/2012/01/github_ribbons_in_css</link>
      <description>&lt;p&gt;&lt;img style="float: right;" src="/blog/assets/content/ribbon.png" alt="" width="305" height="179" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com"&gt;Github&lt;/a&gt; has these &lt;a href="https://github.com/blog/273-github-ribbons"&gt;cool ribbon images&lt;/a&gt; that you can use if you want to encourage forking your project on your site. They're great and I wanted to use them on a little project I am working on. However, one of my goals was not to use any images, but rather produce all display elements with CSS. &lt;/p&gt;
&lt;p&gt;It was a little bit of trial and error but I got it working. Basically you do the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create a link in a div with an id of "banner"&lt;/li&gt;
&lt;li&gt;Force div#banner to be 149px x 149px.&lt;/li&gt;
&lt;li&gt;Set overflow to "hidden"&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="clear: both"&gt;This creates a square display area that won't show things that stretch out past the bounds of the box.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create an A link&lt;/li&gt;
&lt;li&gt;Tilt it using a CSS transform&lt;/li&gt;
&lt;li&gt;Use relative positioning to pull the ribbon into place&lt;/li&gt;
&lt;li&gt;Use CSS shadows to tweak the text and ribbon shadows&lt;/li&gt;
&lt;li&gt;Finally I use a CSS gradient in the background of the ribbon to give it the bands that run along the edge.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;script src="https://gist.github.com/1679040.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p style="clear: both"&gt;&lt;strong&gt;Issues&lt;/strong&gt;:&lt;/p&gt;
&lt;ul style="clear: both"&gt;
&lt;li&gt;It's not a pixel perfect representation. &lt;/li&gt;
&lt;li&gt;It doesn' work on IE before 9. It doesn't appear at all. &lt;/li&gt;
&lt;/ul&gt;
&lt;p style="clear: both"&gt;I'm not sure if I'm going to use this. I'll sound judgmental here, but the fact that it doesn't show up on IE less than 9 seems like a good thing. Do I want a developer on my project that isn't using the latest browser? Probably not. &lt;/p&gt;
&lt;p style="clear: both"&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;br /&gt;&lt;a href="/examples/ribbon/"&gt;See the live demo here.&lt;/a&gt;&lt;/p&gt;
&lt;p style="clear: both"&gt;&lt;strong&gt;Update&lt;/strong&gt;&lt;/p&gt;
&lt;p style="clear: both"&gt;A couple people pointed out that there was a weird doubling of the letters on their browser (Chrome on Windows, and Safari on iPad.) Looks like it was caused by a slight text-shadow I had on the text. The text on the original banner has some anti-aliasing going on, and on some browsers, the text shadow helps it look a little smoother, but on others you get that doubling. So I've removed the text shadow.  Display should be a little more consistent. &lt;/p&gt;</description>
      <pubDate>Wed, 25 Jan 2012 15:55:00 CST</pubDate>
      <guid isPermaLink="true">http://www.terrenceryan.com/blog/post.cfm/github-ribbons-in-css</guid>
      <dc:creator>Terry Ryan</dc:creator>
    </item>
    <item>
      <title>Tapestry 5.4: Focus on JavaScript</title>
      <link>http://therichwebexperience.com/blog/howard_lewis_ship/2012/01/tapestry_5_4_focus_on_javascript_1</link>
      <description>&lt;div&gt;
  &lt;p&gt;
       Tapestry 5.3.1 is out in the wild ... and if Tapestry is to
       stay relevant, Tapestry 5.4 is going to need to be something
       quite (r)evolutionary.
  &lt;/p&gt;

&lt;blockquote&gt;
  There was some confusion on the Tapestry developer mailing list in
  advance of this blog post; I'd alluded that it was coming, and some
  objected to such pronouncements coming out fully formed, without
  discussion. In reality, this is just a distillation of ideas, a
  starting point, and not a complete, finalized solution. If it's more
  detailed than some discussions of Tapestry's evolution in the past,
  that just means that the mailing list discussion and eventual
  implementation will be that much better informed.
&lt;/blockquote&gt;
  &lt;p&gt;
    In posts and other conversations, I've alluded to my vision for
    Tapestry 5.4. As always, the point of Tapestry is to allow
    developers to &lt;em&gt;code less, deliver more&lt;/em&gt;, and that has been
    the focus of Tapestry on the server side: everything drives that
    point: terseness of code and templates, live class reloading, and
    excellent feedback are critical factors there. Much of what went
    into Tapestry 5.3 strengthened those points ... enhancements to
    Tapestry's meta-programming capabilities, improvements to the IoC
    container, and reducing Tapestry's memory footprint in a number of
    ways. I have one client reporting a 30% reduction in memory
    utilization, and another reporting a 30 - 40% improvement in
    execution speed.
  &lt;/p&gt;

  &lt;p&gt;
    Interestingly, I think that for Tapestry to truly stay relevant,
    it needs to shift much, much, more of the emphasis to the client
    side. For some time, Tapestry has been walking a fine line with
    regards to the critical question of &lt;em&gt;where does the application
    execute?&lt;/em&gt;  Pre-Ajax, that was an easy question: the
    application runs on the server, with at most minor JavaScript
    tricks and validations on the client.  As the use of Ajax has
    matured, and customer expectations for application behavior in the
    browser have expanded, it is no longer acceptable to say that
    Tapestry is page based, with limited Ajax
    enhancements. Increasingly, application flow and business logic
    need to execute in the browser, and the server-side's role is to
    orchestrate and facilitate the client-side application, as well as
    to act as a source and sink of data ultimately stored in a
    database.
  &lt;/p&gt;

  &lt;p&gt;
    As Tapestry's server-side has matured, the client side has not
    kept sufficient pace. Tapestry does include some excellent
    features, such as how it allows the server-side to drive
    client-side JavaScript in a modular and efficient way. However,
    that is increasingly insufficient ... and the tension caused by
    give-and-take between client-side and server-side logic has grown
    with each release.
  &lt;/p&gt;

  &lt;p&gt;
    Nowhere is this more evident than in how Tapestry addresses HTML
    forms. This has always been a tricky issue in Tapestry, because
    the dynamic rendering that can occur needs to be matched by
    dynamic form submission processing. In Tapestry, the approach is
    to serialize into the form instructions that will be used when the
    form is submitted (see the &lt;code&gt;store()&lt;/code&gt; method of the
    &lt;a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/FormSupport.html"&gt;FormSupport&lt;/a&gt;
    API). These instructions are used during the processing of the
    form submission request to re-configure the necessary components,
    and direct them to read their query parameters, perform
    validations, and push updated values back into server-side objects
    properties. If you've ever wondered what
    the &lt;code&gt;t:formdata&lt;/code&gt; hidden input field inside every
    Tapestry forms is about ... well, now you know: it's a serialized
    stream of Java objects, GZipped and MIME encoded.

  &lt;/p&gt;
  &lt;p&gt;
    However, relative to many other things in Tapestry, this is a bit
    clumsy and limited. You start to notice this when you see the
    tepid response to questions on the mailing list such as "&lt;em&gt;how
    to do cross-field validation?&lt;/em&gt;" Doing more complicated things,
    such as highly dynamic form layouts, or forms with even marginal
    relationships between fields, can be problematic (though still
    generally possible) ... but it requires a bit too much internal
    knowledge of Tapestry, and the in-browser results feel a bit
    kludgy, a bit clumsy. Tapestry starts to feel like it is getting
    in the way, and that's never acceptible.
  &lt;/p&gt;
  &lt;p&gt;
    Simply put, Tapestry's abstractions on forms and fields is
    both &lt;a href="http://en.wikipedia.org/wiki/Leaky_abstraction"&gt;leaky&lt;/a&gt;
    and insufficient. Tapestry is trying to do too much, and simply
    can't keep up with modern, reasonable demands in terms of
    responsiveness and useability inside the client. We've become used
    to pages rebuilding and reformatting themselves even while we're
    typing.  For Tapestry to understand how to process the form
    submission, it needs a model of what the form looks like on the
    client-side, and it simply doesn't have it. There isn't an
    effective way to do so without significantly restricting what is
    possible on the client side, or requiring much more data to be
    passed in requests, or stored server-side in the session.
  &lt;/p&gt;
  &lt;p&gt;
    The primary issue here is that overall form submission cycle,
    especially combined with Tapestry's need to serialize commands
    into the form (as the hidden &lt;code&gt;t:formdata&lt;/code&gt; field). Once
    you add Ajax to this mix, where new fields and rules are created
    dynamically (on the server side) and installed into the
    client-side DOM ... well, it gets harder and harder to manage.
    Add in a few more complications (such as a mix of transient and
    persistent Hibernate entities, or dynamic creation of sub-entities
    and relationships) into a form, it can be a brain burner getting
    Tapestry to do the right thing when the form is submitted: you
    need to understand exactly how Tapestry processes
    that &lt;code&gt;t:formdata&lt;/code&gt; information, and how to add your own
    callbacks into the callback stream to accomplish just exactly the
    right thing at just exactly the right time. Again, this is not the
    Tapestry way, where things are expected to &lt;em&gt;just work&lt;/em&gt;.
  &lt;/p&gt;
  &lt;p&gt;
    Further, there is some doubt about even the desirability of the
    overall model. In many cases, it makes sense to batch together a
    series of changes to individual properties ... but in many more,
    it is just as desirable for individual changes to filter back to
    the server (and the database) as the user
    navigates. Form-submit-and-re-render is
    a &lt;a href="http://en.wikipedia.org/wiki/IBM_3270"&gt;green screen&lt;/a&gt;
    style of user interaction. Direct interaction is the expectation
    now, and that's something Tapestry should embrace.
  &lt;/p&gt;
  &lt;p&gt;
    What's the solution, then? Well, it's still very much a moving
    target. The goal is to make creating client-side JavaScript
    libraries easier, to make it easier to integrate with libraries such
    as &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; (and its vast library
    of extensions), make things simpler and more efficient on the
    client side, and not sacrifice the features that make Tapestry fun
    and productive in the first place.&lt;/p&gt;

  &lt;h3&gt;Overall Vision&lt;/h3&gt;

  &lt;p&gt;The overall vision breaks down into a number of steps:&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;Reduce or remove outside dependencies&lt;/li&gt;
    &lt;li&gt;Modularize JavaScript&lt;/li&gt;
    &lt;li&gt;Change page initializations to use modules&lt;/li&gt;
    &lt;li&gt;Embrace client-side controller logic&lt;/li&gt;
  &lt;/ul&gt;

  &lt;p&gt;
    Of course, all of these steps depend on the others, so there isn't
    a good order to discuss them.
  &lt;/p&gt;

  &lt;h3&gt;Reducing and removing outside dependencies&lt;/h3&gt;

  &lt;p&gt;
    Tapestry's client-side strength has always been lots of "out of
    the box" functionality: client-side validation, Zones and other
    Ajax-oriented behaviors, and a well-integrated system for
    performing page-level initializations.
  &lt;/p&gt;
  &lt;p&gt;
    However, this strength is also a weakness, since that out of the
    box behavior is too tightly tied to the &lt;a href="http://prototypejs.org/"&gt;Prototype&lt;/a&gt; and
    &lt;a href="http://script.aculo.us/"&gt;Scriptaculous&lt;/a&gt; libraries ... reasonable choices in 2006, but
    out-of-step with the industry today. Not just in terms of the
    momentum behind jQuery, but also in terms of very different
    approaches, such
    as &lt;a href="http://www.sencha.com/"&gt;Sencha/ExtJS&lt;/a&gt; and
    others.&lt;/p&gt;

  &lt;p&gt;
    It was a conscious decision in 2006 to not attempt to create an
    abstraction layer before I understood all the abstractions. I've
    had the intermediate time to embrace those abstractions. Now the
    big problem is momentum and backwards compatibility.&lt;/p&gt;

  &lt;p&gt;
    Be removing unnecessary behaviors, such as animations, we can
    reduce Tapestry's client-side needs. Tapestry needs to be able
    to &lt;strong&gt;attach event handlers&lt;/strong&gt; to elements. It needs to
    be able to easily &lt;strong&gt;locate elements&lt;/strong&gt; via unique ids,
    or via &lt;strong&gt;CSS selectors&lt;/strong&gt;. It needs to be able
    to &lt;strong&gt;run Ajax requests&lt;/strong&gt; and handle the responses,
    including &lt;strong&gt;dynamic updates to elements&lt;/strong&gt;.&lt;/p&gt;
  &lt;p&gt;

    &lt;p&gt;All of these things are reasonable to abstract, and by making
    it even easier to execute JavaScript as part of a page render or
    page update
    (&lt;a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/ajax/AjaxResponseRenderer.html"&gt;something
    already present in Tapestry 5.3&lt;/a&gt;), currently built-in features
    (such as animations) can be delegated to the application, which is
    likely a better choice in any case.&lt;/p&gt;

  &lt;h3&gt;Modularizing JavaScript&lt;/h3&gt;

  &lt;p&gt;
    Tapestry has always been careful about avoiding client-side
    namespace polution.  Through release 5.2, most of Tapestry's
    JavaScript was encapulated in the &lt;code&gt;Tapestry&lt;/code&gt; object. In
    Tapestry 5.3, a second object, &lt;code&gt;T5&lt;/code&gt; was introduced with
    the intention that it gradually replace the
    original &lt;code&gt;Tapestry&lt;/code&gt; object (but this post represents a
    change in direction).&lt;/p&gt;
  &lt;p&gt;
    However, that's not enough. Too often, users have created in-line
    JavaScript, or JavaScript libraries that defined "bare" variables
    and functions (that are ultimately added to the
    browser's &lt;code&gt;window&lt;/code&gt; object). This causes problems,
    including collisions between components (that provide competing
    definitions of objects and functions), or behavior that varies
    depending on whether the JavaScript was added to the page as part
    of a full-page render, or via an Ajax partial page render.&lt;/p&gt;
  &lt;p&gt;
    The right approach is to encourage and embrace some form of
    &lt;a href="http://yuiblog.com/blog/2007/06/12/module-pattern/"&gt;JavaScript
      module architecture&lt;/a&gt;, where there are no explicit global
    variables or functions, and that all JavaScript is evaluated
    inside a function, allowing for private variables and
    functions.&lt;/p&gt;
  &lt;p&gt;
    Currently, I'm thinking in terms of &lt;a href="http://requirejs.org/"&gt;RequireJS&lt;/a&gt; as
    the way to organize the JavaScript. Tapestry would faciliate
    organizing its own code into modules, as well as
    application-specific (or even page-specific) JavaScript
    modules. This would mean that de-referencing the &lt;code&gt;T5&lt;/code&gt;
    object would no longer occur (outside of some kind of temporary
    compatibility mode).&lt;/p&gt;
  &lt;p&gt;
    For example, clicking a button inside some container element
    might, under 5.3, publish an event using Tapestry's client-side
    publish/subscribe system. In the following example, the click
    events bubble up from the buttons (with the &lt;code&gt;button&lt;/code&gt;
    CSS class name) to a container element, and are then published
    under the topic name &lt;code&gt;button-clicked&lt;/code&gt;.
  &lt;/p&gt;
  &lt;script src="https://gist.github.com/1603920.js?file=53pubsubexample.js"&gt;&lt;/script&gt;
  &lt;p&gt;
    Consider this an abbreviated example, as it doesn't explain where
    the &lt;code&gt;element&lt;/code&gt; variable is defined or initialized; the
    important part is the interaction with Tapestry's client-side
    library: the reference to the &lt;code&gt;T5.pubsub.publish&lt;/code&gt; function.
  &lt;/p&gt;
  &lt;p&gt;
    Under 5.4, using the RequireJS &lt;code&gt;require&lt;/code&gt; function, this
    might be coded instead as:
  &lt;/p&gt;
  &lt;script src="https://gist.github.com/1603930.js?file=54pubsubexample.js"&gt;&lt;/script&gt;
  &lt;p&gt;
    Here, the &lt;code&gt;t5/pubsub&lt;/code&gt; module will be loaded by RequireJS and
    passed as a parameter into the function, which is automatically
    executed. So, this supports JavaScript modularization, and
    leverages RequireJS's ability to load modules on-the-fly, 
    as needed.
  &lt;/p&gt;
  &lt;p&gt;
    Notice the difference between the two examples; in the first
    example, coding as a module was &lt;em&gt;optional&lt;/em&gt; (but
    recommended), since the necessary &lt;code&gt;publish()&lt;/code&gt; function
    was accessible either way. In the 5.4 example, coding using
    JavaScript modules is virtually &lt;em&gt;required&lt;/em&gt;: the anonymous
    function passed to &lt;code&gt;require()&lt;/code&gt; is effectively a module,
    but its only through the use of &lt;code&gt;require()&lt;/code&gt; (or
    RequireJS's &lt;code&gt;define()&lt;/code&gt;) that the &lt;code&gt;publish()&lt;/code&gt;
    function can be accessed. &lt;/p&gt;
  &lt;p&gt;
    This is both the carrot and the stick; the carrot is how easy it
    is to declare dependencies and have them passed in to your
    function-as-a-module. The stick is that (eventually)
    the &lt;em&gt;only&lt;/em&gt; way to access those dependencies is by providing
    a module and declaring dependencies.
  &lt;/p&gt;
  &lt;h3&gt;Change page initializations to use modules&lt;/h3&gt;

  &lt;p&gt;
    Tapestry has a reasonably sophisticated system for allowing
    components to describe their JavaScript requirements as they
    render, in the form of
    the &lt;a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html"&gt;JavaScriptSupport&lt;/a&gt;
    environmental (an environmental is a kind of
    per-thread/per-request service object).  Methods on
    JavaScriptSupport allow a component to request that a JavaScript
    library be imported in the page (though this is most commonly
    accomplished using
    the &lt;a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Import.html"&gt;Import&lt;/a&gt;
    annotation), and to request the &lt;em&gt;initialization functions&lt;/em&gt;
    get executed.&lt;/p&gt;
  &lt;p&gt;
    Part of Tapestry's Ajax support is that in an Ajax request, the
    JavaScriptSupport methods can still be invoked, but a completely
    different implementation is responsible for integrating those
    requests into the overall reply (which in an Ajax request is a JSON object, rather
    than a simple stream of HTML).
  &lt;/p&gt;
  &lt;p&gt;
    Here's an example component from the TapX library:&lt;/p&gt;

&lt;script src="https://gist.github.com/1673763.js?file=Expando.java"&gt;&lt;/script&gt;

  &lt;p&gt;
    The @Import annotation directs that a stack (a set of related
    JavaScript libraries, defined elsewhere) be imported into the
    page; alternately, the component could import any number of
    specific JavaScript files, located either in the web application
    context folder, or on the classpath.&lt;/p&gt;
  &lt;p&gt;
    Inside the &lt;code&gt;afterRender()&lt;/code&gt; method, the code constructs
    a &lt;a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/json/JSONObject.html"&gt;JSONObject&lt;/a&gt;
    of data needed on the client side to perform the operation. The
    call to &lt;code&gt;addInitializerCall&lt;/code&gt; references a function by
    name: this function must be added to
    the &lt;code&gt;T5.Initializers&lt;/code&gt; namespace object.  Notice the
    naming: &lt;code&gt;tapxExpando&lt;/code&gt;: a prefix to identify the
    library, and to prevent collisions with any other application or
    library that also added its own functions to
    the &lt;code&gt;T5.initializers&lt;/code&gt; object.
  &lt;/p&gt;
  &lt;p&gt;
    The JavaScript library includes the function that will be invoked:
  &lt;/p&gt;
  &lt;script src="https://gist.github.com/1673810.js?file=tapx-core.js"&gt;&lt;/script&gt;
  &lt;p&gt;
    Under 5.4, this would largely be the same except:
  &lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;There will be a specific Java package for each library (or the
      application) to store library modules.&lt;/li&gt;
    &lt;li&gt;The JavaScriptSupport environmental will have new methods to
      reference a function, inside a module, to invoke.&lt;/li&gt;
      &lt;li&gt;Stacks will consist not just of individual libraries, but
 also modules, following the naming and packaging
 convention.&lt;/li&gt;
  &lt;/ul&gt;

  &lt;h3&gt;Embrace client-side controller logic&lt;/h3&gt;

&lt;p&gt;
  The changes discussed so far only smooth out a few rough edges;
  they still position Tapestry code, running on the server, as driving
  the entire show. 
 &lt;/p&gt;

&lt;p&gt;
  As alluded to earlier; for any sophisticated user interface, the
  challenge is to coordinate the client-side user interface (in terms
  of form fields, DOM elements, and query parameters) with the
  server-side components; this is encoded into the
  hidden &lt;code&gt;t:formdata&lt;/code&gt; field. However, it is my opinion that
  for any dynamic form, Tapestry is or near the end of the road for
  this approach.&lt;/p&gt;
&lt;p&gt;Instead, it's time to embrace client-logic, written in JavaScript,
  in the browser. Specifically, break away from HTML forms, and
  embrace a more dynamic structure, one where "submitting" a form
  always works through an Ajax update ... and what is sent is not a
  simple set of query parameters and values, but a JSON representation
  of what was updated, changed, or created.
&lt;/p&gt;
&lt;p&gt;
  My specific vision is to
  integrate &lt;a href="http://documentcloud.github.com/backbone/"&gt;Backbone.js&lt;/a&gt;
  (or something quite similar), to move this logic solidly to the
  client side. This is a fundamental change: one where the client-side
  is free to change and reconfigure the UI in any way it likes, and is
  ultimately responsible for packaging up the completed data and
  sending it to the server.
&lt;/p&gt;
&lt;p&gt;
  When you are used to
  the &lt;a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/BeanEditForm.html"&gt;BeanEditForm&lt;/a&gt;
  component, this might feel like a step backwards, as you end up
  responsible for writing a bit more code (in JavaScript) to
  implement the user interface, input validations, and relationships
  between fields. However, as fun as BeanEditForm is, the declarative
  approach to validation on the client and the server has proven to be
  limited and limiting, especially in the face of cross-field
  relationships. We could attempt to extend the declarative nature,
  introducing rules or even scripting languages to establish the
  relationships ... or we could move in a situation that puts the
  developer back in the driver's seat.&lt;/p&gt;
&lt;p&gt;
  Further, there are some that will be concerned that this is a
  violation of
  the &lt;a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;DRY
  pricipal&lt;/a&gt;; however I subscribe to different philosophy that
  client-side and server-side validation are fundamentally different
  in any case; this is discussed in an excellent
  &lt;a href="http://blog.ianbicking.org/2011/03/30/js-on-server-and-client-is-not-a-big-deal/"&gt;blog
  post by Ian Bickling&lt;/a&gt;.

&lt;p&gt;
  Certainly there will be components and services to assist with this
  process, in term of extracting data into JSON format, and converting
  JSON data into a set of updates to the server-side objects. There's
  also a number of security concerns that necessitate careful
  validation of what comes up from the client in the Ajax request.
  Further, there will be new bundled libraries to make it easier to
  build these dynamic user interfaces.&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;
  In this vision of Tapestry's future, the server-side framework
  starts to shift from the focus of all behavior to
  the &lt;em&gt;facilitator&lt;/em&gt;: it paints the broad stokes on the server,
  but the key interactions end up working exclusively on the
  client. &lt;/p&gt;
&lt;p&gt;
  I'm sure this view will be controversial: after all, on the surface,
  what the community really wants is just "jQuery instead of
  Prototype". However, all of the factors described in the above
  sections are, I feel, critical to keeping Tapestry relevant by
  embracing the client-side in the way that the client-side
  demands.&lt;/p&gt;

&lt;p&gt;
  I think this change in focus is a big deal; I think it is also
  necessary for Tapestry to stay relevant in the medium to long
  term. I've heard from many individual developers (not necessarily
  Tapestry users) that what they really want is "just jQuery and a
  restful API"; I think Tapestry can be that restful API, but by
  leveraging many of Tapestry's other strengths, it can be a lot more.
  Building something right on the metal feels empowering ... until you
  hit all the infrastructure that Tapestry provides, including
  best-of-class exception reporting, on-the-fly JavaScript aggregation
  and minimization, and (of course) live class reloading during
  development.
java&lt;/p&gt;  
  &lt;p&gt;
    I'm eager to bring Tapestry to the forfront of web application
  development ... and to deliver it fast!  Monitor the Tapestry
  developer mailing list to see how this all plays out.&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4110180-7447306489952674714?l=tapestryjava.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TapestryCentral/~4/mlpJ4i8ShSA" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 25 Jan 2012 09:46:00 CST</pubDate>
      <guid isPermaLink="true">tag:blogger.com,1999:blog-4110180.post-7447306489952674714</guid>
      <dc:creator>Howard Lewis Ship</dc:creator>
    </item>
    <item>
      <title>More shovels</title>
      <link>http://therichwebexperience.com/blog/tim_kadlec/2012/01/more_shovels</link>
      <description>&lt;p&gt;There is no shortage of information floating around today. There are a multitude of books, magazines, newspapers, blog posts, articles, videos and podcasts just clamoring for our attention. It&amp;#8217;s an incredible thing, this wealth of information we have at our fingertips. Never before has so much knowledge been so easily accessible.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;ve responded by creating a lot of tools that help us collect this information. We can easily store quotes, snippets or even full articles in any one of a hundred different sites and services. We can save links to the videos and recordings that moved us on some level. RSS feeds make it incredibly easy to consume massive quantities of online articles and blog posts. Tools like the incredible &lt;a href="http://ifttt.com/"&gt;Ifttt&lt;/a&gt; help make our many online services interact with each other, further easing the process of collecting information.&lt;/p&gt;
&lt;p&gt;But what happens to that information after it has been carefully tagged and stored away? The more new information we collect, the more old information gets buried. That post we read that sparked an idea, that quote that stirred something deep within—lost and buried. Forgotten amongst the piles of all the other information we&amp;#8217;ve collected.&lt;/p&gt;
&lt;p&gt;Certainly this is nothing new—the issue has merely been amplified. Technology, though, is supposed to work for us. It&amp;#8217;s supposed to help us solve issues we&amp;#8217;ve had in the past. Why not push our tools to not merely collect, but to remind us what is already there?&lt;/p&gt;
&lt;p&gt;We need more services like the&lt;a href="https://kindle.amazon.com/"&gt; Kindle Daily Review&lt;/a&gt; and &lt;a href="http://timehop.com/"&gt;Timehop&lt;/a&gt;. Kindle&amp;#8217;s Daily Review delivers &amp;#8220;flash-cards&amp;#8221; of a book you&amp;#8217;ve read in the past. It displays notes and highlights that you made. It&amp;#8217;s fantastic! I love seeing a passage from a book that I had forgotten all about, but that still sparks something within me. Timehop is similar—it lets you know what you posted on Twitter, Facebook, Foursquare or Instagram a year ago. I&amp;#8217;ve only been using that service for a short time, but already I&amp;#8217;ve found several articles and conversations that I had forgotten about.&lt;/p&gt;
&lt;p&gt;Why is this important? Because serendipity is a stimulant. In his book, &lt;a href="http://www.amazon.com/gp/product/1935633163/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=timkadcom-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1935633163"&gt;&amp;#8220;Marshall McLuhan: You Know Nothing of My Work&amp;#8221;&lt;/a&gt;, Douglas Coupland had this to say about Marshall McLuhan, one of the most prescient minds of the last century: &amp;#8220;For Marshall, the fun of ideas lay in crashing them together to see what emerged from the collision.&amp;#8221; When you rub two stones together, you can make a spark that starts a fire. Put two seemingly unrelated ideas next to each other and the effect is the same.&lt;/p&gt;
&lt;p&gt;Searching, for the most part, eliminates those kinds of serendipitous discoveries. It&amp;#8217;s a more or less direct path to the very specific type of information we are looking for. A service like the Kindle Daily Review, a service that provides &lt;a href="http://test.org.uk/2009/01/28/slow-data-and-the-pleasure-of-automated-nostalgia/"&gt;automated nostalgia&lt;/a&gt;—that&amp;#8217;s the kind of tool that encourages the mixing of ideas, the friction that causes the spark.&lt;/p&gt;
&lt;p&gt;We have enough piles. What we need are more shovels.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/timkadlec/~4/Ykxh3aJQqpI" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 25 Jan 2012 09:39:00 CST</pubDate>
      <guid isPermaLink="true">http://timkadlec.com/?p=1232</guid>
      <dc:creator>Tim Kadlec</dc:creator>
    </item>
    <item>
      <title>Boston Cream Pie [Flickr]</title>
      <link>http://therichwebexperience.com/blog/aaron_gustafson/2012/01/boston_cream_pie_flickr_</link>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/people/aarongustafson/"&gt;Aaron Gustafson&lt;/a&gt; posted a photo:&lt;/p&gt;
	
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/aarongustafson/6758086737/" title="Boston Cream Pie"&gt;&lt;img src="http://farm8.staticflickr.com/7001/6758086737_e828edd011_m.jpg" width="240" height="240" alt="Boston Cream Pie" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EasyReader/~4/l18mNj3T8HA" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 24 Jan 2012 20:29:00 CST</pubDate>
      <guid isPermaLink="true">tag:flickr.com,2005:/photo/6758086737</guid>
      <dc:creator>Aaron Gustafson</dc:creator>
    </item>
    <item>
      <title>Batch Update All Your Vendor Repositories</title>
      <link>http://therichwebexperience.com/blog/mike_girouard/2012/01/batch_update_all_your_vendor_repositories</link>
      <description>&lt;p&gt;I&amp;#8217;ve got just shy of 100 vendor repositories that I pull from for my side projects and client work. Updating them all has become quite a bother so I wrote this little guy to save me some time.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s certainly not perfect, and sometimes falls over, but this does the trick. This handles both Git and SVN repositories, but I&amp;#8217;m sure with a few extra lines you can make it work for whatever SCM you prefer to use.&lt;/p&gt;
&lt;p&gt;&lt;script src="https://gist.github.com/1674246.js"&gt; &lt;/script&gt;&lt;noscript&gt;&lt;a href="https://gist.github.com/1674246"&gt;https://gist.github.com/1674246&lt;/a&gt;&lt;/noscript&gt;&lt;/p&gt;
&lt;div style='clear:both'&gt;&lt;/div&gt;</description>
      <pubDate>Tue, 24 Jan 2012 20:18:00 CST</pubDate>
      <guid isPermaLink="true">http://www.lovemikeg.com/?p=413</guid>
      <dc:creator>Mike Girouard</dc:creator>
    </item>
    <item>
      <title>Tapestry 5.4: Focus on JavaScript</title>
      <link>http://therichwebexperience.com/blog/howard_lewis_ship/2012/01/tapestry_5_4_focus_on_javascript</link>
      <description>&lt;div&gt;
  &lt;p&gt;
       Tapestry 5.3.1 is out in the wild ... and if Tapestry is to
       stay relevant, Tapestry 5.4 is going to need to be something
       quite (r)evolutionary.
  &lt;/p&gt;

&lt;blockquote&gt;
  There was some confusion on the Tapestry developer mailing list in
  advance of this blog post; I'd alluded that it was coming, and some
  objected to such pronouncements coming out fully formed, without
  discussion. In reality, this is just a distillation of ideas, a
  starting point, and not a complete, finalized solution. If it's more
  detailed than some discussions of Tapestry's evolution in the past,
  that just means that the mailing list discussion and eventual
  implementation will be that much better informed.
&lt;/blockquote&gt;
  &lt;p&gt;
    In posts and other conversations, I've alluded to my vision for
    Tapestry 5.4. As always, the point of Tapestry is to allow
    developers to &lt;em&gt;code less, deliver more&lt;/em&gt;, and that has been
    the focus of Tapestry on the server side: everything drives that
    point: terseness of code and templates, live r2eloading, and
    excellent feedback are critical factors there. Much of what went
    into Tapestry 5.3 strengthened those points ... enhancements to
    Tapestry's meta-programming capabilities, improvements to the IoC
    container, and reducing Tapestry's memory footprint in a number of
    ways. I have one client reporting a 30% reduction in memory
    utilization, and another reporting a 30 - 40% improvement in
    execution speed.
  &lt;/p&gt;

  &lt;p&gt;
    Interestingly, I think that for Tapestry to truly stay relevant,
    it needs to shift much, much, more of the emphasis to the client
    side. For some time, Tapestry has been walking a fine line with
    regards to the critical question of &lt;em&gt;where does the application
    execute?&lt;/em&gt;  Pre-Ajax, that was an easy question: the
    application runs on the server, with at most minor JavaScript
    tricks and validations on the client.  As the use of Ajax has
    matured, and customer expectations for application behavior in the
    browser have expanded, it is no longer acceptable to say that
    Tapestry is page based, with limited Ajax
    enhancements. Increasingly, application flow and business logic
    need to execute in the browser, and the server-side's role is to
    orchestrate and facilitate the client-side application, as well as
    to act as a source and sink of data ultimately stored in a
    database.
  &lt;/p&gt;

  &lt;p&gt;
    As Tapestry's server-side has matured, the client side has not
    kept sufficient pace. Tapestry does include some excellent
    features, such as how it allows the server-side to drive
    client-side JavaScript in a modular and efficient way. However,
    that is increasingly insufficient ... and the tension caused by
    give-and-take between client-side and server-side logic has grown
    with each release.
  &lt;/p&gt;

  &lt;p&gt;
    Nowhere is this more evident than in how Tapestry addresses HTML
    forms. This has always been a tricky issue in Tapestry, because
    the dynamic rendering that can occur needs to be matched by
    dynamic form submission processing. In Tapestry, the approach is
    to serialize into the form instructions that will be used when the
    form is submitted (see the &lt;code&gt;store()&lt;/code&gt; method of the
    &lt;a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/FormSupport.html"&gt;FormSupport&lt;/a&gt;
    API). These instructions are used during the processing of the
    form submission request to re-configure the necessary components,
    and direct them to read their query parameters, perform
    validations, and push updated values back into server-side objects
    properties. If you've ever wondered what
    the &lt;code&gt;t:formdata&lt;/code&gt; hidden input field inside every
    Tapestry forms is about ... well, now you know: it's a serialized
    stream of Java objects, GZipped and MIME encoded.

  &lt;/p&gt;
  &lt;p&gt;
    However, relative to many other things in Tapestry, this is a bit
    clumsy and limited. You start to notice this when you see the
    tepid response to questions on the mailing list such as "&lt;em&gt;how
    to do cross-field validation?&lt;/em&gt;" Doing more complicated things,
    such as highly dynamic form layouts, or forms with even marginal
    relationships between fields, can be problematic (though still
    generally possible) ... but it requires a bit too much internal
    knowledge of Tapestry, and the in-browser results feel a bit
    kludgy, a bit clumsy. Tapestry starts to feel like it is getting
    in the way, and that's never acceptible.
  &lt;/p&gt;
  &lt;p&gt;
    Simply put, Tapestry's abstractions on forms and fields is
    both &lt;a href="http://en.wikipedia.org/wiki/Leaky_abstraction"&gt;leaky&lt;/a&gt;
    and insufficient. Tapestry is trying to do too much, and simply
    can't keep up with modern, reasonable demands in terms of
    responsiveness and useability inside the client. We've become used
    to pages rebuilding and reformatting themselves even while we're
    typing.  For Tapestry to understand how to process the form
    submission, it needs a model of what the form looks like on the
    client-side, and it simply doesn't have it. There isn't an
    effective way to do so without significantly restricting what is
    possible on the client side, or requiring much more data to be
    passed in requests, or stored server-side in the session.
  &lt;/p&gt;
  &lt;p&gt;
    The primary issue here is that overall form submission cycle,
    especially combined with Tapestry's need to serialize commands
    into the form (as the hidden &lt;code&gt;t:formdata&lt;/code&gt; field). Once
    you add Ajax to this mix, where new fields and rules are created
    dynamically (on the server side) and installed into the
    client-side DOM ... well, it gets harder and harder to manage.
    Add in a few more complications (such as a mix of transient and
    persistent Hibernate entities, or dynamic creation of sub-entities
    and relationships) into a form, it can be a brain burner getting
    Tapestry to do the right thing when the form is submitted: you
    need to understand exactly how Tapestry processes
    that &lt;code&gt;t:formdata&lt;/code&gt; information, and how to add your own
    callbacks into the callback stream to accomplish just exactly the
    right thing at just exactly the right time. Again, this is not the
    Tapestry way, where things are expected to &lt;em&gt;just work&lt;/em&gt;.
  &lt;/p&gt;
  &lt;p&gt;
    Further, there is some doubt about even the desirability of the
    overall model. In many cases, it makes sense to batch together a
    series of changes to individual properties ... but in many more,
    it is just as desirable for individual changes to filter back to
    the server (and the database) as the user
    navigates. Form-submit-and-re-render is
    a &lt;a href="http://en.wikipedia.org/wiki/IBM_3270"&gt;green screen&lt;/a&gt;
    style of user interaction. Direct interaction is the expectation
    now, and that's something Tapestry should embrace.
  &lt;/p&gt;
  &lt;p&gt;
    What's the solution, then? Well, it's still very much a moving
    target. The goal is to make creating client-side JavaScript
    libraries easier, to make it easier to integrate with libraries such
    as &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; (and its vast library
    of extensions), make things simpler and more efficient on the
    client side, and not sacrifice the features that make Tapestry fun
    and productive in the first place.&lt;/p&gt;

  &lt;h3&gt;Overall Vision&lt;/h3&gt;

  &lt;p&gt;The overall vision breaks down into a number of steps:&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;Reduce or remove outside dependencies&lt;/li&gt;
    &lt;li&gt;Modularize JavaScript&lt;/li&gt;
    &lt;li&gt;Change page initializations to use modules&lt;/li&gt;
    &lt;li&gt;Embrace client-side controller logic&lt;/li&gt;
  &lt;/ul&gt;

  &lt;p&gt;
    Of course, all of these steps depend on the others, so there isn't
    a good order to discuss them.
  &lt;/p&gt;

  &lt;h3&gt;Reducing and removing outside dependencies&lt;/h3&gt;

  &lt;p&gt;
    Tapestry's client-side strength has always been lots of "out of
    the box" functionality: client-side validation, Zones and other
    Ajax-oriented behaviors, and a well-integrated system for
    performing page-level initializations.
  &lt;/p&gt;
  &lt;p&gt;
    However, this strength is also a weakness, since that out of the
    box behavior is too tightly tied to the &lt;a href="http://prototypejs.org/"&gt;Prototype&lt;/a&gt; and
    &lt;a href="http://script.aculo.us/"&gt;Scriptaculous&lt;/a&gt; libraries ... reasonable choices in 2006, but
    out-of-step with the industry today. Not just in terms of the
    momentum behind jQuery, but also in terms of very different
    approaches, such
    as &lt;a href="http://www.sencha.com/"&gt;Sencha/ExtJS&lt;/a&gt; and
    others.&lt;/p&gt;

  &lt;p&gt;
    It was a conscious decision in 2006 to not attempt to create an
    abstraction layer before I understood all the abstractions. I've
    had the intermediate time to embrace those abstractions. Now the
    big problem is momentum and backwards compatibility.&lt;/p&gt;

  &lt;p&gt;
    Be removing unnecessary behaviors, such as animations, we can
    reduce Tapestry's client-side needs. Tapestry needs to be able
    to &lt;strong&gt;attach event handlers&lt;/strong&gt; to elements. It needs to
    be able to easily &lt;strong&gt;locate elements&lt;/strong&gt; via unique ids,
    or via &lt;strong&gt;CSS selectors&lt;/strong&gt;. It needs to be able
    to &lt;strong&gt;run Ajax requests&lt;/strong&gt; and handle the responses,
    including &lt;strong&gt;dynamic updates to elements&lt;/strong&gt;.&lt;/p&gt;
  &lt;p&gt;

    &lt;p&gt;All of these things are reasonable to abstract, and by making
    it even easier to execute JavaScript as part of a page render or
    page update
    (&lt;a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/ajax/AjaxResponseRenderer.html"&gt;something
    already present in Tapestry 5.3&lt;/a&gt;), currently built-in features
    (such as animations) can be delegated to the application, which is
    likely a better choice in any case.&lt;/p&gt;

  &lt;h3&gt;Modularizing JavaScript&lt;/h3&gt;

  &lt;p&gt;
    Tapestry has always been careful about avoiding client-side
    namespace polution.  Through release 5.2, most of Tapestry's
    JavaScript was encapulated in the &lt;code&gt;Tapestry&lt;/code&gt; object. In
    Tapestry 5.3, a second object, &lt;code&gt;T5&lt;/code&gt; was introduced with
    the intention that it gradually replace the
    original &lt;code&gt;Tapestry&lt;/code&gt; object (but this post represents a
    change in direction).&lt;/p&gt;
  &lt;p&gt;
    However, that's not enough. Too often, users have created in-line
    JavaScript, or JavaScript libraries that defined "bare" variables
    and functions (that are ultimately added to the
    browser's &lt;code&gt;window&lt;/code&gt; object). This causes problems,
    including collisions between components (that provide competing
    definitions of objects and functions), or behavior that varies
    depending on whether the JavaScript was added to the page as part
    of a full-page render, or via an Ajax partial page render.&lt;/p&gt;
  &lt;p&gt;
    The right approach is to encourage and embrace some form of
    &lt;a href="http://yuiblog.com/blog/2007/06/12/module-pattern/"&gt;JavaScript
      module architecture&lt;/a&gt;, where there are no explicit global
    variables or functions, and that all JavaScript is evaluated
    inside a function, allowing for private variables and
    functions.&lt;/p&gt;
  &lt;p&gt;
    Currently, I'm thinking in terms of &lt;a href="http://requirejs.org/"&gt;RequireJS&lt;/a&gt; as
    the way to organize the JavaScript. Tapestry would faciliate
    organizing its own code into modules, as well as
    application-specific (or even page-specific) JavaScript
    modules. This would mean that de-referencing the &lt;code&gt;T5&lt;/code&gt;
    object would no longer occur (outside of some kind of temporary
    compatibility mode).&lt;/p&gt;
  &lt;p&gt;
    For example, clicking a button inside some container element
    might, under 5.3, publish an event using Tapestry's client-side
    publish/subscribe system. In the following example, the click
    events bubble up from the buttons (with the &lt;code&gt;button&lt;/code&gt;
    CSS class name) to a container element, and are then published
    under the topic name &lt;code&gt;button-clicked&lt;/code&gt;.
  &lt;/p&gt;
  &lt;script src="https://gist.github.com/1603920.js?file=53pubsubexample.js"&gt;&lt;/script&gt;
  &lt;p&gt;
    Consider this an abbreviated example, as it doesn't explain where
    the &lt;code&gt;element&lt;/code&gt; variable is defined or initialized; the
    important part is the interaction with Tapestry's client-side
    library: the reference to the &lt;code&gt;T5.pubsub.publish&lt;/code&gt; function.
  &lt;/p&gt;
  &lt;p&gt;
    Under 5.4, using the RequireJS &lt;code&gt;require&lt;/code&gt; function, this
    might be coded instead as:
  &lt;/p&gt;
  &lt;script src="https://gist.github.com/1603930.js?file=54pubsubexample.js"&gt;&lt;/script&gt;
  &lt;p&gt;
    Here, the &lt;code&gt;t5/pubsub&lt;/code&gt; module will be loaded by RequireJS and
    passed as a parameter into the function, which is automatically
    executed. So, this supports JavaScript modularization, and
    leverages RequireJS's ability to load modules on-the-fly, 
    as needed.
  &lt;/p&gt;
  &lt;p&gt;
    Notice the difference between the two examples; in the first
    example, coding as a module was &lt;em&gt;optional&lt;/em&gt; (but
    recommended), since the necessary &lt;code&gt;publish()&lt;/code&gt; function
    was accessible either way. In the 5.4 example, coding using
    JavaScript modules is virtually &lt;em&gt;required&lt;/em&gt;: the anonymous
    function passed to &lt;code&gt;require()&lt;/code&gt; is effectively a module,
    but its only through the use of &lt;code&gt;require()&lt;/code&gt; (or
    RequireJS's &lt;code&gt;define()&lt;/code&gt;) that the &lt;code&gt;publish()&lt;/code&gt;
    function can be accessed. &lt;/p&gt;
  &lt;p&gt;
    This is both the carrot and the stick; the carrot is how easy it
    is to declare dependencies and have them passed in to your
    function-as-a-module. The stick is that (eventually)
    the &lt;em&gt;only&lt;/em&gt; way to access those dependencies is by providing
    a module and declaring dependencies.
  &lt;/p&gt;
  &lt;h3&gt;Change page initializations to use modules&lt;/h3&gt;

  &lt;p&gt;
    Tapestry has a reasonably sophisticated system for allowing
    components to describe their JavaScript requirements as they
    render, in the form of
    the &lt;a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html"&gt;JavaScriptSupport&lt;/a&gt;
    environmental (an environmental is a kind of
    per-thread/per-request service object).  Methods on
    JavaScriptSupport allow a component to request that a JavaScript
    library be imported in the page (though this is most commonly
    accomplished using
    the &lt;a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Import.html"&gt;Import&lt;/a&gt;
    annotation), and to request the &lt;em&gt;initialization functions&lt;/em&gt;
    get executed.&lt;/p&gt;
  &lt;p&gt;
    Part of Tapestry's Ajax support is that in an Ajax request, the
    JavaScriptSupport methods can still be invoked, but a completely
    different implementation is responsible for integrating those
    requests into the overall reply (which in an Ajax request is a JSON object, rather
    than a simple stream of HTML).
  &lt;/p&gt;
  &lt;p&gt;
    Here's an example component from the TapX library:&lt;/p&gt;

&lt;script src="https://gist.github.com/1673763.js?file=Expando.java"&gt;&lt;/script&gt;

  &lt;p&gt;
    The @Import annotation directs that a stack (a set of related
    JavaScript libraries, defined elsewhere) be imported into the
    page; alternately, the component could import any number of
    specific JavaScript files, located either in the web application
    context folder, or on the classpath.&lt;/p&gt;
  &lt;p&gt;
    Inside the &lt;code&gt;afterRender()&lt;/code&gt; method, the code constructs
    a &lt;a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/json/JSONObject.html"&gt;JSONObject&lt;/a&gt;
    of data needed on the client side to perform the operation. The
    call to &lt;code&gt;addInitializerCall&lt;/code&gt; references a function by
    name: this function must be added to
    the &lt;code&gt;T5.Initializers&lt;/code&gt; namespace object.  Notice the
    naming: &lt;code&gt;tapxExpando&lt;/code&gt;: a prefix to identify the
    library, and to prevent collisions with any other application or
    library that also added its own functions to
    the &lt;code&gt;T5.initializers&lt;/code&gt; object.
  &lt;/p&gt;
  &lt;p&gt;
    The JavaScript library includes the function that will be invoked:
  &lt;/p&gt;
  &lt;script src="https://gist.github.com/1673810.js?file=tapx-core.js"&gt;&lt;/script&gt;
  &lt;p&gt;
    Under 5.4, this would largely be the same except:
  &lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;There will be a specific Java package for each library (or the
      application) to store library modules.&lt;/li&gt;
    &lt;li&gt;The JavaScriptSupport environmental will have new methods to
      reference a function, inside a module, to invoke.&lt;/li&gt;
      &lt;li&gt;Stacks will consist not just of individual libraries, but
 also modules, following the naming and packaging
 convention.&lt;/li&gt;
  &lt;/ul&gt;

  &lt;h3&gt;Embrace client-side controller logic&lt;/h3&gt;

&lt;p&gt;
  The changes discussed so far only smooth out a few rough edges;
  they still position Tapestry code, running on the server, as driving
  the entire show. 
 &lt;/p&gt;

&lt;p&gt;
  As alluded to earlier; for any sophisticated user interface, the
  challenge is to coordinate the client-side user interface (in terms
  of form fields, DOM elements, and query parameters) with the
  server-side components; this is encoded into the
  hidden &lt;code&gt;t:formdata&lt;/code&gt; field. However, it is my opinion that
  for any dynamic form, Tapestry is or near the end of the road for
  this approach.&lt;/p&gt;
&lt;p&gt;Instead, it's time to embrace client-logic, written in JavaScript,
  in the browser. Specifically, break away from HTML forms, and
  embrace a more dynamic structure, one where "submitting" a form
  always works through an Ajax update ... and what is sent is not a
  simple set of query parameters and values, but a JSON representation
  of what was updated, changed, or created.
&lt;/p&gt;
&lt;p&gt;
  My specific vision is to
  integrate &lt;a href="http://documentcloud.github.com/backbone/"&gt;Backbone.js&lt;/a&gt;
  (or something quite similar), to move this logic solidly to the
  client side. This is a fundamental change: one where the client-side
  is free to change and reconfigure the UI in any way it likes, and is
  ultimately responsible for packaging up the completed data and
  sending it to the server.
&lt;/p&gt;
&lt;p&gt;
  When you are used to
  the &lt;a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/BeanEditForm.html"&gt;BeanEditForm&lt;/a&gt;
  component, this might feel like a step backwards, as you end up
  responsible for writing a bit more code (in JavaScript) to
  implement the user interface, input validations, and relationships
  between fields. However, as fun as BeanEditForm is, the declarative
  approach to validation on the client and the server has proven to be
  limited and limiting, especially in the face of cross-field
  relationships. We could attempt to extend the declarative nature,
  introducing rules or even scripting languages to establish the
  relationships ... or we could move in a situation that puts the
  developer back in the driver's seat.&lt;/p&gt;
&lt;p&gt;
  Further, there are some that will be concerned that this is a
  violation of
  the &lt;a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;DRY
  pricipal&lt;/a&gt;; however I subscribe to different philosophy that
  client-side and server-side validation are fundamentally different
  in any case; this is discussed in an excellent
  &lt;a href="http://blog.ianbicking.org/2011/03/30/js-on-server-and-client-is-not-a-big-deal/"&gt;blog
  post by Ian Bickling&lt;/a&gt;.

&lt;p&gt;
  Certainly there will be components and services to assist with this
  process, in term of extracting data into JSON format, and converting
  JSON data into a set of updates to the server-side objects. There's
  also a number of security concerns that necessitate careful
  validation of what comes up from the client in the Ajax request.
  Further, there will be new bundled libraries to make it easier to
  build these dynamic user interfaces.&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;
  In this vision of Tapestry's future, the server-side framework
  starts to shift from the focus of all behavior to
  the &lt;em&gt;facilitator&lt;/em&gt;: it paints the broad stokes on the server,
  but the key interactions end up working exclusively on the
  client. &lt;/p&gt;
&lt;p&gt;
  I'm sure this view will be controversial: after all, on the surface,
  what the community really wants is just "jQuery instead of
  Prototype". However, all of the factors described in the above
  sections are, I feel, critical to keeping Tapestry relevant by
  embracing the client-side in the way that the client-side
  demands.&lt;/p&gt;

&lt;p&gt;
  I think this change in focus is a big deal; I think it is also
  necessary for Tapestry to stay relevant in the medium to long
  term. I've heard from many individual developers (not necessarily
  Tapestry users) that what they really want is "just jQuery and a
  restful API"; I think Tapestry can be that restful API, but by
  leveraging many of Tapestry's other strengths, it can be a lot more.
  Building something right on the metal feels empowering ... until you
  hit all the infrastructure that Tapestry provides, including
  best-of-class exception reporting, on-the-fly JavaScript aggregation
  and minimization, and (of course) live class reloading during
  development.
java&lt;/p&gt;  
  &lt;p&gt;
    I'm eager to bring Tapestry to the forfront of web application
  development ... and to deliver it fast!  Monitor the Tapestry
  developer mailing list to see how this all plays out.&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4110180-7447306489952674714?l=tapestryjava.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TapestryCentral/~4/mlpJ4i8ShSA" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 24 Jan 2012 19:24:33 CST</pubDate>
      <guid isPermaLink="true">tag:blogger.com,1999:blog-4110180.post-7447306489952674714</guid>
      <dc:creator>Howard Lewis Ship</dc:creator>
    </item>
    <item>
      <title>@globalmoxie on the furry blanket [Flickr]</title>
      <link>http://therichwebexperience.com/blog/aaron_gustafson/2012/01/_globalmoxie_on_the_furry_blanket_flickr_</link>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/people/aarongustafson/"&gt;Aaron Gustafson&lt;/a&gt; posted a photo:&lt;/p&gt;
	
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/aarongustafson/6756367145/" title="@globalmoxie on the furry blanket"&gt;&lt;img src="http://farm8.staticflickr.com/7152/6756367145_cf086c4452_m.jpg" width="240" height="240" alt="@globalmoxie on the furry blanket" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EasyReader/~4/FWIXah9ZCQg" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 24 Jan 2012 13:39:00 CST</pubDate>
      <guid isPermaLink="true">tag:flickr.com,2005:/photo/6756367145</guid>
      <dc:creator>Aaron Gustafson</dc:creator>
    </item>
    <item>
      <title>Review: Gradle Class with Luke Daley</title>
      <link>http://therichwebexperience.com/blog/howard_lewis_ship/2012/01/review_gradle_class_with_luke_daley</link>
      <description>&lt;p&gt;Last week, Luke Daly arrived in Portland to teach a three day &lt;a href="http://gradle.org/"&gt;Gradle&lt;/a&gt; class; the folks at Gradleware were nice enough let me audit the class (so it only cost me a couple of thousand dollars of lost billing revenue to attend).  My goals for the class was to gain a deeper understanding of how Gradle works, so that I could write more efficient builds, diagnose problems, and write my own plugins. The class scored very high on all of those counts!&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;Much of the first day was spent on basics, including a very useful introduction to the Groovy programming language (which is the basis of the &lt;a href="http://gradle.org/docs/current/dsl/index.html"&gt;Gradle DSL&lt;/a&gt;). Even though I have used Groovy pretty extensively for testing purposes over the last couple of years, there were features I've glossed over in the past that turned out to be very useful.&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;The class is taught largely bottom up: from the basics of declaring tasks, then actions on tasks, and gradually working up towards defining tasks inputs and outputs. Compiling Java came pretty late, which seems curious since that's the primary job of Gradle, but this makes sense from a bottom-up approach as &lt;a href="http://gradle.org/docs/current/dsl/org.gradle.api.Project.html#org.gradle.api.plugins.JavaPluginConvention:sourceSets(groovy.lang.Closure)"&gt;SourceSets&lt;/a&gt; can then be described correctly. &lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;The class alternates between lecture and discussion, and short focused labs. At the end of the third day, we worked on tuning up our own builds, passing the video projector cable around ... we had a good time making the Tapestry build more efficient and readable, as well as adding new features to it.&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;I'm feeling very good about my Gradle skills after attending the course; I've already been able to make further improvements to the Tapestry build subsequently, and I have plans for more involving things going forward. &lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;The return on investment for this class is a bit tricky; Gradle simply does so much straight out of the box, and even without a strong understanding of its structure, you can &lt;em&gt;kind of&lt;/em&gt; get it to do what you want just by guesswork and Googling. If you've been using Gradle for a while, I give this a cautious recommendation: getting back the three days of invested time may take a while to pay off. On the other hand, if you are currently dependent on Ant or Maven ... &lt;a href="http://gradle.org/training"&gt;sign up for the next class&lt;/a&gt; and get yourself switched over, today!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4110180-4121218058413204699?l=tapestryjava.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TapestryCentral/~4/stulP-4bay8" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 24 Jan 2012 12:32:18 CST</pubDate>
      <guid isPermaLink="true">tag:blogger.com,1999:blog-4110180.post-4121218058413204699</guid>
      <dc:creator>Howard Lewis Ship</dc:creator>
    </item>
    <item>
      <title>Now rotating: Baristas Fashionistas Mother Teresas by The Nim Nims [Flickr]</title>
      <link>http://therichwebexperience.com/blog/aaron_gustafson/2012/01/now_rotating_baristas_fashionistas_mother_teresas_by_the_nim_nims_flickr_</link>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/people/aarongustafson/"&gt;Aaron Gustafson&lt;/a&gt; posted a photo:&lt;/p&gt;
	
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/aarongustafson/6752926923/" title="Now rotating: Baristas Fashionistas Mother Teresas by The Nim Nims"&gt;&lt;img src="http://farm8.staticflickr.com/7162/6752926923_93e08fe912_m.jpg" width="240" height="240" alt="Now rotating: Baristas Fashionistas Mother Teresas by The Nim Nims" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EasyReader/~4/xAr4OIXI_tE" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 23 Jan 2012 21:54:00 CST</pubDate>
      <guid isPermaLink="true">tag:flickr.com,2005:/photo/6752926923</guid>
      <dc:creator>Aaron Gustafson</dc:creator>
    </item>
    <item>
      <title>80s’ [Flickr]</title>
      <link>http://therichwebexperience.com/blog/aaron_gustafson/2012/01/80s__flickr_</link>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/people/aarongustafson/"&gt;Aaron Gustafson&lt;/a&gt; posted a photo:&lt;/p&gt;
	
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/aarongustafson/6751836243/" title="80s’"&gt;&lt;img src="http://farm8.staticflickr.com/7031/6751836243_833472b2e1_m.jpg" width="240" height="240" alt="80s’" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EasyReader/~4/CaGVvymH3-0" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 23 Jan 2012 17:43:00 CST</pubDate>
      <guid isPermaLink="true">tag:flickr.com,2005:/photo/6751836243</guid>
      <dc:creator>Aaron Gustafson</dc:creator>
    </item>
    <item>
      <title>Speaking in Philly this Week</title>
      <link>http://therichwebexperience.com/blog/terry_ryan/2012/01/speaking_in_philly_this_week</link>
      <description>&lt;p style="clear: both"&gt;&lt;img style="float: right; margin: 0 0 10px 10px" src="http://maps.google.com/maps/api/staticmap?center=39.953633,-75.198806&amp;amp;zoom=16&amp;amp;markers=3800+Walnut Street Philadelphia, Pa &amp;amp;size=300x300&amp;amp;sensor=false" alt="" width="300" height="300" /&gt;I'll be speaking in my hometown this week. I'll be presenting at the &lt;a href="http://www.panma.org/organization/news/2012/01/jan-26th-event-adobe-and-html5-the-next-generation-of-tools"&gt;Philadelphia Area New Media Association (PANMA) meeting for January&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Topics&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;jQuery Mobile&lt;/li&gt;
&lt;li&gt;PhoneGap&lt;/li&gt;
&lt;li&gt;Typekit&lt;/li&gt;
&lt;li&gt;Edge&lt;/li&gt;
&lt;li&gt;CSS Shaders&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;:&lt;/p&gt;
&lt;blockquote style="clear: both"&gt;
&lt;p style="clear: both"&gt;Adobe and HTML5&lt;/p&gt;
&lt;p style="clear: both"&gt;In the past few months, there has been a number of new tools and new services from Adobe for HTML5. Some of these tools, like PhoneGap Build and jQuery contributions are aimed at developers and some, such as Edge, are more focused on designers. Adobe Evangelist Terry Ryan will give an overview and demos of these and other tools.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p style="clear: both"&gt;The meeting is on &lt;strong&gt;Thursday, January 26th at 6:00PM&lt;/strong&gt;. It will be at the &lt;strong&gt;Huntsman Building at 38th and Walnut&lt;/strong&gt; on Penn's Campus. &lt;/p&gt;</description>
      <pubDate>Mon, 23 Jan 2012 12:57:00 CST</pubDate>
      <guid isPermaLink="true">http://www.terrenceryan.com/blog/post.cfm/speaking-in-philly-this-week</guid>
      <dc:creator>Terry Ryan</dc:creator>
    </item>
    <item>
      <title>Venn Diagram entirely in CSS</title>
      <link>http://therichwebexperience.com/blog/terry_ryan/2012/01/venn_diagram_entirely_in_css</link>
      <description>&lt;p&gt;&lt;img style="float: right;" src="/blog/assets/content/venn.png" alt="" width="350" height="250" /&gt;A friend of mine alerted me this weekend to just how much I have a weird fascination with Venn diagrams. I decided to roll with it. So yeah, I have an irrational love of Venn diagrams. But that begs the question, can I make a Venn diagram with just CSS?&lt;/p&gt;
&lt;p&gt;I found a couple of examples out there:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://uxthing.posterous.com/dusting-off-my-html-skills-css-venn-diagram"&gt;Dusting off front-end skills: CSS Venn Diagram&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.w3human.me/05/2011/html-and-css-venn-diagram/"&gt;HTML And CSS Venn Diagram&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But I felt like they had a bit too much fluff in the HTML markup. Not that there is anything technically wrong with their implementations. I prefer complexity in my CSS and not in my HTML. It's probably just a subjective thing, but I do. &lt;/p&gt;
&lt;p&gt;So how do you do it?&lt;/p&gt;
&lt;p&gt;First you create 3 divs. 1 for each Venn circle, and 1 for the overlap section. Each div contains a p with content in it.&lt;/p&gt;
&lt;p&gt;
&lt;script src="https://gist.github.com/1664396.js?file=htmlportion.html"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;Then you go to style each of the circles. Give them matching heights and widths, and a border radius of half of the height. This creates the circle. Then give each one an opacity below 1. This will ensure that when they overlap they will form a new color. &lt;/p&gt;
&lt;p&gt;
&lt;script src="https://gist.github.com/1664396.js?file=circles.css"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;I then created two rules based on the nth child css selector to color each of the circles. I also padded to ensure that there would be a space to write in the overlap section. &lt;/p&gt;
&lt;p&gt;
&lt;script src="https://gist.github.com/1664396.js?file=eachcircle.css"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;Finally I styled the overlap section using relative positioning and pulled it back towards the center. &lt;/p&gt;
&lt;p&gt;
&lt;script src="https://gist.github.com/1664396.js?file=overlap.css"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;The real trick is to watch the pixel counts because a couple are directly related.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;To create a circle: &lt;/strong&gt;&lt;/p&gt;
&lt;ul style="clear: both"&gt;
&lt;li&gt;width must equal height &lt;/li&gt;
&lt;li&gt;border radius must equal 50% of width.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;To overlap circles:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Circle 2 must have negative &lt;em&gt;x&lt;/em&gt; left margin&lt;/li&gt;
&lt;li&gt;(Or Circle 1 must have negative &lt;em&gt;x&lt;/em&gt; right margin)&lt;/li&gt;
&lt;li&gt;Each circle must have &lt;em&gt;x&lt;/em&gt; padding-left or &lt;em&gt;x&lt;/em&gt; padding-right to ensure its text doesn't spill over borders &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It looks like &lt;a href="http://terrenceryan.com/examples/venn/"&gt;the example&lt;/a&gt; works across modern browsers, including IE 9, but not previous versions. &lt;/p&gt;</description>
      <pubDate>Mon, 23 Jan 2012 11:56:00 CST</pubDate>
      <guid isPermaLink="true">http://www.terrenceryan.com/blog/post.cfm/venn-diagram-entirely-in-css</guid>
      <dc:creator>Terry Ryan</dc:creator>
    </item>
    <item>
      <title>Columbus Circle grid [Flickr]</title>
      <link>http://therichwebexperience.com/blog/aaron_gustafson/2012/01/columbus_circle_grid_flickr_</link>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/people/aarongustafson/"&gt;Aaron Gustafson&lt;/a&gt; posted a photo:&lt;/p&gt;
	
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/aarongustafson/6722711593/" title="Columbus Circle grid"&gt;&lt;img src="http://farm8.staticflickr.com/7155/6722711593_281f1d1427_m.jpg" width="240" height="240" alt="Columbus Circle grid" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EasyReader/~4/N8ZrwQF8Zw4" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 18 Jan 2012 17:33:00 CST</pubDate>
      <guid isPermaLink="true">tag:flickr.com,2005:/photo/6722711593</guid>
      <dc:creator>Aaron Gustafson</dc:creator>
    </item>
    <item>
      <title>Lost [Flickr]</title>
      <link>http://therichwebexperience.com/blog/aaron_gustafson/2012/01/lost_flickr_</link>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/people/aarongustafson/"&gt;Aaron Gustafson&lt;/a&gt; posted a photo:&lt;/p&gt;
	
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/aarongustafson/6721446759/" title="Lost"&gt;&lt;img src="http://farm8.staticflickr.com/7160/6721446759_c33529c7f5_m.jpg" width="240" height="240" alt="Lost" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EasyReader/~4/_PNTcidRSYc" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 18 Jan 2012 13:01:00 CST</pubDate>
      <guid isPermaLink="true">tag:flickr.com,2005:/photo/6721446759</guid>
      <dc:creator>Aaron Gustafson</dc:creator>
    </item>
    <item>
      <title>Explore the Future [Flickr]</title>
      <link>http://therichwebexperience.com/blog/aaron_gustafson/2012/01/explore_the_future_flickr_</link>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/people/aarongustafson/"&gt;Aaron Gustafson&lt;/a&gt; posted a photo:&lt;/p&gt;
	
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/aarongustafson/6720100925/" title="Explore the Future"&gt;&lt;img src="http://farm8.staticflickr.com/7023/6720100925_02c0da973e_m.jpg" width="240" height="240" alt="Explore the Future" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EasyReader/~4/LvmuNltkqsY" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 18 Jan 2012 07:59:00 CST</pubDate>
      <guid isPermaLink="true">tag:flickr.com,2005:/photo/6720100925</guid>
      <dc:creator>Aaron Gustafson</dc:creator>
    </item>
    <item>
      <title>Glowing red [Flickr]</title>
      <link>http://therichwebexperience.com/blog/aaron_gustafson/2012/01/glowing_red_flickr_</link>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/people/aarongustafson/"&gt;Aaron Gustafson&lt;/a&gt; posted a photo:&lt;/p&gt;
	
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/aarongustafson/6718106943/" title="Glowing red"&gt;&lt;img src="http://farm8.staticflickr.com/7167/6718106943_2a021f612a_m.jpg" width="240" height="240" alt="Glowing red" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EasyReader/~4/z2ZNb_xshDM" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 17 Jan 2012 21:32:00 CST</pubDate>
      <guid isPermaLink="true">tag:flickr.com,2005:/photo/6718106943</guid>
      <dc:creator>Aaron Gustafson</dc:creator>
    </item>
    <item>
      <title>Sparkly [Flickr]</title>
      <link>http://therichwebexperience.com/blog/aaron_gustafson/2012/01/sparkly_flickr_</link>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/people/aarongustafson/"&gt;Aaron Gustafson&lt;/a&gt; posted a photo:&lt;/p&gt;
	
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/aarongustafson/6716387509/" title="Sparkly"&gt;&lt;img src="http://farm8.staticflickr.com/7023/6716387509_43cc4761e8_m.jpg" width="240" height="240" alt="Sparkly" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EasyReader/~4/_3qhfrz4gPI" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 17 Jan 2012 15:09:00 CST</pubDate>
      <guid isPermaLink="true">tag:flickr.com,2005:/photo/6716387509</guid>
      <dc:creator>Aaron Gustafson</dc:creator>
    </item>
    <item>
      <title>One heckuva chandelier [Flickr]</title>
      <link>http://therichwebexperience.com/blog/aaron_gustafson/2012/01/one_heckuva_chandelier_flickr_</link>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/people/aarongustafson/"&gt;Aaron Gustafson&lt;/a&gt; posted a photo:&lt;/p&gt;
	
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/aarongustafson/6716356241/" title="One heckuva chandelier"&gt;&lt;img src="http://farm8.staticflickr.com/7022/6716356241_58bd2c036f_m.jpg" width="240" height="240" alt="One heckuva chandelier" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EasyReader/~4/AhZqMnaU9XM" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 17 Jan 2012 15:02:00 CST</pubDate>
      <guid isPermaLink="true">tag:flickr.com,2005:/photo/6716356241</guid>
      <dc:creator>Aaron Gustafson</dc:creator>
    </item>
    <item>
      <title>Speaking at Webvisions Next Week in NYC</title>
      <link>http://therichwebexperience.com/blog/terry_ryan/2012/01/speaking_at_webvisions_next_week_in_nyc</link>
      <description>&lt;p&gt;I was originally scheduled to help out my colleague &lt;a href="http://blog.kevinhoyt.com/"&gt;Kevin Hoyt&lt;/a&gt; as a TA. Turns out that there was a slight scheduling SNAFU and I'm taking a full slot. My &lt;a href="http://www.webvisionsevent.com/new-york/session/the-future-of-html5-motion-design/"&gt;topic&lt;/a&gt;: &lt;/p&gt;
&lt;blockquote style="clear: both"&gt;
&lt;p&gt;&lt;strong&gt;The Future of HTML5 Motion Design&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;HTML5 and CSS3 are hot, driven by an explosion of new, Internet connected devices. While they offer many new features that should allow you to do the types of things that you previously did in Flash, actually making it happen is really hard. Until now. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img style="float: right;" src="/blog/assets/content/punchy.gif" alt="" width="222" height="221" /&gt;If you weren't sure, I'll be talking about &lt;a href="http://labs.adobe.com/technologies/edge/"&gt;Adobe Edge&lt;/a&gt;, our HTML5 animation tool. It's currently in beta, and looking pretty cool. &lt;br /&gt;&lt;br /&gt;So if you're in NYC, and want to get some dirt on where Adobe is going with HTML animation or just to get close to some of the foremost experts on the web, you really got to check out &lt;a href="http://www.webvisionsevent.com/new-york/"&gt;Webvisions&lt;/a&gt;. &lt;/p&gt;</description>
      <pubDate>Fri, 13 Jan 2012 15:57:00 CST</pubDate>
      <guid isPermaLink="true">http://www.terrenceryan.com/blog/post.cfm/speaking-at-webvisions-next-week-in-nyc</guid>
      <dc:creator>Terry Ryan</dc:creator>
    </item>
  </channel>
</rss>


