<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Marty Haught</title>
    <link>http://martyhaught.com/rss/</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>My blog covering software design.</description>
    
    
        <item>
          <title>Yui4Rails leaving svn</title>
          <description>&lt;p&gt;I&amp;#8217;ve beaten my head up against the git-svn wall for hopefully the last time.  On the Yui4Rails plugin, I&amp;#8217;ve been enjoying using github and managing the constant sea of change from new &lt;span class=&quot;caps&quot;&gt;YUI&lt;/span&gt; library releases as well as enhancements from two of my projects as well as merging in changes from a couple others.  All of this I&amp;#8217;ve done on the git side of the house.  I struggled to do this efficiently with svn before and once my fellow programmers started to use git, I checked it out.&lt;/p&gt; &lt;p&gt;Now, I&amp;#8217;m hardly great with git.  I&amp;#8217;ve still much git fu to learn.  However, I have noticed how easier many things are to do in git, even with my limited knowledge and experience.  As most of you will know, I created the Yui4Rails project on Rubyforge as a svn repo.  Git wasn&amp;#8217;t an option on Rubyforge and I hadn&amp;#8217;t tried git out as yet.  So to allow me to use the ease of git I used git-svn to bridge the gap and for the most part it was good.  I&amp;#8217;ve only once before had a fairly challenging conflict and with some irc help, got through it.  However, tonight I ran into such a merge trainwreck that I again questioned why am I maintaining a svn repo when I don&amp;#8217;t use it?  No one else is contributing through svn and the last patch came via a pull request on github.  It&amp;#8217;s only causing more work for me and I don&amp;#8217;t need to do that.  I&amp;#8217;ve got so little extra time for Yui4Rails at the moment that anything that causes me to waste a couple hours of my free time better be worth it.&lt;/p&gt;


	&lt;p&gt;So I&amp;#8217;ve decided to kick the svn habit for Yui4Rails.  I&amp;#8217;ve just submitted a request to convert the svn repo to git on Rubyforge.  Given that everything else in Rails seems to be switching over to git, I&amp;#8217;m not going to resist it.  As I&amp;#8217;ve mentioned before, if you want the truly up-to-date version go to the &lt;a href=&quot;http://github.com/mghaught/yui4rails/tree/master&quot;&gt;github repo&lt;/a&gt;.  I will continue to maintain zip/tarballs of the plugin for each release on Rubyforge so that will remain.  Ciao svn!&lt;/p&gt;</description>
          <pubDate>Mon, 28 Jul 2008 22:05:00 GMT</pubDate>
          <guid>http://martyhaught.com/articles/2008/07/28/yui4rails-leaving-svn/</guid>
          <link>http://martyhaught.com/articles/2008/07/28/yui4rails-leaving-svn/</link>
        </item>
    
        <item>
          <title>Page Event Extension Updated</title>
          <description>&lt;p&gt;There have been a few things that have changed with Page Event extension recently in the &lt;a href=&quot;http://github.com/mghaught/radiant-page-event/tree/master&quot;&gt;github repo&lt;/a&gt;.  First, limited the calendar to showing only published events.  I added an upcoming and next tag for events.  I also moved from test:unit to rspecs.  I haven&amp;#8217;t completed the conversion but it&amp;#8217;s well underway.  Additionally, I added doc to all the tags so you can look up the details in the &amp;#8216;available tags&amp;#8217; reference in the admin ui.  Finally, I pulled some changes from Sean Santry&amp;#8217;s fork that adds a format option to the event:date and event:time tags.  Enjoy!&lt;/p&gt;</description>
          <pubDate>Sat, 26 Jul 2008 21:01:00 GMT</pubDate>
          <guid>http://martyhaught.com/articles/2008/07/26/page-event-extension-updated/</guid>
          <link>http://martyhaught.com/articles/2008/07/26/page-event-extension-updated/</link>
        </item>
    
        <item>
          <title>Yui4rails and YUI 2.5.2</title>
          <description>&lt;p&gt;I apologize for being so silent since RailsConf.  It&amp;#8217;s been quite busy for me at work and home.  I will see if I can get the next official release pushed to svn in the coming weeks.  I have not yet looked into the 2.5.2 &lt;span class=&quot;caps&quot;&gt;YUI&lt;/span&gt; release but will make sure it&amp;#8217;s part of the next release of Yui4Rails.  On a side note, I have updated the &lt;span class=&quot;caps&quot;&gt;README&lt;/span&gt; in the &lt;a href=&quot;http://github.com/mghaught/yui4rails/tree/master&quot;&gt;github repo&lt;/a&gt; to be more accurate.  If you have any comments or suggestions, please email me.&lt;/p&gt;</description>
          <pubDate>Sun, 22 Jun 2008 21:30:00 GMT</pubDate>
          <guid>http://martyhaught.com/articles/2008/06/22/yui4rails-and-yui-2-5-2/</guid>
          <link>http://martyhaught.com/articles/2008/06/22/yui4rails-and-yui-2-5-2/</link>
        </item>
    
        <item>
          <title>Yui4Rails at RailsConf</title>
          <description>&lt;p&gt;Just a quick note to anyone interested in Yui4Rails at RailsConf 2008.  I have scheduled a Birds of a Feather session for Yui4Rails on Friday night at 9pm.  You&amp;#8217;re all welcome to come hang out with us and talk about Yui4Rails and what we&amp;#8217;re up to in person.  Here&amp;#8217;s the entry with all the details:&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://en.oreilly.com/rails2008/public/schedule/detail/4529&quot;&gt;Yui4Rails &lt;span class=&quot;caps&quot;&gt;BOF&lt;/span&gt; Session&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Otherwise, I&amp;#8217;m getting ready to head out to RailsConf.  I&amp;#8217;ll be there Thursday afternoon.  If you want to meet up, please send me an email to coordinate.&lt;/p&gt;</description>
          <pubDate>Tue, 27 May 2008 17:27:00 GMT</pubDate>
          <guid>http://martyhaught.com/articles/2008/05/27/yui4rails-at-railsconf/</guid>
          <link>http://martyhaught.com/articles/2008/05/27/yui4rails-at-railsconf/</link>
        </item>
    
        <item>
          <title>Yui4Rails Component Tutorial</title>
          <description>&lt;h2&gt;Building &lt;span class=&quot;caps&quot;&gt;YUI&lt;/span&gt; components in Yui4Rails&lt;/h2&gt;


	&lt;p&gt;I&amp;#8217;m going to go over the process for adding a &lt;span class=&quot;caps&quot;&gt;YUI&lt;/span&gt; component into YUI4Rails.  The basic philosophy that I have been following is the end result should be a concise, easy to use api for the developer yet allow flexibility for the myriad options that the &lt;span class=&quot;caps&quot;&gt;YUI&lt;/span&gt; components offer.  Let&amp;#8217;s explore this approach with the latest widget that I&amp;#8217;ve added, the carousel.&lt;/p&gt;


	&lt;p&gt;Before we dive into the code, let&amp;#8217;s look at how the developer would use the carousel widget on one of his pages.&lt;/p&gt; &lt;h3&gt;Using the component&lt;/h3&gt;


	&lt;p&gt;1) Add the yui_includes call to the &lt;span class=&quot;caps&quot;&gt;HEAD&lt;/span&gt; section of your layout:&lt;/p&gt;


&lt;pre&gt;
&amp;lt;%= yui_includes :reset, :fonts %&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;In the above example, we&amp;#8217;ve decided that we also want the reset and fonts css components added to all pages that use this layout.  You can just call yui_includes with no arguments.&lt;/p&gt;


	&lt;p&gt;2) Add the yui_carousel call to the page&amp;#8217;s template:&lt;/p&gt;


&lt;pre&gt;
&amp;lt;% yui_carousel(&quot;featured_photos&quot;, @featured_photos, {:scrollInc =&amp;gt; 1, :navMargin =&amp;gt; 82, :numVisible =&amp;gt; 4}) do %&amp;gt;
    &amp;lt;div class=&quot;carousel-prev&quot;&amp;gt;
        &amp;lt;div id=&quot;prev_arrow&quot;&amp;gt;&amp;lt;span class=&quot;access&quot;&amp;gt;&amp;amp;#171; Left&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&quot;carousel-next&quot;&amp;gt;
        &amp;lt;div id=&quot;next_arrow&quot;&amp;gt;&amp;lt;span class=&quot;access&quot;&amp;gt;Right &amp;amp;#187;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;div class=&quot;carousel-clip-region&quot;&amp;gt;
            &amp;lt;ul class=&quot;carousel-list&quot;&amp;gt;
&amp;lt;%= render :partial =&amp;gt; '/photos/featured_photo', :collection =&amp;gt; @featured_photos %&amp;gt;
            &amp;lt;/ul&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;Here, we have identified a carousel, featured_photos, that will display a set of four images at once with a scrolling increment of one per click.  The first parameter is the id name of the carousel object that we want to use.  It is followed by the collection of photos that will populate the carousel list.  Next we set several options that differ from the component&amp;#8217;s defaults.  Finally, the yui_carousel method takes a block which contains the html that you wish to put inside the carousel.  Since the carousel control expects very specific html elements to work, I&amp;#8217;ve chosen to wrap it but allow the developer to tweak css and html specifics to meet their needs.&lt;/p&gt;


	&lt;p&gt;Those are the only two steps.  Let&amp;#8217;s look into what happens under the hood and follow the flow as a component author.&lt;/p&gt;


	&lt;h3&gt;Authoring a component&lt;/h3&gt;


	&lt;p&gt;1) Widget class&lt;/p&gt;


	&lt;p&gt;The first step for writing a component in Yui4Rails is to write a Widget class.  We&amp;#8217;ll look at /lib/yui4rails/widgets/carousel.rb as our example.&lt;/p&gt;


	&lt;p&gt;The intent of a widget class is to take in the required arguments as well as optional ones and output the required pieces of javascript and html that will be required to make the &lt;span class=&quot;caps&quot;&gt;YUI&lt;/span&gt; component work.&lt;/p&gt;


	&lt;p&gt;You start off placing the class into the appropriate module space, Yui4Rails::Widgets::Carousel.&lt;/p&gt;


&lt;pre&gt;
module Yui4Rails
    module Widgets
      class Carousel
        def initialize(carousel_id, collection, options = {})    
                @carousel_id = carousel_id
                @collection = collection
                @options = defaults.merge(options)
                @options[:size] = @collection.size
                render_head_script
        end
    ...
&lt;/pre&gt;

	&lt;p&gt;The class&amp;#8217;s initialize method requires the carousel_id, collection and a hash of options.  We merge the options with default values that are defined in the class as well as put the size of the collection into the options.  Finally we call the render_head_script method.&lt;/p&gt;


render_head_script is simply a method that contains the script output that will go into the head section of the page.  
&lt;pre&gt;
    def render_head_script
        Yui4Rails::AssetManager.manager.add_script &amp;lt;&amp;lt;-PAGE
        YAHOO.util.Event.addListener(window, &quot;load&quot;, function() 
        {
            new YAHOO.extension.Carousel(&quot;#{@carousel_id}&quot;, 
                {#{@options.keys.map{|key| optional_value(key)}.join(&quot;, &quot;)}}
            );
        });
                                                                                                PAGE
    end    
&lt;/pre&gt;

	&lt;p&gt;We leverage the Yui4Rails::AssetManager&amp;#8217;s add_script method to add our script content.  This will keep hold of all the head script until the layout is rendered which is handy as it allows us to construct many components before anything is outputted to the page.  Also of note here is that AssetManager is a singleton that is referenced through the class method manager.  The rest of the content here should be familiar to anyone using &lt;span class=&quot;caps&quot;&gt;YUI&lt;/span&gt; components on their own.&lt;/p&gt;


	&lt;p&gt;The only other methods in the class are private.  One is defaults which just contains all the default parameters that I, as a component author, have decided should be automatic in widget&amp;#8217;s constructor.&lt;/p&gt;


&lt;pre&gt;
    def defaults
        {
            :numVisible =&amp;gt; 3,
            :animationSpeed =&amp;gt; 0.5,
            :scrollInc =&amp;gt; 3,
            :navMargin =&amp;gt; 60,
            :prevElement =&amp;gt; &quot;prev_arrow&quot;,
            :nextElement =&amp;gt; &quot;next_arrow&quot;,
            :wrap =&amp;gt; true
        }
    end
&lt;/pre&gt;

	&lt;p&gt;One note here is that I&amp;#8217;ve decided that I want to make a app-wide override for these.  So that if you want to use the carousel multiple times on your site and that there are one or more options that you always set you can do it in one place instead of each time.&lt;/p&gt;


	&lt;p&gt;The other private method is optional_value which will either output the javascript parameters as a hash if they&amp;#8217;re present as a key and value in the options hash.&lt;/p&gt;


&lt;pre&gt;
    def optional_value(option, carousel_key = nil)
        carousel_key ||= option
        if @options.has_key?(option) &amp;#38;&amp;#38; !@options[option].nil? 
            %\#{carousel_key}: #{@options[option].is_a?(String) ? &quot;'#{@options[option]}'&quot; : @options[option] }\
        else
            &quot;&quot; 
        end    
    end
&lt;/pre&gt;

	&lt;p&gt;2) Asset Manager&lt;/p&gt;


	&lt;p&gt;The asset manager&amp;#8217;s role is to give a convenient and unified interface to indicating what &lt;span class=&quot;caps&quot;&gt;YUI&lt;/span&gt; resources you will need for your component.  Furthermore as we have seen, it gives a place to add custom script that will be outputted into the head section after template processing is complete.&lt;/p&gt;


	&lt;p&gt;The main thing you&amp;#8217;ll need to do here is to make sure the javascript and css includes are handled.  The current implementation is ultra simple and will be enhanced in the near future.  There are two methods that will look at to understand how to add to the asset manager as designed&lt;/p&gt;


&lt;pre&gt;
    def process_components            
        @yui_stylesheets = []
        @yui_javascript = []

        @components.flatten!

        @yui_stylesheets &amp;lt;&amp;lt; &quot;reset/reset-min&quot; if @components.include?(:reset)
        @yui_stylesheets &amp;lt;&amp;lt; &quot;fonts/fonts-min&quot; if @components.include?(:fonts)
        add_container_includes if @components.include?(:container)
        add_datatable_includes if @components.include?(:datatable)
        add_charts_includes if @components.include?(:charts)
        add_carousel_includes if @components.include?(:carousel)

        @stylesheets = @yui_stylesheets.uniq
        @javascripts = @yui_javascript.uniq
    end
&lt;/pre&gt;

	&lt;p&gt;Process components is where all the javascript files and css files are collected into unique arrays.  They are simple strings to the path of the resources as consumed by the stylesheet_link_tag and javascript_include_tag helpers.  The path &amp;#8221;/yui/&amp;#8221; will be prepended for all.  Thus for the reset css file you can see it adds the string &amp;#8220;reset/reset-min&amp;#8221; into the yui_stylesheets array.&lt;/p&gt;


	&lt;p&gt;Most likely you will need something like what carousel uses.  In this case I wrote a method, add_carousel_includes, to handle it for me.  If the :carousel is passed in, it will invoke this method.&lt;/p&gt;


&lt;pre&gt;
    def add_carousel_includes
        @yui_stylesheets &amp;lt;&amp;lt; &quot;carousel/assets/carousel&quot; 
        @yui_javascript &amp;lt;&amp;lt; &quot;yahoo-dom-event/yahoo-dom-event&quot; 
        @yui_javascript &amp;lt;&amp;lt; &quot;animation/animation-min&quot; 
        @yui_javascript &amp;lt;&amp;lt; &quot;container/container-min&quot; 
        @yui_javascript &amp;lt;&amp;lt; &quot;carousel/carousel_min&quot;    
    end
&lt;/pre&gt;

	&lt;p&gt;As you can see here I add in each css and js file needed into their respective arrays.  Since these arrays are uniq&amp;#8217;d later on we don&amp;#8217;t need to worry too much about duplication.&lt;/p&gt;


	&lt;p&gt;The eventual design will not require you to do anything in here.  You will simply pass the resource names (as symbols) in and it will determine dependencies and include them, in the most optimal way.  Thus for Drag n Drop you&amp;#8217;d be able to pass in :dragdrop.  This will be identical to what is defined in &lt;span class=&quot;caps&quot;&gt;YUI&lt;/span&gt; Loader as the &lt;span class=&quot;caps&quot;&gt;YUI&lt;/span&gt; module names.  It would then make sure these dependencies are there: yahoo-dom-event.js, dragdrop-min.js.  I will look to make sure it minifies and compresses based on site-wide preferences and such.&lt;/p&gt;


	&lt;p&gt;3) Helper method&lt;/p&gt;


	&lt;p&gt;The last important piece is writing a helper method to make it convenient for the developer to invoke.  In this case I&amp;#8217;ve added the carousel&amp;#8217;s method to /lib/yui4rails/helpers_extension.rb.&lt;/p&gt;


&lt;pre&gt;
    def yui_carousel(carousel_id, collection, options = {}, &amp;#38;block)
        asset_manager.add_components :carousel
        carousel = Yui4Rails::Widgets::Carousel.new(carousel_id, collection, options)

        concat(%{&amp;lt;div id=&quot;#{carousel_id}&quot; class=&quot;carousel-component&quot;&amp;gt;}, block.binding)
        yield block
        concat(&quot;&amp;lt;/div&amp;gt;&quot;, block.binding)            
    end
&lt;/pre&gt;

	&lt;p&gt;In this helper, you can see we take in the arguments that we first talked about.  The first order of business is it calls asset_manager.add_components with the key name that AssetManager&amp;#8217;s process_components is aware of.  There is another helper module, include_extension.rb, that provide a convenience method to get the AssetManager&amp;#8217;s instance via asset_manager.  We use it here but you don&amp;#8217;t have to.  Additionally, you could call add_components from the initialize method of the Widget class.&lt;/p&gt;


	&lt;p&gt;The next thing I do is construct the widget class passing through the parameters it needs.  One nice thing with helpers is you could provide multiple helpers that use the same widget class varying their parameters.  Finally, I output the required div as a wrapper around the block that they specified.&lt;/p&gt;


	&lt;p&gt;4) Testing&lt;/p&gt;


	&lt;p&gt;In reality, I wouldn&amp;#8217;t do testing as the last step in my workflow.  However, I wanted to mention it after you have seen the different parts and how they fit together.  Testing, or specs, in this plugin have not been as strong as I would have liked.  Part of that is it&amp;#8217;s challenging to test this sort of code.  Javascript is not something you can 100% test in a framework like Rails with any confidence.  Other scripts, browser differences and html will keep it from being so simple.  That said, you can test some things.  Let&amp;#8217;s look at /spec/models/carousel_spec.rb to see an example of what I&amp;#8217;ve done so far.&lt;/p&gt;


	&lt;p&gt;We&amp;#8217;ll only look briefly at the render_head_script describe block.&lt;/p&gt;


&lt;pre&gt;
    describe &quot;.render_head_script&quot; do
        before(:each) do
          @carousel = Yui4Rails::Widgets::Carousel.new(@carousel_id, @collection)
        end

        it &quot;should register the code as an anonymous function on the page load event&quot; do
            @carousel.render_head_script.should match(/YAHOO\.util\.Event\.addListener\(window, &quot;load&quot;, function\(\)/)
        end

      it &quot;should render a YAHOO.extension.Carousel with our carousel_id&quot; do
        @carousel.render_head_script.should match(/new YAHOO\.extension\.Carousel\(&quot;#{@carousel_id}&quot;,/)
      end

        it &quot;should set the collection size into the size option&quot; do
            @carousel.render_head_script.should match(/size: #{@collection.size},/)
        end

        it &quot;should include default options&quot; do
            @carousel.render_head_script.should match(/numVisible: 3,/)
        end
    ...
&lt;/pre&gt;

	&lt;p&gt;You can see I&amp;#8217;m listing several specifications that I expect for the output to be valid.  I use regex matches to confirm parts of the script are there.  Clearly, this will not guarantee that the script is valid javascript but it will catch is major, important pieces are missing and that&amp;#8217;s good enough for me here.  I would suggest you take a similar approach.&lt;/p&gt;


	&lt;p&gt;That is essentially it for the steps you will need to take as a component author.  As this project has grown organically out of &lt;span class=&quot;caps&quot;&gt;YUI&lt;/span&gt; integration that I&amp;#8217;ve used on a couple of my projects, it&amp;#8217;s likely that we&amp;#8217;ll need to enhance things as we go forward.  The AssetManager is a great example.&lt;/p&gt;


	&lt;p&gt;One last thing to note on AssetManager.  There is a class method called reset that will nil out the class instance of the manager.  This is automatically prepended to your before filters so you never have to worry about stale AssetManager state biting you.  The main motivator for this behavior is to allow the AssetManager instance to be available to any object that wishes to call it whether it be a template helper method or isolated Yui4Rails class that has no reference to the template or its variables.&lt;/p&gt;


	&lt;p&gt;Hopefully, this walk through will give you more confidence on writing components. Go forth and add your favorite components as you will.&lt;/p&gt;</description>
          <pubDate>Fri, 23 May 2008 19:19:00 GMT</pubDate>
          <guid>http://martyhaught.com/articles/2008/05/23/yui4rails-component-tutorial/</guid>
          <link>http://martyhaught.com/articles/2008/05/23/yui4rails-component-tutorial/</link>
        </item>
    
        <item>
          <title>Yui4Rails trunk updates</title>
          <description>&lt;p&gt;I&amp;#8217;ve just pushed up my latest changes for Yui4Rails to the subversion trunk from my git repository.  There have been some major changes under the hood and it will break if you don&amp;#8217;t make a simple code change and you get the latest from the trunk.  The zip and tarball versions, found on Rubyforge, are not affected by these yet.  We&amp;#8217;ll look for more testing and some hardening before we roll this out as a new release.&lt;/p&gt; &lt;p&gt;So how do you start to use the latest changes, you ask?  Well, go ahead and pull the latest from the subversion trunk::&lt;/p&gt;


&lt;pre&gt;svn://rubyforge.org/var/svn/yui4rails/trunk/&lt;/pre&gt;

	&lt;p&gt;Two primary changes are needed to make it work, &lt;span class=&quot;caps&quot;&gt;AFAIK&lt;/span&gt;.  First, you will need to add one line in the head section of your layout/template:&lt;/p&gt;


&lt;code&gt;
&amp;lt;%= yui_includes %&amp;gt;
&lt;/code&gt;

	&lt;p&gt;I would put it after any other javascript includes such as the Rails defaults.&lt;/p&gt;


	&lt;p&gt;Second, you most likely have include_yui includes that need to be updated such as this:&lt;/p&gt;


&lt;code&gt;
&amp;lt;%= include_yui :datatable, :charts %&amp;gt;
&lt;/code&gt;

	&lt;p&gt;These no longer need to output anything so you can change them to this:&lt;/p&gt;


&lt;code&gt;
&amp;lt;% include_yui :datatable, :charts %&amp;gt; 
&lt;/code&gt;

	&lt;p&gt;Those changes should get you working on the trunk again.  I will be posting a more complete tutorial on how to use the new features as well as approaches for developing new components in the plugin.  For now I wanted to get this out there so you can start playing with it, without needing git.&lt;/p&gt;</description>
          <pubDate>Tue, 13 May 2008 22:09:00 GMT</pubDate>
          <guid>http://martyhaught.com/articles/2008/05/13/yui4rails-trunk-updates/</guid>
          <link>http://martyhaught.com/articles/2008/05/13/yui4rails-trunk-updates/</link>
        </item>
    
        <item>
          <title>Page Event Extension Released</title>
          <description>&lt;p&gt;The event extension (for &lt;a href=&quot;http://radiantcms.org/&quot;&gt;RadiantCMS&lt;/a&gt;) that I have been talking about and working on for nearly half a year has finally been released.  You can see it in action on &lt;a href=&quot;http://boulderruby.org/event-calendar/&quot;&gt;Boulder Ruby&amp;#8217;s calendar page&lt;/a&gt;.  This extension has been on my list ever since I created the Boulder Ruby site in Radiant.  I will also be using this on the website for my children&amp;#8217;s school.  Loren Johnson already had done an event calendar extension but it was tied to an iCal feed and this was not how I wanted to manage the events.  So this event extension is all about tying one of your pages to some date and time.&lt;/p&gt; &lt;p&gt;I currently have the extension hosted on &lt;a href=&quot;http://github.com/mghaught/radiant-page-event/tree/master&quot;&gt;github&lt;/a&gt;.  Being the first release it should be considered alpha.  Over the next month I will be fixing any bugs and improving the UI.  The &lt;span class=&quot;caps&quot;&gt;README&lt;/span&gt; in the project has detailed notes on installation and usage but I&amp;#8217;ll outline how to install and use it briefly.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;NOTE&lt;/span&gt;: The extension is tested against 6.6 though it might work for some of the older 6 releases.  I have no intention of adding support for any release prior to 6.6.&lt;/p&gt;


	&lt;p&gt;You&amp;#8217;ll need both the &lt;a href=&quot;http://wiki.radiantcms.org/Thirdparty_Extensions&quot;&gt;Shards&lt;/a&gt; extension and the &lt;a href=&quot;http://code.google.com/p/calendardateselect/&quot;&gt;Calendar Date Select&lt;/a&gt; plugin before you can use Page Event.&lt;/p&gt;


	&lt;p&gt;You have two options for installing the extension:&lt;/p&gt;


	&lt;p&gt;1) Use git to clone the extension&lt;/p&gt;


&lt;code&gt;
git clone git://github.com/mghaught/radiant-page-event.git vendor/extensions/page_event
&lt;/code&gt;

	&lt;p&gt;2) Click the download button on Github to get a tarball of the extension.  At that point just expand the tarball into a vendor/extensions/page_event directory of your Radiant application.&lt;/p&gt;


	&lt;p&gt;Once you have the code installed you&amp;#8217;ll need to run the migrations and update commands.  Here&amp;#8217;s an example of those commands for the production env:&lt;/p&gt;


&lt;pre&gt;
  rake production radiant:extensions:page_event:migrate
  rake radiant:extensions:page_event:update
&lt;/pre&gt;

	&lt;p&gt;After a restart of your server you&amp;#8217;ll be ready to rock, event-style.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;The most visible feature of the extension is the monthly calendar which will display all events for the current month.  You can get this by using the &lt;code&gt;&amp;lt;r : calendar /&amp;gt; &lt;/code&gt; tag on whatever page you want.  It currently takes no options so it&amp;#8217;s stuck displaying a single month defaulting to the current month.  It does include next and previous month navigation.  It also displays the title of the page (with an event) that is a url to that page as well as the time.  I&amp;#8217;m sure eventually I&amp;#8217;ll expose more flexibility on this.&lt;/p&gt;


	&lt;p&gt;Along with the main calendar tag there are two event specific tags for displaying formatted date and time strings:&lt;/p&gt;


&lt;pre&gt;
  &amp;lt;r : event:date /&amp;gt;
  &amp;lt;r : event:time /&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;On the admin side, you&amp;#8217;ll notice that all pages now have an event date field with calendar select widget next to it.  This is how you set the date and time for your event.  If it&amp;#8217;s blank, the page has no event.  You do need to save the page to have it take effect.  You&amp;#8217;ll also get a new tab next to pages called Page Event.  There you can view a month&amp;#8217;s view of all events in your pages.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;What&amp;#8217;s Next&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;I have a short road map for upcoming features and enhancements.  First, I plan to get more use out of the extension on two sites of mine.  Up until now it&amp;#8217;s just been in development mode on my laptop.  I&amp;#8217;ve already noticed something tonight that will need attention.  Status is ignored in the calendar tag.  This means that hidden or draft events will show links in the calendar.  I&amp;#8217;ll change that to only display published events in the calendar.  Second, I plan to do some refactoring and making the page event tab more attractive.  It&amp;#8217;s functional but won&amp;#8217;t win any UI awards. :)  Further down the road, I&amp;#8217;ll be extracting the event date concept into its own model so you can create a start and end time to your event and assign it to multiple pages.  I&amp;#8217;ll also be interested in getting any feedback from others who might find this extension useful.&lt;/p&gt;


	&lt;p&gt;Feel free to watch or fork the project on github.  You can also email me or the Radiant list to discuss things about the extension.  Enjoy!&lt;/p&gt;</description>
          <pubDate>Sat, 03 May 2008 22:46:00 GMT</pubDate>
          <guid>http://martyhaught.com/articles/2008/05/03/page-event-extension-released/</guid>
          <link>http://martyhaught.com/articles/2008/05/03/page-event-extension-released/</link>
        </item>
    
        <item>
          <title>Upgrading Rubygems</title>
          <description>&lt;p&gt;This week I&amp;#8217;ve been spending much of my free time getting the release of my new Radiant extension wrapped up.  I&amp;#8217;m in the final stages of that right now so expect a post soon on those details.  So as part of this process I wanted to install the new extension on an external facing Radiant system, such as &lt;a href=&quot;http://boulderruby.org&quot;&gt;Boulder Ruby&lt;/a&gt;.  I&amp;#8217;ll reference it so people can see it in action.  In order to do this I need to upgrade several things.  First, I need to upgrade BoulderRuby to Radiant 6.6.  Radiant 6.6 is built on Rails 2.0 and also needs the newer version of Rubygems.  No problem, right?  Well it turned out not to be so!&lt;/p&gt; &lt;p&gt;So I tried to simply update the Radiant gem.  I tried multiple times but it hung on me.  More specifically it got to this line and just stayed there, forever (well, until I killed it).&lt;/p&gt;


&lt;pre&gt;
Bulk updating Gem source index for: http://gems.rubyforge.org/
&lt;/pre&gt;

	&lt;p&gt;Usually, it might take 5-15 seconds or so for this line on my development system.  I wasn&amp;#8217;t sure what was happening so I decided to skip the gem install and just manually bring up a tarball of my local BoulderRuby radiant upgrade.  Fine except I could run rake as it needed a newer version of Rubygems.  Updating Rubygems also hung on the same command.  wtf?!?&lt;/p&gt;


	&lt;p&gt;I then manually upgrade Rubygems as I wanted to be on the newest release after going through all the trouble of updating my system.  Then moved on to upgrading Rails which Radiant needs.  Then Rails was hanging on the bulk updating line.  By this point Slicehost is emailing me telling my server has been going heavy into swap.  After some googling it appears that my issue may be the 256 MB Ram limit my meager slice has.  Yikes!  I was able to install and update gems before, what&amp;#8217;s the deal now?&lt;/p&gt;


	&lt;p&gt;So I got around this by manually pulling down the gem files and installing with this command:&lt;/p&gt;


&lt;code&gt;
sudo gem install --ignore-dependencies --local activeresource-2.0.2.gem
&lt;/code&gt;

	&lt;p&gt;It took me several tries to get to this workable solution.  Rubygems doc doesn&amp;#8217;t really talk about how to use all the options available and several different combos still got stuck on the bulk updating line.  I&amp;#8217;m guessing that upgrading my slice&amp;#8217;s memory to 512 might make the difference but that just seems wrong.&lt;/p&gt;</description>
          <pubDate>Fri, 02 May 2008 17:23:00 GMT</pubDate>
          <guid>http://martyhaught.com/articles/2008/05/02/upgrading-rubygems/</guid>
          <link>http://martyhaught.com/articles/2008/05/02/upgrading-rubygems/</link>
        </item>
    
        <item>
          <title>YUI4Rails release 0.1.1</title>
          <description>&lt;p&gt;I&amp;#8217;ve just posted the newest release of YUI4Rails, &lt;a href=&quot;http://rubyforge.org/projects/yui4rails/&quot;&gt;0.1.1&lt;/a&gt;.  I&amp;#8217;ve upgraded the plugin to &lt;span class=&quot;caps&quot;&gt;YUI 2&lt;/span&gt;.5.1 and have applied Bryan Donovan&amp;#8217;s datatable patch.  Several of you have contacted me on how to take things forward.  In effort to make things a bit easier I&amp;#8217;ve made a git repository of the plugin that is cloned off the RubyForge svn repo.  You can find it here: &lt;a href=&quot;http://github.com/mghaught/yui4rails/tree/master&quot;&gt;http://github.com/mghaught/yui4rails/tree/master&lt;/a&gt;&lt;/p&gt; &lt;p&gt;We&amp;#8217;ve got some new components that we&amp;#8217;ve been developing lately.  Carousel, lightbox and tooltip are close to being ready.  One thing that has come up from this is that we&amp;#8217;ve got some limitations with the current approach of including dependencies.  I&amp;#8217;m working on a new prototype that would ease this pain and output much nicer html/script tags.  I&amp;#8217;ll be pushing it to the github repository either tonight or this weekend.  It will be in its own branch for the time being.&lt;/p&gt;


	&lt;p&gt;The basic idea is that you would have one helper call in the head section of your layout.  You could declare components that all pages would need such as reset or fonts.  Then in each individual template you can invoke the widget helpers as needed.  They would in turn call an AssetManager class to indicate what dependencies they have on &lt;span class=&quot;caps&quot;&gt;YUI&lt;/span&gt; assets.  Additionally, javascript code that belongs in the head section will be outputted there, even though you are invoking it throughout your templates or partials.  The end result should be cleaner html and javascript with less hassle calling helper methods.&lt;/p&gt;


	&lt;p&gt;I have several other things on the horizon for the plugin.  First, several other developers have contacted me about contributing to the plugin so look for those additions in the coming weeks on the github repository.  As we get closer to a stable release we&amp;#8217;ll push up to the Rubyforge svn repo and post new release files.  Part of this process will involve more discussion on YUI4Rails&amp;#8217; mailing list on design philosophies so we can keep a cohesive plugin.  I welcome your comments and suggestions so we can build the best possible plugin.  Second, we&amp;#8217;re going to start working on improving documentation, tutorials and an official YUI4Rails website with access to all of it. It&amp;#8217;s time to make this plugin more user-friendly.  The other important thing is to have this plugin well tested.  While the nature of js based widgets makes testing incredibly difficult, I think we can provide some test coverage for how our helpers operate.  I&amp;#8217;ll try to expand on this in another email/blog post in the future.  So enjoy this new release and don&amp;#8217;t be afraid to join the mailing list or fork the github repo.&lt;/p&gt;</description>
          <pubDate>Fri, 18 Apr 2008 21:16:31 GMT</pubDate>
          <guid>http://martyhaught.com/articles/2008/04/18/yui4rails-release-0-1-1/</guid>
          <link>http://martyhaught.com/articles/2008/04/18/yui4rails-release-0-1-1/</link>
        </item>
    
        <item>
          <title>MountainWest RubyConf 2008 Reflections</title>
          <description>&lt;p&gt;It&amp;#8217;s been almost a week since the MountainWest RubyConf 2008.  I had a great time there and if I hadn&amp;#8217;t been under the weather with a sore throat I would have had an awesome time.  The talks were some of the best I&amp;#8217;ve seen, especially for a conference only costing $100 for two days. I was going to post this earlier but I wanted to wait for some of the talks to be available via video.&lt;/p&gt; &lt;p&gt;So what were the highlights?  First, there was several cameos of Darth Vader and his colorful sombrero.  Then Rick Astley decided he should make several appearances.  You can catch them yourselves in the &lt;a href=&quot;http://mtnwestrubyconf2008.confreaks.com/index.html&quot;&gt;videos of the presentations&lt;/a&gt;.  Not many are up at this point but they&amp;#8217;ll get there eventually.&lt;/p&gt;


	&lt;p&gt;Evan Phoenix got things started with his &lt;a href=&quot;http://mtnwestrubyconf2008.confreaks.com/01phoenix.html&quot;&gt;overview on Rubinius and the community&lt;/a&gt;.  This was a cool talk and if nothing else presented some interesting ideas on how to organize an open source community around a project.  It made me want to dive right into the Rubinius code and submit some patches!  Ezra&amp;#8217;s &lt;a href=&quot;http://mtnwestrubyconf2008.confreaks.com/02zygmuntowicz.html&quot;&gt;talk&lt;/a&gt; followed and covered Merb.  I&amp;#8217;ve been pondering using Merb in several cases and I was impressed to see how easy it could be to port some of our services to it (from Rails).&lt;/p&gt;


	&lt;p&gt;Now probably the coolest and most entertaining talk that totally came out of the blue was Giles &lt;a href=&quot;http://mtnwestrubyconf2008.confreaks.com/03bowkett.html&quot;&gt;talk on code generation&lt;/a&gt;.  I was blown away.  I definitely want to use Rubinius and Ruby2Ruby to do some cool jedi tricks now.  Giles comments on the the self image of the Lisp community was just hilarious!  If you only watch one video from this conference check this one out.&lt;/p&gt;


	&lt;p&gt;Several topics seem to run deep through the talks.  Metaprogramming and more of an understanding of the dynamic nature of Ruby was explored several times.  Patrick Farley&amp;#8217;s talk on Ruby Internals was one such example that was very illuminating.  On an interesting side note, I was reading &lt;a href=&quot;http://jsdesignpatterns.com/&quot;&gt;Pro JavaScript Design Patterns&lt;/a&gt; by Harmes and Diaz on the the flight to and from the conference.  The first several chapters of that book also cover the dynamic nature and internals of JavaScript and reminded me very much of Patrick&amp;#8217;s talk.  Exploring the prototype chain of a JavaScript object and how functions resolve based on how you construct/set those parent references.  Very cool stuff indeed.&lt;/p&gt;


	&lt;p&gt;Another topic of interest was DSLs (which seemed to get mentioned in the metaprogramming talks too). Joe O&amp;#8217;Brien&amp;#8217;s talk focused on DSLs and I found enjoyable.  Git was also mentioned a lot and it felt like a git lovefest.  After seeing how people are using it, I now get it (ha ha).  I was going to use git anyway but now I&amp;#8217;m very excited about it.  I&amp;#8217;ll be converting my personal projects to use it now.  I&amp;#8217;m also tickled to see the git-svn library to allow me to use git with a subversion repo.  Anyway, enough on that.&lt;/p&gt;


	&lt;p&gt;The other thing that I found interesting was a constant, but subtle, anti-rails sentiment.  Don&amp;#8217;t get me wrong, I think everyone&amp;#8217;s appreciative of what Rails did and how many great ideas are baked in there.  However, it seemed that people are recognizing that there are some alternatives out there that are superior.  Sequel and DataMapper were both mentioned as alternatives to ActiveRecord.  Merb and it&amp;#8217;s focused, smaller footprint compared to Rails.  I&amp;#8217;m not going out and dumping all my Rails apps but I&amp;#8217;m glad to see the Ruby ecosystem maturing with other alternatives that are still going and ripe with enthusiasm.&lt;/p&gt;


	&lt;p&gt;I think the other 160 people that attended also had a great time.  What a bargain it was.  I&amp;#8217;m starting to think that regional ruby conferences are where it&amp;#8217;s at.  I&amp;#8217;ll be attending RailsConf 2008 but I&amp;#8217;m not quite as excited.  It may simply be too big now, too corporate.  We&amp;#8217;ll see.  At least most of my friends in the community will be there.  RubyConf is probably still the best conference but I think if you haven&amp;#8217;t considered the regional Ruby conferences you might want to look into one close to you.  There are many of them now.  Oh well, enough on all that.  It&amp;#8217;s late and I have a Radiant extension that needs some finishing touches.&lt;/p&gt;</description>
          <pubDate>Wed, 02 Apr 2008 22:20:37 GMT</pubDate>
          <guid>http://martyhaught.com/articles/2008/04/02/mountainwest-rubyconf-2008-reflections/</guid>
          <link>http://martyhaught.com/articles/2008/04/02/mountainwest-rubyconf-2008-reflections/</link>
        </item>
    
    
  </channel>
</rss>

