<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>David Parker - software and web development</title>
	
	<link>http://davidwparker.com</link>
	<description>software development, web design, and programming languages - ruby, rails, merb, jquery, javascript, erlang, and more</description>
	<pubDate>Thu, 11 Dec 2008 03:40:52 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/davidwparker" type="application/rss+xml" /><item>
		<title>Dynamic, Search-based RSS feeds</title>
		<link>http://feeds.feedburner.com/~r/davidwparker/~3/481243060/</link>
		<comments>http://davidwparker.com/2008/12/10/dynamic-search-based-rss-feeds/#comments</comments>
		<pubDate>Thu, 11 Dec 2008 03:33:39 +0000</pubDate>
		<dc:creator>David Parker</dc:creator>
		
		<category><![CDATA[None]]></category>

		<category><![CDATA[programming]]></category>

		<category><![CDATA[rails]]></category>

		<category><![CDATA[ruby]]></category>

		<category><![CDATA[tutorials]]></category>

		<category><![CDATA[web]]></category>

		<category><![CDATA[rss]]></category>

		<category><![CDATA[search]]></category>

		<guid isPermaLink="false">http://davidwparker.com/?p=84</guid>
		<description><![CDATA[For the current application I am working on, I needed the ability to generate RSS feeds on the fly.  Users have the ability to search for a lot of different information, and I needed to provide them with a way to save that search via an RSS feed.  To see how I went [...]]]></description>
			<content:encoded><![CDATA[<p>For the current application I am working on, I needed the ability to generate RSS feeds on the fly.  Users have the ability to search for a lot of different information, and I needed to provide them with a way to save that search via an RSS feed.  To see how I went about performing basic search, see <a href="http://davidwparker.com/2008/09/27/simple-multi-form-field-search-with-thinking-sphinx/">here</a>.</p>
<p>In my controller, I started by adding the ability to respond_to rss:</p>
<pre><code>
# GET /search
def search
  @models = Model.search_page params

  respond_to do |format|
    format.html
    format.rss { render :layout => false }
  end
end
</code></pre>
<p>Next, in my routes.rb file, I added a specific route for the dynamic search.</p>
<pre><code>
map.search_rss  '/search.rss',    :controller => 'models', :action => 'search', :format => 'rss'
</code></pre>
<p>This provided me with the method search_rss_path, which I was able to use in my view.  I attempted to use the route that I already had:</p>
<pre><code>
map.search '/search', :controller => 'search', :action => 'search'
</code></pre>
<p>With something along the lines of search_path(params, :format => &#8216;rss&#8217;), and that ended up being a very bad thing.  This was a bit ago, and I can&#8217;t recall at the moment why that wasn&#8217;t working, but I do recall that it just ended up being easier and nicer to just add one more route in my routes.rb file.</p>
<p>Continuing on, in my search.html.haml file, I have both a direct link and the auto_discovery link for the search generated RSS:</p>
<pre><code>
= link_to("RSS for this Search", search_rss_path(params))
- content_for(:extra_header) do
  = auto_discovery_link_tag(:rss, {:controller => 'models' , :action => 'search', :format => 'rss', :params => params}, {:title => 'RSS for Search Result Model Listings'})
</code></pre>
<p>The content_for :extra header is just an &#8220;extra header&#8221; area in my application.html.haml file:</p>
<pre><code>
= yield(:extra_header)
</code></pre>
<p>Finally, don&#8217;t forget to include the search.rss.builder file in your view folder:</p>
<pre><code>
xml.instruct! :xml, :version=>"1.0"

xml.rss "version" => "2.0" do

  xml.channel do

    xml.title "Search results"

    xml.link search_rss_path(params)

    xml.description("Description here")

    xml.language 'en-us'
    unless @models.empty?
      model = @models.first
      xml.lastBuildDate model.posted_at_rss
    end

    for model in @models

      xml.item do

        xml.title h(model.title)

        xml.description h(model.description)

        xml.pubDate model.posted_at_rss

        xml.author "some author"
        xml.link model_url(model)

        xml.guid model_url(model)

      end

    end

  end

end
</code></pre>
<p>All-in-all, it ended up being very easy to implement dynamic, search-based RSS feeds.</p>
]]></content:encoded>
			<wfw:commentRss>http://davidwparker.com/2008/12/10/dynamic-search-based-rss-feeds/feed/</wfw:commentRss>
		<feedburner:origLink>http://davidwparker.com/2008/12/10/dynamic-search-based-rss-feeds/</feedburner:origLink></item>
		<item>
		<title>Rails text_field tag with datetime data gotcha</title>
		<link>http://feeds.feedburner.com/~r/davidwparker/~3/454210926/</link>
		<comments>http://davidwparker.com/2008/11/15/rails-text_field-tag-with-datetime-data-gotcha/#comments</comments>
		<pubDate>Sat, 15 Nov 2008 19:06:20 +0000</pubDate>
		<dc:creator>David Parker</dc:creator>
		
		<category><![CDATA[rails]]></category>

		<category><![CDATA[ruby]]></category>

		<category><![CDATA[tutorials]]></category>

		<category><![CDATA[actionView]]></category>

		<category><![CDATA[computer]]></category>

		<category><![CDATA[formHelper]]></category>

		<category><![CDATA[gotcha]]></category>

		<category><![CDATA[helpers]]></category>

		<guid isPermaLink="false">http://davidwparker.com/?p=80</guid>
		<description><![CDATA[Another quick gotcha that I just discovered.  If you have a model that has a time on the backend, be careful which tags you use.  In my case, I have an app that is outside UTC:

config.time_zone = 'Central Time (US &#038; Canada)'

On my form, when editing the model, everything appears fine.  But [...]]]></description>
			<content:encoded><![CDATA[<p>Another quick gotcha that I just discovered.  If you have a model that has a time on the backend, be careful which tags you use.  In my case, I have an app that is outside UTC:</p>
<pre><code>
config.time_zone = 'Central Time (US &#038; Canada)'
</code></pre>
<p>On my form, when editing the model, everything appears fine.  But when you check out the difference in these two tags, you&#8217;ll see that text_field renders the incorrect time, whereas datetime_select renders the correct time.</p>
<pre><code>
= f.datetime_select :posted_at
= f.text_field :posted_at
</code></pre>
<p>I put in a defect ticket for this <a href="http://rails.lighthouseapp.com/projects/8994/tickets/1380-text_field-tag-has-incorrect-time#ticket-1380-1" onclick="javascript:pageTracker._trackPageview ('/outbound/rails.lighthouseapp.com');">here</a>.  Hopefully the Rails team will be able to knock that out quick.</p>
]]></content:encoded>
			<wfw:commentRss>http://davidwparker.com/2008/11/15/rails-text_field-tag-with-datetime-data-gotcha/feed/</wfw:commentRss>
		<feedburner:origLink>http://davidwparker.com/2008/11/15/rails-text_field-tag-with-datetime-data-gotcha/</feedburner:origLink></item>
		<item>
		<title>named_scope and Thinking Sphinx gotcha</title>
		<link>http://feeds.feedburner.com/~r/davidwparker/~3/452532501/</link>
		<comments>http://davidwparker.com/2008/11/13/named_scope-and-thinking-sphinx-gotcha/#comments</comments>
		<pubDate>Fri, 14 Nov 2008 04:43:00 +0000</pubDate>
		<dc:creator>David Parker</dc:creator>
		
		<category><![CDATA[programming]]></category>

		<category><![CDATA[rails]]></category>

		<category><![CDATA[tutorials]]></category>

		<category><![CDATA[help]]></category>

		<category><![CDATA[named scope]]></category>

		<category><![CDATA[named_scope]]></category>

		<category><![CDATA[nil]]></category>

		<category><![CDATA[search]]></category>

		<category><![CDATA[sphinx]]></category>

		<category><![CDATA[thinking sphinx]]></category>

		<guid isPermaLink="false">http://davidwparker.com/?p=74</guid>
		<description><![CDATA[I was working with named_scope earlier today and I was have an issue getting it to work properly with a Thinking Sphinx search that I had.  This makes sense, as named_scope is not completely supported yet by Thinking Sphinx.  Read below for the gotcha and a short-term work around.
I had a named_scope something [...]]]></description>
			<content:encoded><![CDATA[<p>I was working with named_scope earlier today and I was have an issue getting it to work properly with a Thinking Sphinx search that I had.  This makes sense, as named_scope is not completely supported yet by Thinking Sphinx.  Read below for the gotcha and a short-term work around.</p>
<p>I had a named_scope something like this:</p>
<pre><code>
named_scope :not_expired, lambda { {:conditions => ["expiration_date >= ?", Time.now.utc]} }
</code></pre>
<p>I was calling it in a chain to another method which just called a Thinking Sphinx search:</p>
<pre><code>
@posts = Post.not_expired.search_page(params)
</code></pre>
<p>My problem came from what came back in my @posts:</p>
<pre><code>
Sphinx Result: [85, 44, 26]
Post Load (0.003232)   SELECT * FROM `posts` WHERE (`posts`.`id` IN (85,44,26)) AND (expiration_date >= '2008-11-14 04:15:08')
</code></pre>
<p>All looks fine.  But then I would hit a nil object error&#8230; huh?</p>
<pre><code>
ActionView::TemplateError (You have a nil object when you didn't expect it!
The error occurred while evaluating nil.title) on line #5 of posts.html.haml
</code></pre>
<p>Loading up a script/console, I was finally able to see the problem. </p>
<pre><code>
>> @posts = Post.not_expired.search_page({:some=>"Param"})
=> some results....
>> @posts.size
=> 3
</code></pre>
<p>Somehow combining named_scope with Thinking Sphinx decided to load three posts into my @posts object even though it only found one.  So I had something like this:</p>
<pre><code>
[< Post id: 1, title: "something">, nil, nil]
</code></pre>
<p>And here was my fix (after the query):</p>
<pre><code>
@posts = @posts.compact
</code></pre>
<p>This throws out the nil results.<br />
Hopefully this will help out those out in Google land.</p>
]]></content:encoded>
			<wfw:commentRss>http://davidwparker.com/2008/11/13/named_scope-and-thinking-sphinx-gotcha/feed/</wfw:commentRss>
		<feedburner:origLink>http://davidwparker.com/2008/11/13/named_scope-and-thinking-sphinx-gotcha/</feedburner:origLink></item>
		<item>
		<title>Simple non-model checkbox in Rails</title>
		<link>http://feeds.feedburner.com/~r/davidwparker/~3/451295995/</link>
		<comments>http://davidwparker.com/2008/11/12/simple-non-model-checkbox-in-rails/#comments</comments>
		<pubDate>Thu, 13 Nov 2008 01:26:25 +0000</pubDate>
		<dc:creator>David Parker</dc:creator>
		
		<category><![CDATA[programming]]></category>

		<category><![CDATA[rails]]></category>

		<category><![CDATA[ruby]]></category>

		<category><![CDATA[tutorials]]></category>

		<category><![CDATA[web]]></category>

		<category><![CDATA[computer]]></category>

		<category><![CDATA[helpers]]></category>

		<guid isPermaLink="false">http://davidwparker.com/?p=69</guid>
		<description><![CDATA[I recently needed to do search in Rails with several checkboxes.  The search itself was not model backed, so the check_box tag was out.  I decided to use the check_box_tag instead.  The problem I had with that was that the check_box_tag had no real easy way of maintaining the state as to [...]]]></description>
			<content:encoded><![CDATA[<p>I recently needed to do search in Rails with several checkboxes.  The search itself was not model backed, so the check_box tag was out.  I decided to use the check_box_tag instead.  The problem I had with that was that the check_box_tag had no real easy way of maintaining the state as to whether or not the boxes were checked from search to search.</p>
<p>If I had params[:a] and params[:b], they may both be set, but I wouldn&#8217;t know it based off my GET request.  So I came up with a simple check_box_tag modification to retain the state of the checkboxes based on an identifier (in my case, I use the params)</p>
<p>In my application_helper.rb:</p>
<pre><code>
  def check_box_tag_new(name, value = "1", options = {})
    html_options = { "type" => "checkbox", "name" => name, "id" => name, "value" => value }.update(options.stringify_keys)
    unless html_options["check"].nil?
      html_options["checked"] = "checked" if html_options["check"].to_i == 1
    end
    tag :input, html_options
  end
</code></pre>
<p>Usage in a Haml file:</p>
<pre><code>
= check_box_tag_new :a, 1, :check => params[:a]
= check_box_tag_new :b, 1, :check => params[:b]
</code></pre>
<p>Here&#8217;s what I came up with for specs:</p>
<pre><code>
  describe "should create a check_box tag with the proper checked based on params:" do
    it "if check is nil, it should not be checked" do
      tag = helper.check_box_tag_new("me", nil, {:check => nil})
      tag.should == "< input id=\"me\" name=\"me\" type=\"checkbox\" \/>"
    end

    it "if check is not 1, it should not be checked" do
      tag = helper.check_box_tag_new("me", nil, {:check => 0})
      tag.should == "< input check=\"0\" id=\"me\" name=\"me\" type=\"checkbox\" \/>"
    end

    it "if check is 1, it should be checked" do
      tag = helper.check_box_tag_new("me", nil, {:check => 1})
      tag.should == "< input check=\"1\" checked=\"checked\" id=\"me\" name=\"me\" type=\"checkbox\" \/>"
    end
  end
</code></pre>
<p>Ignore the space between < and input&#8230; Wordpress is giving me formatting issues.</p>
]]></content:encoded>
			<wfw:commentRss>http://davidwparker.com/2008/11/12/simple-non-model-checkbox-in-rails/feed/</wfw:commentRss>
		<feedburner:origLink>http://davidwparker.com/2008/11/12/simple-non-model-checkbox-in-rails/</feedburner:origLink></item>
		<item>
		<title>Facebook style, unobrusive ajax pagination for will_paginate with jQuery</title>
		<link>http://feeds.feedburner.com/~r/davidwparker/~3/425819171/</link>
		<comments>http://davidwparker.com/2008/09/30/facebook-style-unobrusive-ajax-pagination-for-will_paginate-with-jquery/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 02:26:33 +0000</pubDate>
		<dc:creator>David Parker</dc:creator>
		
		<category><![CDATA[javascript]]></category>

		<category><![CDATA[jquery]]></category>

		<category><![CDATA[plugins]]></category>

		<category><![CDATA[tutorials]]></category>

		<category><![CDATA[computer]]></category>

		<category><![CDATA[pagination]]></category>

		<category><![CDATA[rails]]></category>

		<category><![CDATA[tools]]></category>

		<category><![CDATA[will paginate]]></category>

		<guid isPermaLink="false">http://davidwparker.com/?p=57</guid>
		<description><![CDATA[I really like the &#8216;pagination&#8217; that Facebook provides on their status tab.  It&#8217;s not true &#8216;pagination&#8217; in that the result set is changed, but it does add additional results to the bottom of the set.

If you want to just change the result set and not add to it (with will_paginate), then I suggest checking [...]]]></description>
			<content:encoded><![CDATA[<p>I really like the &#8216;pagination&#8217; that Facebook provides on their status tab.  It&#8217;s not true &#8216;pagination&#8217; in that the result set is changed, but it does add additional results to the bottom of the set.</p>
<p><img src="http://davidwparker.com/wp-content/uploads/2008/09/fb_bottomless_pagination.png" alt="" title="fb_bottomless_pagination" class="alignnone"  /></p>
<p>If you want to just change the result set and not add to it (with will_paginate), then I suggest checking out Chris&#8217; solution <a href="http://ozmm.org/posts/ajax_will_paginate_jq_style.html" onclick="javascript:pageTracker._trackPageview ('/outbound/ozmm.org');">here</a>, otherwise, read on&#8230;</p>
<p>Anyway, I went ahead and created a plugin for jQuery based on the wonder Rails plugin <a href="http://github.com/mislav/will_paginate/tree/master" onclick="javascript:pageTracker._trackPageview ('/outbound/github.com');">will_paginate</a>.  Introducing, jquery-bottomless-pagination.</p>
<p>Usage:<br />
You should already be using the will_paginate plugin.<br />
Then, be sure to include the javascript plugin:</p>
<pre>
<code>
= javascript_include_tag 'jquery.bottomlesspagination.js'
</code>
</pre>
<p>Here are the optional settings (displayed below are the defaults):</p>
<pre>
<code>
ajaxLoaderPath:'../images/ajax-loader.gif',
results:'.results',
objName:'',
callback:null
</code>
</pre>
<p><b>ajaxLoaderPath</b> is the path to your image which will be displayed while the ajax call is being made.<br />
<b>results</b> is the CSS selector that jQuery will use to append the results of the ajax call to.<br />
<b>objName</b> is the name of the object that you would like displayed in the phrase &#8220;Show more (objName)&#8230;&#8221; and &#8220;There are no more (objName) to add&#8230;&#8221;<br />
<b>callback</b> is a function which you can provide to perform extra functions after the objects are appended, such as adding highlight or zebra effects.</p>
<p>All of these settings can be utilized similarly to the following (this would be in your application.js file or something):</p>
<pre>
<code>
$.bottomlessPagination({objName:'rows', callback:function(){
  //highlight current row
  $(".results li").hover(function() {
    $(this).addClass("hover");
  }, function() {
    $(this).removeClass("hover");
  });
}});
</code>
</pre>
<p>You may need to provide something like the following for Rails.</p>
<pre>
<code>
$.ajaxSetup({
  'beforeSend': function(xhr) {
    xhr.setRequestHeader("Accept","text/javascript")}
});
</code>
</pre>
<p>On the rails side of things, in your controller, just return the partial which iterates through your returned objects:</p>
<pre>
<code>
def index
  @objects = Object.paginate :page => params[:page]
  respond_to do |format|
    format.html
    #ajax response
    format.js { render :template => 'objects/_index_objects.html.haml'}
  end
end
</code>
</pre>
<p>and the partial:</p>
<pre>
<code>
- for object in @object
  %li.result_row
    Your stuff here
</code>
</pre>
<p>That&#8217;s it.  Be sure to check out the plugin in its entirety on <a href="http://github.com/davidwparker/jquery-bottomless-pagination/tree/master" onclick="javascript:pageTracker._trackPageview ('/outbound/github.com');">Github</a>.  Feedback is always welcome.  Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://davidwparker.com/2008/09/30/facebook-style-unobrusive-ajax-pagination-for-will_paginate-with-jquery/feed/</wfw:commentRss>
		<feedburner:origLink>http://davidwparker.com/2008/09/30/facebook-style-unobrusive-ajax-pagination-for-will_paginate-with-jquery/</feedburner:origLink></item>
		<item>
		<title>Simple filterered search using drop downs with Thinking Sphinx</title>
		<link>http://feeds.feedburner.com/~r/davidwparker/~3/425819172/</link>
		<comments>http://davidwparker.com/2008/09/27/simple-multi-form-field-search-with-thinking-sphinx/#comments</comments>
		<pubDate>Sat, 27 Sep 2008 12:08:23 +0000</pubDate>
		<dc:creator>David Parker</dc:creator>
		
		<category><![CDATA[rails]]></category>

		<category><![CDATA[tutorials]]></category>

		<category><![CDATA[web]]></category>

		<category><![CDATA[gist]]></category>

		<category><![CDATA[ruby]]></category>

		<category><![CDATA[search]]></category>

		<category><![CDATA[setup]]></category>

		<category><![CDATA[sphinx]]></category>

		<category><![CDATA[thinking sphinx]]></category>

		<guid isPermaLink="false">http://davidwparker.com/?p=51</guid>
		<description><![CDATA[Sometimes you may need to offer your users the ability to perform a filtered search using drop down selects.  I had already settled on using Thinking Sphinx based on past experience, so I just needed to figure out how to offer &#8216;filters&#8217;.
For the sake of this tutorial I&#8217;ll be using a very basic example. [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes you may need to offer your users the ability to perform a filtered search using drop down selects.  I had already settled on using Thinking Sphinx based on past experience, so I just needed to figure out how to offer &#8216;filters&#8217;.</p>
<p>For the sake of this tutorial I&#8217;ll be using a very basic example.  Let&#8217;s start with the index that is defined for Thinking Sphinx in the model:</p>
<pre><code>
define_index do
  indexes city
  indexes state
end
</code></pre>
<p>Not too much going on here.  The city will provide a textbox for the user to perform basic searches on, and the state will be drop down list, or one of many &#8216;filters&#8217; in a real world app.</p>
<p>Onto my routes.rb file, I have defined a search path:</p>
<pre><code>
map.search '/search', :controller => 'search', :action => 'search'
</code></pre>
<p>My haml template looks like so:</p>
<pre><code>
%h2 Search
-form_tag search_path, :method => 'get' do
  .refine
    = label_tag :c, "city"
    %br
    = text_field_tag :c, params[:c]
  .refine
    = label_tag :st, "State"
    %br
    = select_tag "st", (options_from_collection_for_select STATE_LIST, "to_s", "to_s", params[:st])
  .refine
    = label_tag :p, "Results Per Page"
    %br
    = select_tag :p, (options_from_collection_for_select PER_PAGE_LIST, "to_s", "to_s", params[:p])
  .refine
    = submit_tag "Search", :name => nil
</code></pre>
<p>Nothing out of the ordinary here.  For this demonstration, suppose that I have previously defined STATE_LIST and PER_PAGE_LIST to be the list of states and the numbers for results per page that I want to offer my users the ability to select from.  In general your application will probably store the information for the drop downs in the database but if you just want to try something really quick, this will do the trick.  The PER_PAGE_LIST is only required if you&#8217;re using the wonderful <a href="http://github.com/mislav/will_paginate/tree/master" onclick="javascript:pageTracker._trackPageview ('/outbound/github.com');">will_paginate</a> plugin.</p>
<p>Anyway, onto the controller:</p>
<pre><code>
# GET /search
def search
  @models = Model.search_page params
  respond_to do |format|
    format.html
  end
end
</code></pre>
<p>Very basic search here.  I&#8217;ve declared a search_page method in my model and I pass it the params.  Then I simply do a respond_to.</p>
<p>Here is the search_page method in the model:</p>
<pre><code>
  def self.search_page(params)
    Model.search params[:c], :conditions => {
      :state       => params[:st]
    },
    :per_page => (params[:p].to_i unless params[:p].to_i == 0),
    :page => params[:page]
  end
</code></pre>
<p>I use the text field for the city as what I&#8217;m actually searching.  The state gets assigned to a condition.  This allows us to add several drop downs in the future as long as we know what values from which the user can select.  Next, you&#8217;ll note that we assign the :per_page and :page which are used for will_paginate.  If you want to give your users a very easy way to define how many results they want per page, then this is an easy way to do just that.</p>
<p>That&#8217;s it!  You can now define several drop down select filters!</p>
<p>Required additional reading/watching:</p>
<ul>
<li>Pat Allan&#8217;s concise <a href="http://freelancing-gods.com/posts/a_concise_guide_to_using_thinking_sphinx" onclick="javascript:pageTracker._trackPageview ('/outbound/freelancing-gods.com');">guide</a> to Thinking Sphinx.</li>
<li>Ryan Bate&#8217;s Railscasts<a href="http://railscasts.com/episodes/120-thinking-sphinx" onclick="javascript:pageTracker._trackPageview ('/outbound/railscasts.com');">episode</a> on Thinking Sphinx.</li>
<li>Rein&#8217;s <a href="http://reinh.com/blog/2008/07/14/a-thinking-mans-sphinx.html" onclick="javascript:pageTracker._trackPageview ('/outbound/reinh.com');">comparison</a> of UltraSphinx and Thinking Sphinx.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://davidwparker.com/2008/09/27/simple-multi-form-field-search-with-thinking-sphinx/feed/</wfw:commentRss>
		<feedburner:origLink>http://davidwparker.com/2008/09/27/simple-multi-form-field-search-with-thinking-sphinx/</feedburner:origLink></item>
		<item>
		<title>Site wide announcements in Rails using jQuery (jGrowl)</title>
		<link>http://feeds.feedburner.com/~r/davidwparker/~3/425819173/</link>
		<comments>http://davidwparker.com/2008/09/17/site-wide-announcements-in-rails-using-jquery-jgrowl/#comments</comments>
		<pubDate>Thu, 18 Sep 2008 03:16:38 +0000</pubDate>
		<dc:creator>David Parker</dc:creator>
		
		<category><![CDATA[javascript]]></category>

		<category><![CDATA[jquery]]></category>

		<category><![CDATA[programming]]></category>

		<category><![CDATA[rails]]></category>

		<category><![CDATA[ruby]]></category>

		<category><![CDATA[tutorials]]></category>

		<category><![CDATA[web]]></category>

		<category><![CDATA[computer]]></category>

		<category><![CDATA[gist]]></category>

		<category><![CDATA[haml]]></category>

		<category><![CDATA[jgrowl]]></category>

		<guid isPermaLink="false">http://davidwparker.com/?p=30</guid>
		<description><![CDATA[I like it when a site tells me that they&#8217;re going to do some maintenance, so I wanted to implement similar features for a web application that I&#8217;m working on.  I based my announcements on Ryan Bates&#8217; Railscasts episode 103 and updated code based on avarhirion&#8217;s post on the Rails Forum.  The major [...]]]></description>
			<content:encoded><![CDATA[<p>I like it when a site tells me that they&#8217;re going to do some maintenance, so I wanted to implement similar features for a web application that I&#8217;m working on.  I based my announcements on Ryan Bates&#8217; <a href="http://railscasts.com/episodes/103-site-wide-announcements" onclick="javascript:pageTracker._trackPageview ('/outbound/railscasts.com');">Railscasts episode 103</a> and updated code based on avarhirion&#8217;s post on the <a href="http://railsforum.com/post.php?tid=18705" onclick="javascript:pageTracker._trackPageview ('/outbound/railsforum.com');">Rails Forum</a>.  The major changes are the added changes for cookie support, graceful degradation, and jQuery (jGrowl).</p>
<p>If you&#8217;d rather, check out all the files on <a href="http://gist.github.com/11359" onclick="javascript:pageTracker._trackPageview ('/outbound/gist.github.com');">Github</a>.</p>
<p><b>announcement.rb</b></p>
<pre><code>
class Announcement < ActiveRecord::Base
  named_scope :active, lambda { { :conditions => ['starts_at <= ? AND ends_at >= ?', Time.now.utc, Time.now.utc] } }
  named_scope :since, lambda { |hide_time| { :conditions => (hide_time ? ['updated_at > ? OR starts_at > ?', hide_time.utc, hide_time.utc] : nil) } }
  def self.current_announcements(hide_time)
    active.since(hide_time)
  end
end</code></pre>
<p><b>application.html.haml</b></p>
<pre>
<code>
- unless current_announcements.empty?
  #announcements_box
    -for announcement in current_announcements
      .announcement{:id => 'announcement_' + announcement.id.to_s}
        =h announcement.message
        = link_to "Hide Announcements", hide_announcements_path, :id => 'hideAnn'
</code>
</pre>
<p><b>routes.rb</b></p>
<pre>
<code>map.hide_announcements '/hide_announcements', :controller => 'javascripts', :action => 'hide_announcements'</code></pre>
<p>Here&#8217;s the first of the important ones: <b>javascripts_controller.rb</b>.  Note that I&#8217;m setting the session and a cookie.  Also see my TODO.  I&#8217;d like to set the expiration date of the cookie to the oldest expiring active announcement.  </p>
<pre><code>class JavascriptsController < ApplicationController
  def hide_announcements
    time = Time.now.utc
    set_session time
    set_cookies time
    respond_to do |format|
      format.html { redirect_to(root_path) }
      format.js { redirect_to(root_path) }
    end
  end

  private
    def set_session(time)
      session[:announcement_hide_time] = time
    end
    #TODO change expiration time to be the expiration
    #date from the list in current_announcements
    def set_cookies(time)
      cookies[:announcement_hide_time] = {
        :value => time.to_datetime.to_s,
        :expires => time.next_week
      }
    end
end</code>
</pre>
<p>In the <b>application_helper.rb</b>, we check the session first and set the announcements, otherwise, we check the cookies.</p>
<pre>
<code>
def current_announcements
  unless session[:announcement_hide_time].nil?
    time = session[:announcement_hide_time]
  else
    time = cookies[:announcement_hide_time].to_datetime unless cookies[:announcement_hide_time].nil?
  end
  @current_announcements ||= Announcement.current_announcements(time)
end</code>
</pre>
<p>Finally, to make it with the cool-kids, we need to add some jQuery.  So I decided to use the <a href="http://stanlemon.net/projects/jgrowl.html" onclick="javascript:pageTracker._trackPageview ('/outbound/stanlemon.net');">jGrowl</a> plugin because it&#8217;s awesome.  This code goes in your <b>application.js</b> file (somewhere in $(function){ //here })</p>
<pre>
<code>
  //jgrowl announcements. ajax GET to hide ann/store cookie
  $.jGrowl.defaults.closer = false;
  $("#announcements_box").css("display","none");
  $("#announcements_box .announcement").each(function(){
    $.jGrowl(this.textContent,{ sticky:true, close:function(e,m,o){hide_announcements();} });
  });

  function hide_announcements(){
    $.get(
      '/hide_announcements'
    );

    $("#announcements_box").fadeOut();
    return false;
  }</code>
</pre>
<p>Obviously, you&#8217;ll need to include jGrowl js and css files.</p>
<p>I like this solution because it provides a great looking way to do site-wide announcements.  The solution degrades gracefully if the user does not have javascript enabled.  Finally, by saving to a cookie, users can leave, close their browsers, and come back as the please and not see the same announcements over and over again.</p>
<p>I&#8217;d like to leave you with a couple of specs that I wrote.  I attempted to do TDD/BDD and do the specs first, but it was tough.  I didn&#8217;t get too far, as I was having some cookie/session problems.  They&#8217;re in some serious need of help, so if you know cool stuff, help me out in the comments, thanks.<br />
<b>application_helper_spec.rb</b></p>
<pre>
<code>
  #TODO these are weak/inaccurate specs.  These are more-or-less stubs
  describe "should find the current announcements" do
    it "when the session['announcement_hide_time'] is not nil" do
      session['announcement_hide_time'] = Time.now.utc
      current_announcements.should == Announcement.current_announcements(session['announcement_hide_time'])
    end

    it "when the session['announcement_hide_time'] is nil and cookies['announcement_hide_time'] is not nil" do
      session['announcement_hide_time'] = nil
#      cookies['announcement_hide_time'] = CGI::Cookie.new('announcement_hide_time', Time.now.utc.to_datetime.to_s)
      time = Time.now.utc
      request.cookies['announcement_hide_time'] = {:value   => time.to_datetime.to_s,
                                                   :expires => time.next_week}
#      current_announcements.should == Announcement.current_announcements(cookies['announcement_hide_time'].value.first.to_datetime)
    end

    it "when the session['announcement_hide_time'] and cookies['announcement_hide_time'] are not nil" do
      session['announcement_hide_time'] = nil
      cookies['announcement_hide_time'] = nil
      current_announcements.should == Announcement.current_announcements(nil)
    end
  end</code>
</pre>
<p><b>announcement_spec.rb</b></p>
<pre>
<code>
  #TODO these are weak/inaccurate specs.  These are more-or-less stubs
  describe "the current_announcements" do
    it "should return announcements that are active" do
      time = Time.now.utc
      Announcement.active.should == Announcement.find(:all, :conditions => ['starts_at <= ? AND ends_at >= ?', time, time])
    end

    it "should return announcements since a time provided" do
      time = Time.now.utc
      Announcement.since.should == Announcement.find(
            :all,
            :conditions => (time ? ['updated_at > ? OR starts_at > ?', time.utc, time.utc] : nil))
    end

    it "should return announcements since a time provided (nil)" do
      time = nil
      Announcement.since.should == Announcement.find(
            :all,
            :conditions => (time ? ['updated_at > ? OR starts_at > ?', time.utc, time.utc] : nil))
    end
  end</code></pre>
<p>Any feedback is appreciated.</p>
]]></content:encoded>
			<wfw:commentRss>http://davidwparker.com/2008/09/17/site-wide-announcements-in-rails-using-jquery-jgrowl/feed/</wfw:commentRss>
		<feedburner:origLink>http://davidwparker.com/2008/09/17/site-wide-announcements-in-rails-using-jquery-jgrowl/</feedburner:origLink></item>
		<item>
		<title>Lovin Ubiquity</title>
		<link>http://feeds.feedburner.com/~r/davidwparker/~3/425819174/</link>
		<comments>http://davidwparker.com/2008/09/07/lovin-ubiquity/#comments</comments>
		<pubDate>Sun, 07 Sep 2008 20:55:08 +0000</pubDate>
		<dc:creator>David Parker</dc:creator>
		
		<category><![CDATA[fun]]></category>

		<category><![CDATA[ruby]]></category>

		<category><![CDATA[web]]></category>

		<category><![CDATA[colors]]></category>

		<category><![CDATA[colour lovers]]></category>

		<category><![CDATA[efficiency]]></category>

		<category><![CDATA[github]]></category>

		<category><![CDATA[internet]]></category>

		<category><![CDATA[rspec]]></category>

		<category><![CDATA[shortcuts]]></category>

		<category><![CDATA[tools]]></category>

		<category><![CDATA[ubiquity]]></category>

		<category><![CDATA[ubiquity commands]]></category>

		<guid isPermaLink="false">http://davidwparker.com/?p=20</guid>
		<description><![CDATA[So Mozilla&#8217;s Ubiquity project is extremely cool.  If you haven&#8217;t checked it out yet, do it now.  Ubiquity is an extremely efficient way to get around the web.
I wanted an easy way to search rspec documentation.  Not wanting to work too hard, I just forked Jack Dempsey&#8217;s code (which searched the Ruby [...]]]></description>
			<content:encoded><![CDATA[<p>So Mozilla&#8217;s <a href="http://labs.mozilla.com/2008/08/introducing-ubiquity/" onclick="javascript:pageTracker._trackPageview ('/outbound/labs.mozilla.com');">Ubiquity</a> project is extremely cool.  If you haven&#8217;t checked it out yet, do it now.  Ubiquity is an extremely efficient way to get around the web.</p>
<p>I wanted an easy way to search rspec documentation.  Not wanting to work too hard, I just forked Jack Dempsey&#8217;s code (which searched the Ruby documentation) and changed it to handle rspec instead.</p>
<p><code>CmdUtils.CreateCommand(<br />
            {<br />
                name:        "rspec",<br />
                takes:       {"function": noun_arb_text},<br />
                icon:        "http://ruby-doc.org/favicon.ico",<br />
                homepage:    "http://davidwparker.com",<br />
                author:      {name: "Jack Dempsey, fork by David Parker", email: "davidwparker@gmail.com"},<br />
                license:     "MPL,GPL",<br />
                description: "Search rspec functions documentation",<br />
                help:        "Select a rspec function",<br />
                execute: function(directObject)<br />
                {<br />
                    var url       = "http://apidock.com/rspec/search?query={QUERY}&#038;commit=Search"<br />
                    var urlString = url.replace("{QUERY}", directObject.text);<br />
                    Utils.openUrlInBrowser(urlString);<br />
                },<br />
                preview: function(pblock, directObject)<br />
                {<br />
                    searchText = jQuery.trim(directObject.text);<br />
                    if(searchText.length <= 0)<br />
                    {<br />
                      pblock.innerHTML = "Search rspec function documentation";<br />
                      return;<br />
                    }<br />
                    var previewTemplate = "Search rspec function documentation of ${query}";<br />
                    var previewData     = {query: searchText};<br />
                    pblock.innerHTML    = CmdUtils.renderTemplate(previewTemplate, previewData);<br />
                }<br />
            });</code></p>
<p>You can find it <a href="http://gist.github.com/9310" onclick="javascript:pageTracker._trackPageview ('/outbound/gist.github.com');">here</a> on Github if you want to subscribe to it.</p>
<p>Edit: I also just created a decent one for searching on Colourlovers.com.  You can search for colors by colors.  And you can search for palettes by colors/hex.  Here it is:<br />
<code>var cs_pa = ["colors","palettes"]<br />
var noun_type_cs_pa = new CmdUtils.NounType( &#8220;colors or palettes&#8221;, cs_pa );<br />
CmdUtils.CreateCommand({<br />
  name: &#8220;color&#8221;,<br />
  description: &#8220;Find colors and palettes on Colour Lover.  Search by colors or search by colors or hex for palettes.&#8221;,<br />
  help: &#8220;Try issuing &#8220;color blue&#8221; or &#8220;color #005F6B&#8221; by palettes&#8221;,<br />
  icon: &#8220;http://colourlovers.com.s3.amazonaws.com/favicon.ico&#8221;,<br />
  takes: {&#8221;color or hex&#8221;: noun_arb_text},<br />
  modifiers: { &#8220;by&#8221;: noun_type_cs_pa},<br />
  execute: function( directObj, modifier) {<br />
    var value = directObj.text;<br />
    var by = modifier.by.text;<br />
    var url = &#8220;http://www.colourlovers.com/colors/search?hsv=&#038;sortType=rank&#038;sortBy=asc&#038;query={QUERY}&#8221;;<br />
    if (value){<br />
      if (by){<br />
        if (by.indexOf(&#8221;palettes&#8221;) > -1){<br />
          url = url.replace(/colors/g, &#8220;palettes&#8221;);<br />
          url = url + &#8220;&#038;hex={HEX}&#8221;;<br />
        }<br />
      }<br />
      if (value.indexOf(&#8221;#&#8221;) > -1){<br />
        value = value.replace(&#8221;#&#8221;,&#8221;");<br />
        url = url.replace(&#8221;{HEX}&#8221;, value);<br />
        url = url.replace(&#8221;{QUERY}&#8221;, &#8220;&#8221;);<br />
      }<br />
      else{<br />
        url = url.replace(&#8221;{HEX}&#8221;, &#8220;&#8221;);<br />
        url = url.replace(&#8221;{QUERY}&#8221;, value);<br />
      }<br />
      url = url.replace(&#8221;{QUERY}&#8221;, value);<br />
    }<br />
    Utils.openUrlInBrowser(url);<br />
  },<br />
  preview: function( pblock, directObj, modifier) {<br />
    var value = directObj.text;<br />
    var by = modifier.by.text;<br />
    var message = &#8220;Searches Colour Lover Colors by color and search Palettes by color/hex.&#8221;;<br />
    if (value.length > 2){<br />
      if (by){<br />
        if (by.indexOf(&#8221;palettes&#8221;) > -1){<br />
          message = message.replace(&#8221;Lover Colors&#8221;, &#8220;Lover Palettes&#8221;);<br />
          if (value) {<br />
            if (value.indexOf(&#8221;#&#8221;) > -1){<br />
              message = message.replace(&#8221;by color and search Palettes by color/hex&#8221;, &#8220;by the hex value: &#8221; + value);<br />
            }<br />
            else{<br />
              message = message.replace(&#8221;by color and search Palettes by color/hex&#8221;, &#8220;by the color: &#8221; + value);<br />
            }<br />
          }<br />
        }<br />
      }<br />
      else{<br />
        if (value){<br />
          if (value.indexOf(&#8221;#&#8221;) > -1){<br />
            message = &#8220;Colour Lovers cannot search Colors by hex.&#8221;;<br />
          }<br />
          else {<br />
            message = message.replace(&#8221;by color and search Palettes by color/hex&#8221;, &#8220;by the color: &#8221; + value);<br />
          }<br />
        }<br />
      }<br />
    }<br />
    pblock.innerHTML = message;<br />
  }<br />
});</code></p>
<p>and on <a href="http://gist.github.com/9332" onclick="javascript:pageTracker._trackPageview ('/outbound/gist.github.com');">here</a> on Github</p>
]]></content:encoded>
			<wfw:commentRss>http://davidwparker.com/2008/09/07/lovin-ubiquity/feed/</wfw:commentRss>
		<feedburner:origLink>http://davidwparker.com/2008/09/07/lovin-ubiquity/</feedburner:origLink></item>
		<item>
		<title>More Free Time, Less Free Time</title>
		<link>http://feeds.feedburner.com/~r/davidwparker/~3/425819175/</link>
		<comments>http://davidwparker.com/2008/08/24/more-free-time-less-free-time/#comments</comments>
		<pubDate>Mon, 25 Aug 2008 01:10:15 +0000</pubDate>
		<dc:creator>David Parker</dc:creator>
		
		<category><![CDATA[life]]></category>

		<category><![CDATA[programming]]></category>

		<category><![CDATA[working out]]></category>

		<guid isPermaLink="false">http://davidwparker.com/?p=15</guid>
		<description><![CDATA[So there&#8217;s plenty of things that I would love to say, but of course I can&#8217;t say them all.  So, instead, I&#8217;ll just play catch up.
I&#8217;ve decided to not take any classes this semester.  For the past three semesters I took five math classes in the thought that I would like to apply [...]]]></description>
			<content:encoded><![CDATA[<p>So there&#8217;s plenty of things that I would love to say, but of course I can&#8217;t say them all.  So, instead, I&#8217;ll just play catch up.</p>
<p>I&#8217;ve decided to not take any classes this semester.  For the past three semesters I took five math classes in the thought that I would like to apply for a PhD in Economics.  After really looking over my life, programs, and professions, I really just don&#8217;t think this is the route that I would like to take.  So, that was that.  No more classes.  These past few semesters have been really busy and I really haven&#8217;t had time to work on any of my <a href="http://gist.github.com/6443" onclick="javascript:pageTracker._trackPageview ('/outbound/gist.github.com');">side projects</a>.  Now, I can finally play catch up.</p>
<p>Now it comes to which side project I should be working on&#8230; I&#8217;m huge into time management, productivity, etc. but I still find myself searching for time and wasting time.  It&#8217;s a love-hate cycle and I know we all have them.  So when I laid out my general interests and side projects, I began to think of which I should work first.  The good news is that I don&#8217;t have to choose only <a href="http://www.stevepavlina.com/blog/2008/07/what-if-you-have-many-different-interests-and-cannot-commit-to-any-of-them/" onclick="javascript:pageTracker._trackPageview ('/outbound/www.stevepavlina.com');">one</a>.</p>
<p>Anyway, so my interests include Ruby, Rails, Merb, DataMapper, jQuery, Erlang, Fuzed, Hpricot, CouchDB, Amazon EC2, etc&#8230; Hmmm, seems like all the cool kids are getting into Erlang these days.</p>
<p>Additionally, I&#8217;m going to use some of my free time to begin working out (regularly).  I already enjoy working out, but I don&#8217;t really do it regularly.  So, we&#8217;ll see how that goes.  Pictures to come (ooh la la).</p>
<p>Wish me luck in actually getting things done &#8482;.  Hopefully, this time next year, I&#8217;ll have a wealth of knowledge of meaningless stuff, but I&#8217;ll be enjoying it full-time.</p>
]]></content:encoded>
			<wfw:commentRss>http://davidwparker.com/2008/08/24/more-free-time-less-free-time/feed/</wfw:commentRss>
		<feedburner:origLink>http://davidwparker.com/2008/08/24/more-free-time-less-free-time/</feedburner:origLink></item>
		<item>
		<title>Book: Don’t Make Me Think</title>
		<link>http://feeds.feedburner.com/~r/davidwparker/~3/425819176/</link>
		<comments>http://davidwparker.com/2008/08/03/book-dont-make-me-think/#comments</comments>
		<pubDate>Sun, 03 Aug 2008 22:20:51 +0000</pubDate>
		<dc:creator>David Parker</dc:creator>
		
		<category><![CDATA[web]]></category>

		<category><![CDATA[book]]></category>

		<category><![CDATA[review]]></category>

		<category><![CDATA[usability]]></category>

		<guid isPermaLink="false">http://davidwparker.com/?p=9</guid>
		<description><![CDATA[At RubyConf 2007 Ryan Davis said that we, as developers, should be reading one book a month about software development, etc.  Additionally, while reading Jeff Atwood&#8217;s blog I only reaffirmed the habit. Although I haven&#8217;t exactly hit a rate of one technical book per month yet (I read some fiction and other books in [...]]]></description>
			<content:encoded><![CDATA[<p>At RubyConf 2007 <a href="http://blog.zenspider.com" onclick="javascript:pageTracker._trackPageview ('/outbound/blog.zenspider.com');">Ryan Davis</a> said that we, as developers, should be reading one book a month about software development, etc.  Additionally, while reading Jeff Atwood&#8217;s <a href="http://www.codinghorror.com/blog/archives/001108.html" onclick="javascript:pageTracker._trackPageview ('/outbound/www.codinghorror.com');">blog</a> I only reaffirmed the habit. Although I haven&#8217;t exactly hit a rate of one technical book per month yet (I read some fiction and other books in there too), I have enjoyed continuing my education, especially beyond school and reading blogs.  I&#8217;ve read quite a few books this year, but this is the first pseudo review that I&#8217;ve ever written.  Actually, it&#8217;s much less review and much more &#8220;things that I really enjoyed&#8221; and want to remember.</p>
<p><a href="http://www.amazon.com/dp/0321344758?tag=parkonsoft-20" onclick="javascript:pageTracker._trackPageview ('/outbound/www.amazon.com');">Don&#8217;t Make Me Think</a><img src="http://www.assoc-amazon.com/e/ir?t=parkonsoft-20&amp;l=ur2&amp;o=1" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> by Steve Krug is an excellent book.  The second edition was published in 2006, which although may seem ancient by technology standards, is still quite up-to-date on everything critical for a website.  Yes, I&#8217;m sure there are plenty of things in the book that I should be changing on this site, but at the moment, I rather like this theme (Hemingway).  Anyway, on with the book.  </p>
<p>First off, I really like the concept of the book.  Using the web is not about thinking.  It&#8217;s about lack of thought and clicking on what sparks my interest, whether I thought about it or not.</p>
<p>Chapter 5: Omit <del datetime="2008-08-03T20:58:19+00:00">needless</del> words was the first major instruction that I hadn&#8217;t heard before.  In fact, I&#8217;m sure this blog post is full of needless words, but I&#8217;m sure it&#8217;s going to stay that way.  But for a pure business-type/selling something website I can see how important this may be.  I love the point Steve makes about removing Happy talk and Instructions must die.  </p>
<p>Chapter 6: Street Signs and Breadcrumbs, I never thought about the total various &#8220;utility&#8221; links that I site may have and I found his list rather helpful.  I&#8217;ve never driven in LA or in Boston, but I really enjoyed Steve using the street signs in those places as an example of what to do and what not to do.</p>
<p>Chapter 7: The Home Page is Beyond Your Control was rather informative in regards to pull-down/drop-down menus.  I&#8217;ve worked on and used many applications that utilized drop-down menus and some have worked well and some haven&#8217;t.  For example, I&#8217;m not too fond of the Facebook dropdown for the friends section (more), especially after reading Steve&#8217;s book:<br />
<img alt="" src="http://davidwparker.com/images/facebook_dropdown.png" title="Facebook Drop-Down" class="aligncenter" width="189" height="295" /><br />
Sorry about the crappy picture: first Ubuntu screenshot ever, no photo editing skills with GiMP /excuse</p>
<p>Chapter 9: Usability Testing on 10 Cents A Day was an excellent chapter as well.  Over the last couple of years, I&#8217;ve really enjoyed Unit testing my code, specifically with BDD-type testing (rSpec is my current favorite in the Rails world), but I haven&#8217;t done much with usability testing.  Generally, I would just go do the usability testing of &#8220;can my wife use it?&#8221;  If she can, then I generally feel alright.  If not, then there&#8217;s more work to be done.  Anyway, I liked what Steve had to say about testing with just a few people, iteratively.</p>
<p>Chapter 10: Usability as a Common Courtesy introduced several things that can diminish goodwill with the customer.  Specifically, a few that I really liked were:</p>
<ul>
<li>Punishing me for not doing things your way</li>
<li>Asking me for information you don&#8217;t really need</li>
</ul>
<p>To me, I can&#8217;t stand it when a site kicks back an error message for how I put my phone number into their textfield.  Personally, I like to do XXX.XXX.XXXX.  Much more common is (XXX) XXX-XXXX.  Also common is XXX-XXX-XXXX.  I generally use the periods and I think it&#8217;s rather amateurish when I website can&#8217;t accept any of the common formats.  I&#8217;ve worked on many business applications where specific instructions were to not accept other formats.  Reasoning?  None other than, because I&#8217;m the boss, or because it&#8217;s too much code.  It&#8217;s really not, but that&#8217;s besides the point.<br />
Asking for too much information is another peave of mine.  I especially hate when you&#8217;re signing up for a website and it&#8217;s asking for way too much&#8230; generally, for about 90% of the websites out there, all you need to ask for is username, password, and e-mail.  Even then, you may only need e-mail to &#8220;confirm&#8221; the user, or to send them a reset password and it may not be required at all.  This was all restated in Chapter 12: Help! My boss wants me to ____.</p>
<p>Overall, I thought the book was excellent and I&#8217;d highly recommend to anyone doing anything on the web.  Building straight html?  E-commerce sites?  Business intranets?  Social networking sites?  Something else?  No matter what it is, reading this book will help you to understand the usability a little bit better.</p>
]]></content:encoded>
			<wfw:commentRss>http://davidwparker.com/2008/08/03/book-dont-make-me-think/feed/</wfw:commentRss>
		<feedburner:origLink>http://davidwparker.com/2008/08/03/book-dont-make-me-think/</feedburner:origLink></item>
	</channel>
</rss>
