<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
 
 <title>VanDev</title>
 
 <link href="http://vandev.com/" />
 <updated>2009-10-16T22:37:19+00:00</updated>
 <id>http://vandev.com/</id>
 <author>
   <name>Chris Van Pelt</name>
   <email>vanpelt@gmail.com</email>
 </author>
 
 
 <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/vandev" /><feedburner:info uri="vandev" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:browserFriendly></feedburner:browserFriendly><entry>
   <title>MongoDB Fancy Ass Grouping</title>
   <link href="http://vandev.com/2009/10/16/mongdb-fancy-ass-grouping.html" />
   <updated>2009-10-16T00:00:00+00:00</updated>
   <id>http://vandev.com/2009/10/16/mongdb-fancy-ass-grouping</id>
   <content type="html">&lt;p&gt;So lately I&amp;#8217;ve been playing with &lt;a href='http://mongodb.org'&gt;Mongodb&lt;/a&gt; for &lt;a href='http://crowdflower.com'&gt;CrowdFlower&lt;/a&gt;. We need to calculate statistics from the information that we gather. Mongo provides support for this but has little documentation. I thought it would be appropriate to describe how I got some of the fancier group statements working. Let&amp;#8217;s take this document format as an example:&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='javascript'&gt;{
     &amp;quot;state&amp;quot;: &amp;quot;finished&amp;quot;,
     &amp;quot;data&amp;quot;: {
       &amp;quot;everythings_good&amp;quot;: &amp;quot;yes&amp;quot;
     }
   }&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The key property alone of the group function can not be used because our key is in an embedded member. We have to use the keyf property of the &lt;a href='http://www.mongodb.org/display/DOCS/Aggregation'&gt;group&lt;/a&gt; command. I&amp;#8217;m using the Mongo ruby library and it currently doesn&amp;#8217;t support the use of this property. Instead I issue the raw db_command:&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='ruby'&gt;db = Mongo::Connection.new.db('docs')
    db.db_command({
      &amp;quot;group&amp;quot; =&amp;gt; {
        &amp;quot;ns&amp;quot; =&amp;gt; &amp;quot;ratings&amp;quot;,
        &amp;quot;$reduce&amp;quot; =&amp;gt; Mongo::Code.new(&amp;lt;&amp;lt;-JS),
          function(obj,prev){ prev.count++; }
        JS
        &amp;quot;$keyf&amp;quot; =&amp;gt; Mongo::Code.new(&amp;lt;&amp;lt;-JS),
          function(obj){
            var g = {}
            g[obj.data.everythings_good] = true
            return g
          }
        JS
        &amp;quot;cond&amp;quot; =&amp;gt; {},
        &amp;quot;initial&amp;quot; =&amp;gt; {:count =&amp;gt; 0}
      }
    })&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This command returns the following value:&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='ruby'&gt;{
      &amp;quot;retval&amp;quot;=&amp;gt;[
        {&amp;quot;yes&amp;quot;=&amp;gt;1.0, &amp;quot;count&amp;quot;=&amp;gt;17355.0}, 
        {&amp;quot;no&amp;quot;=&amp;gt;1.0, &amp;quot;count&amp;quot;=&amp;gt;6395.0}
      ], 
      &amp;quot;count&amp;quot;=&amp;gt;23750.0, 
      &amp;quot;keys&amp;quot;=&amp;gt;2, 
      &amp;quot;ok&amp;quot;=&amp;gt;1.0
    }&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; the keyf property was not working properly until version 1.1.0 of mongodb&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Fancy Zoom Mootools time</title>
   <link href="http://vandev.com/2008/09/16/fancy-zoom-mootools-time.html" />
   <updated>2008-09-16T00:00:00+00:00</updated>
   <id>http://vandev.com/2008/09/16/fancy-zoom-mootools-time</id>
   <content type="html">&lt;script src='http://github.com/vanpelt/fancy-zoom/tree/master%2Fmootools%2Fjs%2Ffancyzoom.min.js?raw=true' type='text/javascript' /&gt;&lt;script type='text/javascript'&gt;
/* &lt;![CDATA[ */
document.addEvent('domready', function(){
   new FancyZoom($('hot_thumb'), {scaleImg:true, directory:'/images'})
})
/* ]]&gt; */
&lt;/script&gt;
&lt;p&gt;So I stumbled upon this &lt;a href='http://github.com/jnunemaker/fancy-zoom/tree/master'&gt;project&lt;/a&gt; on github.com&amp;#8230; If you browse the archives of this blog you might see I have an affinity for Mootools over Prototype or JQuery &lt;em&gt;(Although JQuery is hot, and the new FX stuff is tempting me to stop being a rebel)&lt;/em&gt;. Regardless, Fancy Zoom for Mootools is &lt;a href='http://github.com/vanpelt/fancy-zoom/tree/master/mootools'&gt;born&lt;/a&gt;. It&amp;#8217;s a pretty straight forward port. The main performance gain is that the effects are only initialized once no matter how many FancyZoom instances there are on a page. Click on the thumbnail below to see it in action.&lt;/p&gt;
&lt;a href='#hot' id='hot_thumb'&gt;
&lt;img src='http://farm3.static.flickr.com/2269/2777947066_5a04fb7b5b_s.jpg' /&gt;&lt;/a&gt;&lt;div id='hot'&gt;
&lt;img src='http://farm3.static.flickr.com/2269/2777947066_5a04fb7b5b.jpg' /&gt;
&lt;/div&gt;
&lt;p&gt;In unrelated news the image you just clicked on is of me speaking at the local &lt;a href='http://javascript.meetup.com'&gt;San Francisco JavaScript meetup&lt;/a&gt; a couple weeks ago. I attempted to give a tutorial of Mootools called &lt;a href='http://github.com/vanpelt/instimage/tree/master'&gt;Instimage&lt;/a&gt;. If you do a search for &lt;a href='http://www.google.com/search?q=sf+js'&gt;&amp;#8220;sf js&amp;#8221;&lt;/a&gt; my &lt;a href='http://www.slideshare.net/sfjsmeetup/chris-van-pelt-instimage-and-mootools-sf-js-3-presentation/'&gt;slides&lt;/a&gt; are the first result for some reason&amp;#8230; Pagerank is the end all. Peace.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>JSAwesome</title>
   <link href="http://vandev.com/2008/04/22/jsawesome.html" />
   <updated>2008-04-22T00:00:00+00:00</updated>
   <id>http://vandev.com/2008/04/22/jsawesome</id>
   <content type="html">&lt;p&gt;Here is a sample call to JSAwesome:&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='javascript'&gt;new JSAwesome('an_id',[
      ['text_field', 'default value'],
      ['#text_area', ''],
      ['_hidden_input','i_am_invisible'],
      ['*radios', ['so|nice', 'many', 'radio|boxes', 'yeah']],
      [['^checkbox', true], '^not'],
      ['^choices', ['Choice 1|one', 'Choice 2|two', ['Choice 3|three', true]]],
      ['single_select', ['boo', '~yah']],
      ['nested_select', 
	 {'rad': ['cool', 'neat'], 
	  'awesome':
	    {'crazy': ['Indeed|~shit', 'man'],
	     'way': ['oh', 'yeah']}
	 }]]).to_html()&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This generates this form (_choose &lt;code&gt;awesome&lt;/code&gt;, than &lt;code&gt;crazy&lt;/code&gt;, than &lt;code&gt;Indeed&lt;/code&gt; from the set of select boxes at the bottom of the form to have your mind blown_)&lt;/p&gt;
&lt;div id='an_id' /&gt;&lt;script src='/js/jsawesome.js' type='text/javascript' charset='utf-8' /&gt;&lt;script type='text/javascript'&gt;
/* &lt;![CDATA[ */
  new JSAwesome('an_id',[
      ['text_field', 'default value'],
      ['#text_area', ''],
      ['_hidden_input','i_am_invisible'],
      ['*radios', ['so|nice', 'many', 'radio|boxes', 'yeah']],
      [['^checkbox', true], '^not'],
      ['^choices', ['Choice 1|one', 'Choice 2|two', ['Choice 3|three', true]]],
      ['single_select', ['boo', '~yah']],
      ['nested_select', 
	 {'rad': ['cool', 'neat'], 
	  'awesome':
	    {'crazy': ['Indeed|~shit', 'man'],
	     'way': ['oh', 'yeah']}
	 }]]).to_html()
/* ]]&gt; */
&lt;/script&gt;
&lt;p&gt;With this markup:&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='html'&gt;&amp;lt;div id=&amp;quot;an_id&amp;quot;&amp;gt;
  &amp;lt;div class=&amp;quot;error text_field&amp;quot;&amp;gt;
    &amp;lt;label for=&amp;quot;an_id_text_field&amp;quot;&amp;gt;Text field&amp;lt;/label&amp;gt; &amp;lt;input id=&amp;quot;an_id_text_field&amp;quot; class=&amp;quot;text_field&amp;quot; type=&amp;quot;text&amp;quot; name=&amp;quot;an_id[text_field]&amp;quot; /&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;error text_area&amp;quot;&amp;gt;
    &amp;lt;label for=&amp;quot;an_id_text_area&amp;quot;&amp;gt;Text area&amp;lt;/label&amp;gt; &amp;lt;textarea id=&amp;quot;an_id_text_area&amp;quot; class=&amp;quot;text_area&amp;quot; name=&amp;quot;an_id[text_area]&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;error hidden_input&amp;quot;&amp;gt;
    &amp;lt;input id=&amp;quot;an_id_hidden_input&amp;quot; class=&amp;quot;hidden_input&amp;quot; type=&amp;quot;hidden&amp;quot; name=&amp;quot;an_id[hidden_input]&amp;quot; value=&amp;quot;i_am_invisible&amp;quot; /&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;error radios&amp;quot;&amp;gt;
    &amp;lt;fieldset&amp;gt;
      &amp;lt;legend&amp;gt;Radios&amp;lt;/legend&amp;gt; 
      &amp;lt;label for=&amp;quot;an_id_radios&amp;quot;&amp;gt;
          &amp;lt;input id=&amp;quot;&amp;quot; class=&amp;quot;radios&amp;quot; type=&amp;quot;radio&amp;quot; name=&amp;quot;an_id[radios]&amp;quot; value=&amp;quot;nice&amp;quot;&amp;gt; So&amp;lt;/label&amp;gt; 
       &amp;lt;label for=&amp;quot;an_id_radios&amp;quot;&amp;gt;
          &amp;lt;input id=&amp;quot;&amp;quot; class=&amp;quot;radios&amp;quot; type=&amp;quot;radio&amp;quot; name=&amp;quot;an_id[radios]&amp;quot; value=&amp;quot;many&amp;quot;&amp;gt; Many&amp;lt;/label&amp;gt; 
       &amp;lt;label for=&amp;quot;an_id_radios&amp;quot;&amp;gt;
          &amp;lt;input id=&amp;quot;&amp;quot; class=&amp;quot;radios&amp;quot; type=&amp;quot;radio&amp;quot; name=&amp;quot;an_id[radios]&amp;quot; value=&amp;quot;boxes&amp;quot;&amp;gt; Radio&amp;lt;/label&amp;gt; 
       &amp;lt;label for=&amp;quot;an_id_radios&amp;quot;&amp;gt;
          &amp;lt;input id=&amp;quot;&amp;quot; class=&amp;quot;radios&amp;quot; type=&amp;quot;radio&amp;quot; name=&amp;quot;an_id[radios]&amp;quot; value=&amp;quot;yeah&amp;quot;&amp;gt; Yeah&amp;lt;/label&amp;gt;
    &amp;lt;/fieldset&amp;gt;
  &amp;lt;/div&amp;gt;
   &amp;lt;div class=&amp;quot;error row_5&amp;quot;&amp;gt;
      &amp;lt;div style=&amp;quot;float: left; margin-right: 5px;&amp;quot;&amp;gt;
        &amp;lt;label for=&amp;quot;an_id_checkbox&amp;quot;&amp;gt;
           &amp;lt;span&amp;gt;
              &amp;lt;input id=&amp;quot;an_id_real_cool&amp;quot; class=&amp;quot;real_cool&amp;quot; type=&amp;quot;checkbox&amp;quot; name=&amp;quot;an_id[checkbox]&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt; 
              &amp;lt;input id=&amp;quot;an_id_real_cool&amp;quot; class=&amp;quot;real_cool&amp;quot; type=&amp;quot;hidden&amp;quot; name=&amp;quot;an_id[checkbox]&amp;quot; value=&amp;quot;false&amp;quot;&amp;gt;
           &amp;lt;/span&amp;gt; Checkbox&amp;lt;/label&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div style=&amp;quot;float: left; margin-right: 5px;&amp;quot;&amp;gt;
        &amp;lt;label for=&amp;quot;an_id_not&amp;quot;&amp;gt;
            &amp;lt;span&amp;gt;
                &amp;lt;input id=&amp;quot;an_id_not&amp;quot; class=&amp;quot;not&amp;quot; type=&amp;quot;checkbox&amp;quot; name=&amp;quot;an_id[not]&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt; 
                &amp;lt;input id=&amp;quot;an_id_not&amp;quot; class=&amp;quot;not&amp;quot; type=&amp;quot;hidden&amp;quot; name=&amp;quot;an_id[not]&amp;quot; value=&amp;quot;false&amp;quot;&amp;gt;
             &amp;lt;/span&amp;gt; Not&amp;lt;/label&amp;gt;
      &amp;lt;/div&amp;gt;&amp;lt;br style=&amp;quot;clear: left;&amp;quot;&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&amp;quot;error choices&amp;quot;&amp;gt;
      &amp;lt;fieldset&amp;gt;
        &amp;lt;legend&amp;gt;Choices&amp;lt;/legend&amp;gt; 
            &amp;lt;label for=&amp;quot;an_id_one&amp;quot;&amp;gt;
               &amp;lt;span&amp;gt;
                  &amp;lt;input id=&amp;quot;an_id_one&amp;quot; class=&amp;quot;one&amp;quot; type=&amp;quot;checkbox&amp;quot; name=&amp;quot;an_id[one]&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt; 
                  &amp;lt;input id=&amp;quot;an_id_one&amp;quot; class=&amp;quot;one&amp;quot; type=&amp;quot;hidden&amp;quot; name=&amp;quot;an_id[one]&amp;quot; value=&amp;quot;false&amp;quot;&amp;gt;
               &amp;lt;/span&amp;gt; Choice 1&amp;lt;/label&amp;gt; 
             &amp;lt;label for=&amp;quot;an_id_two&amp;quot;&amp;gt;
               &amp;lt;span&amp;gt;
                  &amp;lt;input id=&amp;quot;an_id_two&amp;quot; class=&amp;quot;two&amp;quot; type=&amp;quot;checkbox&amp;quot; name=&amp;quot;an_id[two]&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt; 
                  &amp;lt;input id=&amp;quot;an_id_two&amp;quot; class=&amp;quot;two&amp;quot; type=&amp;quot;hidden&amp;quot; name=&amp;quot;an_id[two]&amp;quot; value=&amp;quot;false&amp;quot;&amp;gt;
               &amp;lt;/span&amp;gt; Choice 2&amp;lt;/label&amp;gt; 
            &amp;lt;label for=&amp;quot;an_id_three&amp;quot;&amp;gt;
                &amp;lt;span&amp;gt;
                    &amp;lt;input id=&amp;quot;an_id_three&amp;quot; class=&amp;quot;three&amp;quot; type=&amp;quot;checkbox&amp;quot; name=&amp;quot;an_id[three]&amp;quot; value=&amp;quot;true&amp;quot;&amp;gt;
                    &amp;lt;input id=&amp;quot;an_id_three&amp;quot; class=&amp;quot;three&amp;quot; type=&amp;quot;hidden&amp;quot; name=&amp;quot;an_id[three]&amp;quot; value=&amp;quot;false&amp;quot;&amp;gt;
                &amp;lt;/span&amp;gt; Choice 3&amp;lt;/label&amp;gt;
      &amp;lt;/fieldset&amp;gt;
    &amp;lt;/div&amp;gt;
   &amp;lt;div class=&amp;quot;error single_select&amp;quot;&amp;gt;
      &amp;lt;label for=&amp;quot;an_id_single_select&amp;quot;&amp;gt;Single select&amp;lt;/label&amp;gt;
          &amp;lt;select id=&amp;quot;an_id_single_select&amp;quot; class=&amp;quot;single_select&amp;quot; name=&amp;quot;an_id[single_select]&amp;quot;&amp;gt;
              &amp;lt;option value=&amp;quot;&amp;quot;&amp;gt;Choose Category&amp;lt;/option&amp;gt;
              &amp;lt;option value=&amp;quot;boo&amp;quot;&amp;gt;boo&amp;lt;/option&amp;gt;
              &amp;lt;option value=&amp;quot;yah&amp;quot;&amp;gt;yah&amp;lt;/option&amp;gt;
           &amp;lt;/select&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;error nested_select&amp;quot;&amp;gt;
    &amp;lt;label for=&amp;quot;an_id_nested_select&amp;quot;&amp;gt;Sub cats&amp;lt;/label&amp;gt; &amp;lt;select id=&amp;quot;an_id_nested_select&amp;quot; class=&amp;quot;nested_select&amp;quot; name=&amp;quot;an_id[nested_select]&amp;quot;&amp;gt;
      &amp;lt;option value=&amp;quot;&amp;quot;&amp;gt;
        Choose Category
      &amp;lt;/option&amp;gt;
      &amp;lt;option value=&amp;quot;rad&amp;quot;&amp;gt;
        rad
      &amp;lt;/option&amp;gt;
      &amp;lt;option value=&amp;quot;awesome&amp;quot;&amp;gt;
        awesome
      &amp;lt;/option&amp;gt;
    &amp;lt;/select&amp;gt; &amp;lt;select id=&amp;quot;an_id_nested_select_1&amp;quot; class=&amp;quot;nested_select_1&amp;quot; name=&amp;quot;an_id[nested_select_1]&amp;quot;&amp;gt;
      &amp;lt;option value=&amp;quot;&amp;quot;&amp;gt;
        Choose Subcategory
      &amp;lt;/option&amp;gt;
    &amp;lt;/select&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Wow, lot&amp;#8217;s of HTML from a little JSON. Let&amp;#8217;s do an overview of the parameters.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The first parameter to JSAwesome is an id of an element already in the DOM. It also acts as a namespace for the names and id&amp;#8217;s of form elements to allow for multiple JSAwesome forms on a page. Looking at the html you can see you have plenty of classes added as well to style your generated form to your hearts content.&lt;/li&gt;

&lt;li&gt;The second parameter is an array of tuples specifying the form elements in order. The tuples can create the following elements using these rules: * &lt;strong&gt;textfield&lt;/strong&gt; - the first element is the name with no special character and the second element is a string with the default value * &lt;strong&gt;textarea&lt;/strong&gt; - the first element is the name beginning with a &lt;code&gt;#&lt;/code&gt; and the second element is a string with the default value * &lt;strong&gt;hidden&lt;/strong&gt; - the first element is the name beginning with a &lt;code&gt;_&lt;/code&gt; and the second element is the value * &lt;strong&gt;radio&lt;/strong&gt; - the first element is the legend of a fieldset / name of the radio buttons beginning with a &lt;code&gt;*&lt;/code&gt; and the second element is an array of names. Optionally you can specify label / name pairs separated by the &lt;code&gt;|&lt;/code&gt; character. * &lt;strong&gt;checkbox&lt;/strong&gt; - the first element is the name and label of a checkbox beginning with a &lt;code&gt;^&lt;/code&gt; character. If a second element is present, the checkbox will be checked. The example above also demonstrates the ability to group fields together on the same line. If you use an array of tuples, &lt;em&gt;or in this case checkboxes can be specfied with a single string if the you don&amp;#8217;t want it checked&lt;/em&gt;, those elements will be wrapped in div&amp;#8217;s with the style set to &amp;#8216;float:left&amp;#8217;. Optionally label / name pairs work the same as radio&amp;#8217;s. * &lt;strong&gt;checkbox group&lt;/strong&gt; - the first element is the legend of a fieldset and the second is an array of checkboxes as described above * &lt;strong&gt;single select&lt;/strong&gt; - the first element is the name of the select and the second is an array of options. Optionally the options can specify name / value pairs separated by the &lt;code&gt;|&lt;/code&gt; character. You can also use the &amp;#8217;~&amp;#8217; character to specify a custom input. When this option is selected a textfield will appear to allow the user to enter a custom value. * &lt;strong&gt;nested select&lt;/strong&gt; - the first element is the name of the select. The second element is a hash with the keys being the options and the values being hashes or arrays of the child selects. Optionally name / value pairs and custom inputs work the same as single selects.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But there&amp;#8217;s more. JSAwesome takes a third parameter which gives you custom labels and validations. This use case might look like this:&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='javascript'&gt;var test = new JSAwesome('validated',[
      ['text_field', 'default value'],
      ['#text_area', ''],
      ['single_select', ['boo', '~yah']]
      ], 
      {'text_field': &amp;quot;JSAwesome&amp;quot;,
       'text_area': {
          'required':true,
          'validation': [&amp;quot;\\d+&amp;quot;, &amp;quot;Field must contain atleast one digit&amp;quot;],
          'label': &amp;quot;Input some text with atleast one digit&amp;quot;
       },
       'single_select': {
          'required':true
       },
       '~': 'Custom instructions',
       '{}': ['Select something']
   })
   test.to_html()
   test.addValidation()&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Which generates this form:&lt;/p&gt;
&lt;form action='#' id='form'&gt;&lt;div id='validated' /&gt;&lt;br /&gt;&lt;input type='submit' value='Test validation' /&gt;&lt;/form&gt;&lt;script type='text/javascript'&gt;
/* &lt;![CDATA[ */
   var test = new JSAwesome('validated',[
      ['text_field', 'default value'],
      ['#text_area', ''],
      ['single_select', ['boo', '~yah']]
      ], {   'text_field': "JSAwesome",
       'text_area': {
          'required':true,
          'validation': ["\\d+", "Field must contain atleast one digit"],
          'label': "Input some text with atleast one digit"
       },
       'single_select': {
          'required':true
       },
       '~': 'Custom instructions',
       '{}': ['Select something']
   })
   test.to_html()
   test.addValidation()
   $('form').addEvent('submit', function(e) {
      e.stop()
      if(test.validate()) 
         alert('Passed validation')
    })
/* ]]&gt; */
&lt;/script&gt;
&lt;p&gt;&lt;strong&gt;Bam&lt;/strong&gt;, is your mind completely blown yet? Here&amp;#8217;s an overview of the 3rd parameter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The keys to the hash are either names of elements in the form (_without the special characters_) or one of two special global names &lt;code&gt;~&lt;/code&gt; or &lt;code&gt;{}&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;The values of the hash are either a string or another hash. If it&amp;#8217;s a string, it represents the label for the element specifed. If it&amp;#8217;s a hash you can specify all or one of the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;required&lt;/strong&gt; - a boolean specifying whether the field is required. &lt;em&gt;if it is used for a radio or checkbox group it will require atleast one radio button to be clicked&lt;/em&gt;. It can also be used alongside of &lt;strong&gt;validation&lt;/strong&gt; to make a text input field both required and validated&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;validation&lt;/strong&gt; - a tuple with the first element being a javascript RegEx string. The second is a message to be displayed on failure&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;label&lt;/strong&gt; - the label, just as if you had given only a string, but can be used alongside required and validation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;If the key is &lt;code&gt;~&lt;/code&gt; this specifies the value to be used in custom fields as opposed to the default &amp;#8216;Custom&amp;#8230;&amp;#8217; (_choose &amp;#8216;yah&amp;#8217; from the select box above_)&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;If the key is &lt;code&gt;{}&lt;/code&gt; the value is a tuple with the first element being the default value for the root select element, and the optional second parameter being the default for any sub-selects.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So there you have it. JSAwesome in a nutshell. We use this library over at &lt;a href='http://doloreslabs.com'&gt;Dolores Labs&lt;/a&gt; for easily creating dynamic forms for all of our &lt;a href='http://blog.doloreslabs.com'&gt;experiments&lt;/a&gt;. It beats the crap out of writing HTML forms manually and makes our tasks load a lot faster. We also get validation for free. It currently requires mootools 1.2b, which is packed with the &lt;a href='http://github.com/vanpelt/jsawesome/tree/master'&gt;project&lt;/a&gt;. Fork away!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>6.5 months... not bad</title>
   <link href="http://vandev.com/2007/10/30/6-monthes-not-bad.html" />
   <updated>2007-10-30T00:00:00+00:00</updated>
   <id>http://vandev.com/2007/10/30/6-monthes-not-bad</id>
   <content type="html">&lt;p&gt;Hmmm, well I don&amp;#8217;t know what to say. This will have to do until I come up with something&amp;#8230;&lt;/p&gt;

&lt;p&gt;&lt;img src='http://vandev.com/assets/2007/10/30/dance.gif' alt='Dance baby dance' /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Inside the Croppr frontend</title>
   <link href="http://vandev.com/2007/04/16/inside-the-croppr-frontend.html" />
   <updated>2007-04-16T00:00:00+00:00</updated>
   <id>http://vandev.com/2007/04/16/inside-the-croppr-frontend</id>
   <content type="html">&lt;p&gt;I learned allot creating &lt;a href='http://vandev.com/croppr'&gt;croppr&lt;/a&gt;. It&amp;#8217;s pretty intersting what you can do with the DOM and some CSS. Let&amp;#8217;s take a peek under the hood.&lt;/p&gt;

&lt;p&gt;The first thing croppr does upon instantiation is create a bunch of DOM elements. Here&amp;#8217;s what that looks like.&lt;/p&gt;
&lt;a href='#' id='toggle_styles'&gt;Toggle Styles&lt;/a&gt;&lt;div id='the_styles'&gt;

&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='html'&gt;&amp;lt;div style=&amp;quot;background: white;
            position: absolute;
            top: 0px; left: 0px;
            width: 100%; height: 545px;
            opacity: 0.8;&amp;quot;/&amp;gt; 
&amp;lt;div id=&amp;quot;croppr&amp;quot; style=&amp;quot;overflow: hidden;
                        position: absolute;
                        top: 0px; left: 0px;
                        width: 100%; height: 545px;&amp;quot;&amp;gt;                  
  &amp;lt;div style=&amp;quot;border: 1px solid #000000;
              overflow: hidden;
              position: absolute;
              top: 50%; left: 50%;
              width: 118px; height: 118px;
              margin-top: -60px; margin-left: -60px;&amp;quot;&amp;gt;
    &amp;lt;img src=&amp;quot;/croppr/images/1&amp;quot; style=&amp;quot;cursor: move;
                                       position: absolute;
                                       top: 50%; left: 50%;
                                       margin-top: -272px; margin-left: -357px;
                                       width: 714px; height: 544px;
                                       opacity: 1;&amp;quot;/&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;img src=&amp;quot;/croppr/images/1&amp;quot; style=&amp;quot;cursor: move;
                                     position: absolute;
                                     top: 50%; left: 50%;
                                     margin-top: -272px; margin-left: -357px;
                                     width: 714px; height: 544px;
                                     opacity: 0.3;&amp;quot;/&amp;gt;
  &amp;lt;a class=&amp;quot;exit&amp;quot;&amp;gt;
    &amp;lt;span&amp;gt;EXIT&amp;lt;/span&amp;gt;
  &amp;lt;/a&amp;gt;
  &amp;lt;a class=&amp;quot;crop&amp;quot;&amp;gt;
    &amp;lt;span&amp;gt;CROP&amp;lt;/span&amp;gt;
  &amp;lt;/a&amp;gt;
  &amp;lt;div class=&amp;quot;track&amp;quot;&amp;gt;
    &amp;lt;div class=&amp;quot;handle&amp;quot; style=&amp;quot;cursor: move;
                               position: relative;
                               left: 154.312px;&amp;quot;/&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;



&lt;/div&gt;&lt;script type='text/javascript' charset='utf-8'&gt;
/* &lt;![CDATA[ */
  $('toggle_styles').addEvent('click', toggleStyles);
  function toggleStyles(event) {
    $$('span.style', 'the_styles').each(function(e) {
      var fade = new Fx.Tween(e, {duration:1000, onComplete:function(e){ 
          if(this.to[0].value == 0) {
               e.setStyle('display','none');
               new Element('span', {html:'...'}).inject(e,'before');
          }
      }, onStart: function(e){ 
             e.setStyle('display','inline');
             if(this.from[0].value == 0) e.getPrevious().destroy();
       }
      });
      e.style.visibility == "hidden" ? fade.start( 'opacity', [0,1]) : fade.start( 'opacity', [1,0]);
    });
    event.stop();
  }
  window.addEvent('domready', function(){
     $('second_toggle').addEvent('click', toggleStyles);
     toggleStyles({ stop: function(){} }) 
  });
/* ]]&gt; */
&lt;/script&gt;&lt;a href='#the_styles' id='second_toggle'&gt;Toggle&lt;/a&gt;
&lt;p&gt;The next element is our container for all the fun goodies we&amp;#8217;re about to add (_container_). It serves three purposes.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Makes cleanup easy.&lt;/em&gt; By deleting this element, all the others will disappear.&lt;/li&gt;

&lt;li&gt;&lt;em&gt;Namespaces the rest of our elements.&lt;/em&gt; You can target &lt;code&gt;#croppr .exit&lt;/code&gt; in your CSS without effecting other elements with the class of &lt;code&gt;exit&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;&lt;em&gt;Get&amp;#8217;s rid of vertical and horizontal scroll bars.&lt;/em&gt; By setting &lt;code&gt;overflow:hidden&lt;/code&gt; when the image we are cropping goes outside of the window, the browser doesn&amp;#8217;t add scrollbars and screw up our math.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The transparent box is not placed in this div because we want a nice fade back into the original environment after we have deleted all of the cropping tools. More on this in a little bit.&lt;/p&gt;

&lt;p&gt;Next we have the mask. The width and height of the mask is set to the width and height of the desired crop - 2. We subtract two because it has a 1 pixel border and the box model includes the border in the width and height. A copy of the main image (_ghost_) is put inside of the mask. &lt;code&gt;overflow:hidden&lt;/code&gt; is set on the mask as well, making the parts outside of it invisible. Both the mask and the ghost are positioned absolutely and have &lt;code&gt;top&lt;/code&gt; and &lt;code&gt;left&lt;/code&gt; attributes set to 50%. We then give them negative &lt;code&gt;top&lt;/code&gt; and &lt;code&gt;left&lt;/code&gt; margins. The mask&amp;#8217;s margin&amp;#8217;s will always be half of its width and height, while the ghost&amp;#8217;s margins are based on it&amp;#8217;s current position. This puts the work of keeping the items centered if the window resizes in the hands of the browser. All of this is done rather elegantly with mootools:&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='javascript'&gt;this.mask = new Element(&amp;quot;div&amp;quot;).setStyles({
      border: &amp;quot;1px solid #000&amp;quot;,
      overflow: &amp;quot;hidden&amp;quot;,
      position: &amp;quot;absolute&amp;quot;,
      width: this.options.crop[0]-2+&amp;quot;px&amp;quot;,
      height: this.options.crop[1]-2+&amp;quot;px&amp;quot;,
      top: &amp;quot;50%&amp;quot;,
      left: &amp;quot;50%&amp;quot;, 
      marginTop: -this.options.crop[1]/2+&amp;quot;px&amp;quot;, 
      marginLeft: -this.options.crop[0]/2+&amp;quot;px&amp;quot; 
}).injectInside(this.container);
this.ghost = this.image.clone(false).injectInside(this.mask);&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The image itself is next up. She is infront of the mask so we can drag her around without having the mask conflict. We set the opacity to .3 making the ghosting effect. The positioning of this image is identical to the one inside the mask. Infact, as you drag the image, it&amp;#8217;s css is copied straight into the css of the image inside of the mask. The only difference is the opacity.&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='javascript'&gt;draw: function() {
  this.ghost.style.cssText = this.image.style.cssText;
  this.ghost.setOpacity(1);
}

this.drag = new Drag.Base(this.image, {
  limit: {
    x: [-this.size[0] + this.options.crop[0] / 2, -this.options.crop[0] / 2], 
    y: [-this.size[1] + this.options.crop[1] / 2, -this.options.crop[1] / 2]
  },
  modifiers: {
    x: &amp;quot;margin-left&amp;quot;, 
    y: &amp;quot;margin-top&amp;quot;
  },
  onDrag: this.draw.bind(this)
});&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Mootool&amp;#8217;s awesome &lt;a href='http://docs.mootools.net/Drag/Drag-Base.js'&gt;Drag&lt;/a&gt; class provides a way to constrain the object being drug via the limit parameter in the constructor. This logic is repeated in the scaling function (_updateSlide_) to insure the image is not scaled outside of the mask. This function is the hairiest of them all&amp;#8230; maybe we&amp;#8217;ll dig into her another time.&lt;/p&gt;

&lt;p&gt;Last but not least we have the CROP and EXIT buttons along with the slider itself. These need to be infront of everything else, which is why they are last. There is no styling done explicitly by the croppr javascript library. Instead, it gives you the freedom to style them however you would like.&lt;/p&gt;

&lt;p&gt;When we&amp;#8217;re done using croppr, cleanup is as easy as:&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='javascript'&gt;this.container.remove();
new Fx.Style(this.trans, 'opacity', {duration: 1000, onComplete: this.trans.remove}).start(0.8, 0);&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;And that&amp;#8217;s that, bending the DOM to do your dirty work turns out not to be so bad&amp;#8230;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Croppr, ready for primetime</title>
   <link href="http://vandev.com/2007/04/11/croppr-ready-for-primetime.html" />
   <updated>2007-04-11T00:00:00+00:00</updated>
   <id>http://vandev.com/2007/04/11/croppr-ready-for-primetime</id>
   <content type="html">&lt;p&gt;It&amp;#8217;s been a long time coming&amp;#8230; Croppr has grown out of it&amp;#8217;s infancy. Sparked recently by the release of &lt;a href='http://gravatar.com'&gt;Gravatar 2.0&lt;/a&gt; and the Ruby on Rails podcast &lt;a href='http://podcast.rubyonrails.com/programs/1/episodes/the_camping_episode_ii'&gt;Camping II&lt;/a&gt;, I dove back into the code and cleaned it up. Croppr now adheres to the minimalistic principles of &lt;a href='http://code.whytheluckystiff.net/camping'&gt;Camping&lt;/a&gt;. RMagick was thrown out in favor of &lt;a href='http://seattlerb.rubyforge.org/ImageScience.html'&gt;ImageScience&lt;/a&gt;. The javascript was tweaked for performance and readability using the ever so light and powerfull &lt;a href='http://mootools.net'&gt;MooTools&lt;/a&gt;. The magic is really in the javascript, I encourage you to check &lt;a href='http://svn.vandev.com/croppr/trunk/ext/croppr.js'&gt;it&lt;/a&gt; out. All the pieces come together as a living tutorial of how to implement Croppr on your own. Go &lt;a href='http://vandev.com/croppr'&gt;play&lt;/a&gt; with my vain demo! If you want to get sneaky and upload your own image tag &lt;code&gt;/new&lt;/code&gt; to the end of the URL, but keep it clean&amp;#8230; Here&amp;#8217;s an overview on how to get her up and running on your own machine:&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='javascript'&gt;sudo gem install mongrel
sudo gem install camping
sudo gem install json
sudo gem install sqlite3-ruby (you need to have sqlite3 installed) 
sudo gem install image_science (you need to have freeimage installed)

svn co http://svn.vandev.com/croppr/trunk croppr
cd croppr

ruby croppr.rb&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;It&amp;#8217;s that easy. You should be able to follow the documentation in the javascript and the implementation example in the camping app to get her working yourself. Goodluck, and let me know of any crazy browser issues. I half-assed tested it in IE 6 and 7&amp;#8230; Safari and Firefox are golden.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Mootools and my sidebar, doing it</title>
   <link href="http://vandev.com/2007/03/11/mootools-and-my-sidebar-doing-it.html" />
   <updated>2007-03-11T00:00:00+00:00</updated>
   <id>http://vandev.com/2007/03/11/mootools-and-my-sidebar-doing-it</id>
   <content type="html">&lt;p&gt;This afternoon I was perusing the web and ended up mining &lt;a href='http://yelp.com'&gt;Yelp&lt;/a&gt; for something to do in this new and foreign &lt;a href='http://www.ci.sf.ca.us'&gt;city&lt;/a&gt;. I noticed a slick &lt;a href='http://www.yelp.com/search?find_desc=something+to+do&amp;amp;find_loc=San+Francisco%2C+Ca'&gt;effect&lt;/a&gt; that was used to keep the map in the view port as you scrolled. I had done this before with the &lt;code&gt;position:fixed&lt;/code&gt; css directive, but it&amp;#8217;s rather limited especially in a centered layout. You also can&amp;#8217;t choose your easing equation or delay the effect&amp;#8230; Thanks &lt;a href='http://mootools.net'&gt;Moo&lt;/a&gt;, let&amp;#8217;s do it.&lt;/p&gt;

&lt;p&gt;I added a set of links which link to targets on this &lt;a href='http://vandev.com'&gt;page&lt;/a&gt; in my sidebar entitled &amp;#8220;On this page&amp;#8230;&amp;#8221;. I want the links to scroll the page to the targeted element, and I also want the links to follow me there so I can click on another one if I need to. 8 lines of javascript with the aid of Mootools gets her done.&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='javascript'&gt;var slideEffect = new Fx.Style('sidenav', 'margin-top', {wait:false, duration:800, transition:Fx.Transitions.circOut});
  window.addEvent('load', function() {
    var top = $('sidenav').getPosition().y - 10;
    window.addEvent('scroll', function(){
      slideEffect.start.delay(600, slideEffect, Math.max(0, document.documentElement.scrollTop - top));
    });
    new SmoothScroll({duration:700, transition:Fx.Transitions.circOut});
  });&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Let&amp;#8217;s analyze the crap out of this code. I first create a new Fx.Style specifying &lt;code&gt;wait:false&lt;/code&gt; (_so If I start scrolling down the page and than suddenly switch direction, the effect will simply start over in that new direction_). I&amp;#8217;m modifying the &lt;code&gt;margin-top&lt;/code&gt; property of the &lt;code&gt;sidenav&lt;/code&gt; element. I also specify a custom transition &lt;code&gt;circOut&lt;/code&gt; which starts fast and than slows to a stop. Using &lt;code&gt;window.addEvent(&amp;#39;load&amp;#39;&lt;/code&gt;, I wait for the document to load because the position of my div is relative to the image of my face. You could use the &lt;code&gt;domready&lt;/code&gt; event if the position of the div you will be scrolling is not relative to an image&amp;#8230; Next I get the position of the top of my div and subtract 10 from it to give it some padding.&lt;/p&gt;

&lt;p&gt;Now for the magic. I listen for the &lt;code&gt;scroll&lt;/code&gt; event and when it happens I fire the recently created &lt;code&gt;slideEffect&lt;/code&gt;. However, because the delay is cool and if I don&amp;#8217;t delay the effect will look really jumpy, I delay the start of the effect. Moo provides a delay method which can be called on any function. You have to call it on the function, not on the thing the function returns: e.g. &lt;code&gt;myFunction.delay(100)&lt;/code&gt; or &lt;code&gt;function(){return &amp;#39;rad&amp;#39;}.delay(300)&lt;/code&gt; instead of &lt;code&gt;myFunction(&amp;#39;awesome&amp;#39;).delay(30)&lt;/code&gt;. The second attribute to delay is an object that will become &lt;code&gt;this&lt;/code&gt; in the function delay is being called on. In this case we want &lt;code&gt;this&lt;/code&gt; to be the effect itself. The third attribute is the attribute(s) that will be passed into the function. For us, this is an integer representing the new margin. We calculate this as the maximum of either 0 or the difference of the current viewport offset and the original offset of the image.&lt;/p&gt;

&lt;p&gt;The last thing to do is make a call to &lt;code&gt;SmoothScroll&lt;/code&gt;, making all links that point to a target scroll to the element with that targets id (this was detailed in my &lt;a href='#article_2140'&gt;last&lt;/a&gt; post). So there it is, a detailed description of how my sidebar and mootools did it.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Mootools, a silly Fx tutorial</title>
   <link href="http://vandev.com/2007/02/28/mootools-a-silly-fx-tutorial.html" />
   <updated>2007-02-28T00:00:00+00:00</updated>
   <id>http://vandev.com/2007/02/28/mootools-a-silly-fx-tutorial</id>
   <content type="html">&lt;p&gt;I&amp;#8217;ve been loving &lt;a href='http://mootools.net'&gt;mootools&lt;/a&gt; lately so I figured I would demonstrate some of it&amp;#8217;s awesomeness by explaining a few of the effects generated on this very page.&lt;/p&gt;

&lt;h3 id='awesome_bouncy_nav_tabs__upper_right_funny_creative_projects_'&gt;Awesome bouncy nav tabs (_upper right, funny creative projects_)&lt;/h3&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='javascript'&gt;$$('#header ul li a').each(function(el) {
  var bounce = new Fx.Style(el, 'top', {duration:700, transition: Fx.Transitions.elasticOut});
  var colors = new Fx.Styles(el, {wait:false});
  
  el.addEvent('mouseover', function(){
	el.setStyle('background-color', '#d5e88f');
	bounce.start(15,0);
  	colors.start({
		color: '35342e'
  	});
  });
  el.addEvent('mouseout', function(){
  	colors.start({
		'background-color': '35342e',
		color: 'd5e88f'
  	});
  });
});&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Allright, so moo gives us a DOM selector much like prototypes. I use it to grab all the &lt;code&gt;a&lt;/code&gt; tags in my nav list, and then I iterate over them. Moo has three generic Fx classes, &lt;a href='http://docs.mootools.net/files/Effects/Fx-Style-js.html'&gt;Style&lt;/a&gt;, &lt;a href='http://docs.mootools.net/files/Effects/Fx-Styles-js.html'&gt;Styles&lt;/a&gt;, and &lt;a href='http://docs.mootools.net/files/Effects/Fx-Elements-js.html'&gt;Elements&lt;/a&gt;. I don&amp;#8217;t use Fx.Elements here, but you can read about it via moos excellent &lt;a href='http://docs.mootools.net/files/Core/Moo-js.html'&gt;documentation&lt;/a&gt;. If you are familiar with the scriptaculous Morph effect, these will come natuarlly. They let you tween a list of css attributes, leaving the door of possibilities for amazing custom effects wide open.&lt;/p&gt;

&lt;p&gt;First I create two effects. One to deal with the motion, &lt;em&gt;bounce&lt;/em&gt;, and the other to deal with font and background color, &lt;em&gt;colors&lt;/em&gt;. Moo supplies an &lt;a href='http://mootools.net/download/svn'&gt;optional&lt;/a&gt; set of robust transitions based on Robert Penner&amp;#8217;s &lt;a href='http://www.robertpenner.com/easing/easing_demo.html'&gt;easing&lt;/a&gt; equations (_the easing demo is extremely helpful_). I specify the elasticOut transition upon instantiation of the &lt;em&gt;bounce&lt;/em&gt; effect to make it, well bouncy. Setting &lt;code&gt;wait&lt;/code&gt; to false in the Fx.Styles call tells the effect to go ahead and run even if there is another effect just like it already running. This let&amp;#8217;s the tab fade back to normal if I mouseout before it&amp;#8217;s finished.&lt;/p&gt;

&lt;p&gt;After the effects are created, all that&amp;#8217;s left is attaching them to an event. Voila, crazy cool bouncy tabs.&lt;/p&gt;

&lt;h3 id='a_silly_unobtrusive_smooth_scrolling_effect__click_its_not_what_you_think_next_to_the_vd_logo_'&gt;A silly unobtrusive smooth scrolling effect (_click &amp;#8220;it&amp;#8217;s not what you think&amp;#8221; next to the VD logo_)&lt;/h3&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='javascript'&gt;new SmoothScroll({duration:1000});&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Another &lt;a href='http://mootools.net/download/svn'&gt;optional&lt;/a&gt; effect (thank you kickass building tool), is &lt;a href='http://docs.mootools.net/files/Plugins/SmoothScroll-js.html'&gt;SmoothScroll&lt;/a&gt;. Upon instantiation she finds all of the targets (aka anything with an id) and adds an event to all the &lt;code&gt;a&lt;/code&gt; tags referencing that target (aka href=&amp;#8221;#name_of_target&amp;#8221;), which scrolls the window to that element&amp;#8230; just click it.&lt;/p&gt;

&lt;h3 id='opaque_image_rollover__what_the_flick_'&gt;Opaque image rollover (_what the flick_)&lt;/h3&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='javascript'&gt;$$('div#flickr img').each(function(e){
  var fade = new Fx.Style(e, 'opacity', {wait:false});
  fade.set(.5);
  e.addEvent('mouseover', function(){
	fade.start(1);
  });
  e.addEvent('mouseout', function(){
  	fade.start(.5);
  });
});&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This uses the same techniques as the first effect. The set method allows you to set the initial position of the effect. In this case it makes all of the images 50% opaque when the page loads.&lt;/p&gt;

&lt;p&gt;So there you have it. Mootools is silly powerful and fun. It puts the control in your hands, and does so in a lightweight and extremely sexy manner.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Really awesome, I mean really awesome</title>
   <link href="http://vandev.com/2007/02/12/really-awesome-i-mean-really-awesome.html" />
   <updated>2007-02-12T00:00:00+00:00</updated>
   <id>http://vandev.com/2007/02/12/really-awesome-i-mean-really-awesome</id>
   <content type="html">&lt;p&gt;So back on the 15th of December friend and fellow rubyist, &lt;a href='http://glu.ttono.us'&gt;Kevin Clark&lt;/a&gt;, forwarded me a job description from &lt;a href='http://powerset.com'&gt;Powerset&lt;/a&gt;. Well, I applied to said job and long story short I&amp;#8217;m starting tomorrow! I drove a Budget rental truck up to San Francisco from San Diego on Friday. I don&amp;#8217;t have a place yet&amp;#8230; a slight problem which will hopefully be remedied very soon. Anyway, we had an awesome &lt;a href='http://www.flickr.com/photos/yogurtboy/sets/72157594529172885'&gt;party&lt;/a&gt; last night to celebrate the series A funding, and I&amp;#8217;m excited to get started and settle into San Francisco.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>A mephisto tag cloud</title>
   <link href="http://vandev.com/2007/02/07/a-mephisto-tag-cloud.html" />
   <updated>2007-02-07T00:00:00+00:00</updated>
   <id>http://vandev.com/2007/02/07/a-mephisto-tag-cloud</id>
   <content type="html">&lt;p&gt;As I continue to customize my new &lt;a href='http://mephistoblog.com'&gt;mephisto&lt;/a&gt; installation, I wanted a tag cloud for the Folksonomy section at the bottom of the page. At first I thought I would use a mephisto plugin&amp;#8230; after further consideration I decided that was a little overkill. JavaScript kicks ass, especially with the recent &lt;a href='http://blog.mad4milk.net/entry/mootools-version-1-official-world-release'&gt;release&lt;/a&gt; of &lt;a href='http://mootools.net'&gt;mootools&lt;/a&gt; version 1.0, so I decided to let it do the work. I created a small class called Overcast which makes tag clouds easy peasy japaneasy. So, just how easy is it to get a tag cloud in mephisto? Here&amp;#8217;s a snipet from my layout.liquid&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='html'&gt;mootools
overcast
&amp;lt;/head&amp;gt;

&amp;lt;div id=&amp;quot;overcast&amp;quot;&amp;gt;
  
&amp;lt;/div&amp;gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;
/* &amp;lt;![CDATA[ */
  over = new Overcast({min: 1, fuzz: 2, overlay: &amp;quot;/images/gloss.png&amp;quot;});
/* ]]&amp;gt; */
&amp;lt;/script&amp;gt;&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;A couple sexy things to note are the cool transparent overlays ontop of each tag, and the ability to fuzz tags when your weights aren&amp;#8217;t very diverse. Also, if you&amp;#8217;ve got &lt;a href='http://getfirebug.com'&gt;Firebug&lt;/a&gt; you can type &lt;em&gt;over.update(&amp;#8220;amazing&amp;#8221;,4)&lt;/em&gt; in the console to add a new tag to the cloud with that weight, or &lt;em&gt;over.update(&amp;#8220;javascript&amp;#8221;, 3)&lt;/em&gt; to change the weight of an existing tag. All of the functionality is documented in the source.&lt;/p&gt;

&lt;p&gt;Grab the &lt;a href='http://vandev.com/javascripts/overcast.js'&gt;source&lt;/a&gt; from the include in this page. I&amp;#8217;ll put it under version control soon.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Mephisto is finally up and running</title>
   <link href="http://vandev.com/2007/01/12/mephisto-is-finally-up-and-running.html" />
   <updated>2007-01-12T00:00:00+00:00</updated>
   <id>http://vandev.com/2007/01/12/mephisto-is-finally-up-and-running</id>
   <content type="html">&lt;p&gt;Dang, procrastination is a terrible terrible thing. I had been doing allot of traveling prior to the Holidays and just didn&amp;#8217;t have the motivation needed to put the time into setting up &lt;a href='http://www.mephistoblog.com'&gt;Mephisto&lt;/a&gt;. I finnaly got around to doing it, and it went pretty well. The Typo conversion didn&amp;#8217;t happen as smoothly as I had hoped and I had to hack the Flickr plugin a bit to get her up and going, but she&amp;#8217;s finally here. This time around I shouldn&amp;#8217;t rank as #1 on Google for a series of absurdly explicit terms describing grotesque sexual actions&amp;#8230; Thank you &lt;a href='http://akismet.com'&gt;Akismet&lt;/a&gt;. I also decided to drop the blog from blog.vandev.com. From now on, this is vandev.com.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve got a couple new little projects that I&amp;#8217;ll release in the near future. &lt;a href='http://merb.devjavu.com/'&gt;Merb&lt;/a&gt; has entertained me as of late, as well as &lt;a href='http://mootools.mad4milk.net/'&gt;MooTools&lt;/a&gt;. Anyway, I&amp;#8217;ll get them up and I&amp;#8217;ll finish polishing the site. Polishing it until it shines.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The title says it all</title>
   <link href="http://vandev.com/2007/01/06/the-title-says-it-all.html" />
   <updated>2007-01-06T00:00:00+00:00</updated>
   <id>http://vandev.com/2007/01/06/the-title-says-it-all</id>
   <content type="html">&lt;p&gt;The title&amp;#8217;s kinda funny right? I&amp;#8217;m working on it, something real funny will be here soon!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>MaxMind GeoLite on Rails with PostGIS</title>
   <link href="http://vandev.com/2006/10/15/maxmind-geolite-on-rails-with-postgis.html" />
   <updated>2006-10-15T00:00:00+00:00</updated>
   <id>http://vandev.com/2006/10/15/maxmind-geolite-on-rails-with-postgis</id>
   <content type="html">&lt;p&gt;Ughhhh, many hours of frustration have been spent trying to push the MaxMind GeoLite City CSV &lt;a href='http://www.maxmind.com/app/geolitecity'&gt;files&lt;/a&gt; into a database configured with &lt;a href='http://postgis.refractions.net/'&gt;PostGIS&lt;/a&gt;. Anyway, I figured I would document the process that I went through incase someone else wants some free IP based geocoding in there Rails app.&lt;/p&gt;

&lt;p&gt;MaxMind gives you two CSV files for the city database. One has an assload (2,783,434) of IP blocks that map to the id of a row in the other table containing location data. The location data is pretty rich. It contains a postal code, area code, dma code, country, region (state in US), and a latitude and longitude. Because I wanted to be cool and more efficient, I decided to store the lat / lon as a point in PostGIS format. Using PostGIS along with Guilhem Vellut&amp;#8217;s Spatial Adaptor &lt;a href='http://thepochisuperstarmegashow.com/projects/'&gt;plugin&lt;/a&gt; for Rails, makes doing geo-spatial operations sexier and easier than ever. You can use the Spatial Adaptor with MySQL, but you&amp;#8217;ll never be as cool as the guy using it with PostgreSQL.&lt;/p&gt;

&lt;p&gt;First off I had to create my tables.&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='ruby'&gt;create_table &amp;quot;geo_ip_locations&amp;quot; do |t|
  t.column &amp;quot;country&amp;quot;, :string, :limit =&amp;gt; 2
  t.column &amp;quot;region&amp;quot;, :string, :limit =&amp;gt; 2
  t.column &amp;quot;city&amp;quot;, :string
  t.column &amp;quot;postal_code&amp;quot;, :string, :limit =&amp;gt; 7
  t.column &amp;quot;dma_code&amp;quot;, :integer, :limit =&amp;gt; 3
  t.column &amp;quot;area_code&amp;quot;, :integer, :limit =&amp;gt; 3
  t.column &amp;quot;geom&amp;quot;, :point, :null =&amp;gt; false, :srid =&amp;gt; 4269, :with_z =&amp;gt; false
end

add_index :geo_ip_locations, :geom, :spatial =&amp;gt; true

create_table &amp;quot;geo_ips&amp;quot; do |t|
  t.column &amp;quot;start_ip&amp;quot;, :integer, :limit =&amp;gt; 10
  t.column &amp;quot;end_ip&amp;quot;, :integer, :limit =&amp;gt; 10
  t.column &amp;quot;geo_ip_location_id&amp;quot;, :integer
end

add_index :gep_ips, :start_ip
add_index :geo_ips, :end_ip
add_index :geo_ips, :geo_ip_location_id&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;A few things to note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The geom column has the srid set to 4269, this threw me for a loop for way too long. Make sure you have the &lt;code&gt;spatial_ref_sys&lt;/code&gt; table populated. I&amp;#8217;m also assuming that the MaxMind data is mapped to the WGS 84 standard.&lt;/li&gt;

&lt;li&gt;The limit&amp;#8217;s on the start and end ip&amp;#8217;s are set to 10. This creates bigint columns in my DB. I&amp;#8217;m not sure what version of Rails started doing this (I&amp;#8217;m on Edge), but the columns have to be bigints for the IP block information to be imported.&lt;/li&gt;

&lt;li&gt;Remember to create a couple models for the tables&lt;/li&gt;

&lt;li&gt;You may want to add an index on postal_code or anything else you&amp;#8217;ll be using in a SQL WHERE clause&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now because the CSV file with the blocks of IP addresses in it is so large I went with an importing tool to get it into the table. I was going to use PostgreSQL&amp;#8217;s COPY command, but it doesn&amp;#8217;t seem to support CSV&amp;#8217;s with double quotes. I went with &lt;a href='http://pgsql.navicat.com/download.html'&gt;Navicat&lt;/a&gt; and took advantage of my 30 day trial. The CSV with the locations in it is another story. We need to convert the lat / lon pairs into points for PostGIS. Not only that, but if we want to be really cool we need to convert the city names into UTF-8. The file that MaxMind gives us has ISO-8859-1 encoding. &lt;a href='http://www.gnu.org/software/libiconv/documentation/libiconv/iconv.1.html'&gt;Iconv&lt;/a&gt; comes to the rescue. You can either convert the entire file from the command line, or just use the ruby library to do it in the import script below.&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='ruby'&gt;require &amp;quot;#{File.dirname(__FILE__)}/../../config/environment&amp;quot;
require 'fastercsv'
require 'iconv'
ICONV = Iconv.new( 'UTF-8', 'ISO-8859-1' )

FasterCSV::HeaderConverters[:underscore] = lambda { |h| h.underscore }

FasterCSV.foreach('geo_ip_locations.csv', {:headers =&amp;gt; :first_row, :col_sep =&amp;gt; &amp;quot;,&amp;quot;, :header_converters =&amp;gt; :underscore}) do |row|
  begin
    row['id'] = row.delete('loc_id')[1]
    row['geom'] = Point.from_x_y(row.delete('longitude')[1].to_f, row.delete('latitude')[1].to_f, 4326)
    row['city'] = ICONV.iconv(row['city'])
    cool = GeoIpLocation.new(row.to_hash)
    cool.id = row['id']
    cool.save!
    $stdout.print '.'
  rescue
    puts $!.message
    $stdout.print 'f'
  end
  $stdout.flush
end&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Things to note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need FasterCSV for this to work &lt;code&gt;gem install fastercsv&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;You need to delete the first line (_with the copyright info in it_) in the CSV for this script to work.&lt;/li&gt;

&lt;li&gt;If you converted the file from the command line, comment out the three lines referencing iconv to improve performance.&lt;/li&gt;

&lt;li&gt;I created a directory called &lt;code&gt;transform&lt;/code&gt; in my &lt;code&gt;db&lt;/code&gt; directory, renamed and moved the location CSV there, and created a file with the above code in it.&lt;/li&gt;

&lt;li&gt;Always remember to put the srid in the &lt;code&gt;Point.from_x_y&lt;/code&gt; call, otherwise you&amp;#8217;ll be very very frustrated.&lt;/li&gt;

&lt;li&gt;You&amp;#8217;ll need to specify &lt;code&gt;encoding: unicode&lt;/code&gt; &lt;em&gt;Postgres&lt;/em&gt;, &lt;code&gt;encoding: utf8&lt;/code&gt; &lt;em&gt;MySQL&lt;/em&gt; in database.yml to use UTF-8 with the DB. See the Rails &lt;a href='http://wiki.rubyonrails.org/rails/pages/HowToUseUnicodeStrings'&gt;wiki&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;The id is set this way to preserve it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That&amp;#8217;s it! There you have it, the possibilities are now endless. As I said before, I set this up on PostgreSQL, but this should work the same on MySQL. The one main difference will be the srid&amp;#8217;s. MySQL doesn&amp;#8217;t support them, so you don&amp;#8217;t need to specify them. Goodluck!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>QuickPresent</title>
   <link href="http://vandev.com/2006/10/06/quickpresent.html" />
   <updated>2006-10-06T00:00:00+00:00</updated>
   <id>http://vandev.com/2006/10/06/quickpresent</id>
   <content type="html">&lt;p&gt;I threw together a quick and simple way to make a presentation on a mac using &lt;a href='http://quicksilver.blacktree.com/'&gt;Quicksilver&lt;/a&gt; and &lt;a href='http://code.whytheluckystiff.net/camping'&gt;Camping&lt;/a&gt; a while back. Well, I finally got around to refining it and putting it into a both tiny and awesome package. This puppy is made of two files, and makes presenting dead simple. You just outline your thoughts in a text file, and QuickPresent smacks it onto your screen using Quicksilver&amp;#8217;s &lt;em&gt;largetype&lt;/em&gt; feature. Not only that, but it also gives you a slick little web interface to show you what you&amp;#8217;ve said, and what you&amp;#8217;re about to say. Let me show you&amp;#8230;&lt;/p&gt;
&lt;img title='QuickPresent preview' src='http://vandev.com/assets/2007/2/1/Picture_1.png' width='600' /&gt;
&lt;p&gt;A few other slick features include automatically opening URL&amp;#8217;s and Files from your hard drive. All you need is Camping and Quicksilver (with the &lt;em&gt;command line tool (qs)&lt;/em&gt; plugin installed). Just type &lt;code&gt;camping quickpresent.rb&lt;/code&gt; from the command line and your up running. If you want to try something cheaper than Keynote or Powerpoint, play with QuickPresent. Let me know what you think.&lt;/p&gt;

&lt;p&gt;Get it from my SVN Repo: &lt;a href='http://svn.vandev.com/presenter'&gt;http://svn.vandev.com/presenter&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Croppr podcast... a little late</title>
   <link href="http://vandev.com/2006/09/22/croppr-podcast-a-little-late.html" />
   <updated>2006-09-22T00:00:00+00:00</updated>
   <id>http://vandev.com/2006/09/22/croppr-podcast-a-little-late</id>
   <content type="html">&lt;p&gt;The SDRuby &lt;a href='http://podcast.sdruby.com'&gt;podcast site&lt;/a&gt; is filling up with great episodes. One of which being my little talk on camping and &lt;a href='http://www.vandev.com/croppr'&gt;Croppr&lt;/a&gt; (Episode 002 on the bottom). The thing has been up for a couple of monthes now, but my posting consistency has been miserable lately. I&amp;#8217;ve had more &lt;a href='http://www.vanblog.net/archives/88-Wow,-its-a-record.html'&gt;pressing issues&lt;/a&gt;, but today is a new day. My next project will be pushing this thing over to &lt;a href='http://www.mephistoblog.com'&gt;Mephisto&lt;/a&gt;. I should also spend some time fixing the Rails date_select helper, but that&amp;#8217;s another post all together. The next time I speak, the entire back end of this puppy will be different&amp;#8230; totally awesome.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Croppr is born... perhaps pre-mature</title>
   <link href="http://vandev.com/2006/07/05/croppr.html" />
   <updated>2006-07-05T00:00:00+00:00</updated>
   <id>http://vandev.com/2006/07/05/croppr</id>
   <content type="html">&lt;p&gt;So, I finally got around to testing TextMate&amp;#8217;s new blogging bundle. It&amp;#8217;s dead simple&amp;#8230; Anywho, I figured I would use it to give a sneak peek of my newest invention &lt;em&gt;Croppr&lt;/em&gt;, which I will be revealing in it&amp;#8217;s full glory tomorrow night at &lt;a href='http://sdruby.com'&gt;SDruby&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;All right, so Croppr was born out of a desire to make a better way to crop images online. Specifically the need came from my buddy &lt;a href='http://www.cube6media.com'&gt;Tom Werner&amp;#8217;s&lt;/a&gt; pet project, &lt;a href='http://gravatar.com'&gt;Gravatar&lt;/a&gt;. The inspiration came from iChat&amp;#8217;s avatar cropper:&lt;/p&gt;

&lt;p&gt;&lt;img src='http://vandev.com/assets/2007/2/1/iChat_cropper.png' alt='iChat Cropper' /&gt;&lt;/p&gt;

&lt;p&gt;After days of arduous JavaScript hacking with the help of &lt;a href='http://prototype.conio.net'&gt;Prototype&lt;/a&gt; and eventually Prototype Lite with &lt;a href='http://moofx.mad4milk.net/'&gt;moo.fx&lt;/a&gt; I had a lightweight browser equivalent. Have a &lt;a href='http://svn.vandev.com/croppr'&gt;peek&lt;/a&gt; and play around.&lt;/p&gt;

&lt;p&gt;What good is a lightweight JavaScript cropper without a lightweight back end to actually do the cropping? Enter &lt;a href='http://code.whytheluckystiff.net/camping'&gt;camping&lt;/a&gt;. In just 225 lines of &lt;a href='http://svn.vandev.com/croppr'&gt;sexy Ruby code&lt;/a&gt; I have a fully functional image cropping machine. I hope to have a running demo available in the near future. As far as licensing goes, I&amp;#8217;m still working on it so hold your shorts. Until than, come to the SDruby meetup (start driving now if you have to) and see all the awesomeness that is Croppr!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>EDGE and a <strike>UFO</strike> Satellite</title>
   <link href="http://vandev.com/2006/06/27/edge-and-a-ufo.html" />
   <updated>2006-06-27T00:00:00+00:00</updated>
   <id>http://vandev.com/2006/06/27/edge-and-a-ufo</id>
   <content type="html">&lt;p&gt;I have just witnessed quite the spectacle. About 15 minutes ago, I saw something strange outside of the Encinitas Ca Starbucks on the 101. In the twilight sky over the vast Pacific a UFO appeared. Screaming up from the horizon the strange object slowed abruptly and than continued on it&amp;#8217;s path South-Southeast. At the place where it slowed a large smoke plume appeared which seemed to get brighter as the sky darkened. Fortunately I had my new W600i camera phone. I snapped 8 pics and used the phones wireless modem feature to link up to the EDGE network and send &lt;a href='http://www.flickr.com/photos/vanpelt/sets/72157594180026564/'&gt;them&lt;/a&gt; to Flickr.&lt;/p&gt;
&lt;pre class='markdown-html-error' style='border: solid 3px red; background-color: pink'&gt;REXML could not parse this XML/HTML: 
&amp;lt;typo:flickr img=&amp;quot;176781709&amp;quot; size=&amp;quot;medium&amp;quot;/&amp;gt;&lt;/pre&gt;
&lt;p&gt;I watched as the object seemed to emit some type of vapor sporadically as it trailed off. This was definitely not a comet and had to have been something engineered&amp;#8230; &lt;em&gt;upon further review it must have been a satellite being launched from somewhere in the Pacific&lt;/em&gt; I&amp;#8217;m very curious to see if there were any other sightings. As far as the validity of these photos go, I know the quality is poor but check out the upload timestamps on Flickr. If there were other sightings, this could easily be verified. Crazy stuff.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt; __________________________________&lt;/p&gt;

&lt;p&gt;It is now confirmed that this was no UFO, nay it was a Delta IV rocket launching a NROL-22 reconnaissance satellite into orbit. Here&amp;#8217;s the &lt;a href='http://www.boeing.com/news/releases/2006/q2/060627b_nr.html'&gt;press release&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It was launched from &lt;a href='http://local.google.com/local?f=q&amp;amp;hl=en&amp;amp;q=Vandenberg+Air+Force+Base&amp;amp;ie=UTF8&amp;amp;ll=34.939985,-120.552979&amp;amp;spn=3.926252,10.667725&amp;amp;om=1'&gt;Vandenburg AFB&lt;/a&gt; just north of Santa Barbara. I&amp;#8217;m glad it wasn&amp;#8217;t aliens or the Koreans&amp;#8230;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>RMagick on Mac OS X 10.4 Tiger</title>
   <link href="http://vandev.com/2006/06/06/rmagick-on-mac-os-x-10-4-tiger.html" />
   <updated>2006-06-06T00:00:00+00:00</updated>
   <id>http://vandev.com/2006/06/06/rmagick-on-mac-os-x-10-4-tiger</id>
   <content type="html">&lt;p&gt;Recently I needed Rmagick installed on my Mac OS X 10.4 system. This turned out to be nearly impossible, until I got down and dirty and just went for a fresh compile from source. Actually it became more impossible until I found enlightenment on the long and arduous journey. The following is a pretty bare-bones install. It leaves out excess functionality like exporting to &lt;a href='ftp://ftp.remotesensing.org/libtiff/'&gt;TIFF&lt;/a&gt;, working with &lt;a href='http://www.cs.wisc.edu/~ghost/'&gt;PostScript or PDF&lt;/a&gt; files, &lt;a href='http://www.littlecms.com/'&gt;color management&lt;/a&gt;, &lt;a href='http://sourceforge.net/projects/libexif'&gt;EXIF&lt;/a&gt; headers, &lt;a href='http://xmlsoft.org/'&gt;SVG&lt;/a&gt; images, or &lt;a href='http://sourceforge.net/projects/wvware/'&gt;MSWord&lt;/a&gt; documents. All of this functionality can be added by downloading the source from the links above, and compiling them before you run &lt;code&gt;./configure&lt;/code&gt; for ImageMagick. You can also install GraphicsMagick if you like, it shouldn&amp;#8217;t make a difference which one you use.&lt;/p&gt;

&lt;p&gt;The following instructions will have you up and running in no time (actually about 30 minutes depending on the speed of your system &lt;em&gt;ImageMagick takes forever&lt;/em&gt;). These instructions assume you have installed Ruby according to the instructions at &lt;a href='http://hivelogic.com/articles/2005/12/01/ruby_rails_lighttpd_mysql_tiger'&gt;HiveLogic&lt;/a&gt;. If you have not, make sure you atleast follow the steps up to the point of installing ruby. This makes sure your path is correct and your build environment is in place.&lt;/p&gt;

&lt;p&gt;X11:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;4 Tiger install DVD or http://www.apple.com/downloads/macosx/apple/x11formacosx.html&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Freetype2:&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='bash'&gt;curl -O http://umn.dl.sourceforge.net/sourceforge/freetype/freetype-2.2.1.tar.gz
tar zxvf freetype-2.2.1.tar.gz
cd freetype-2.2.1
./configure &amp;amp;&amp;amp; make &amp;amp;&amp;amp; sudo make install
cd ..&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Jpeg:&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='bash'&gt;curl -O ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz
tar zxvf jpegsrc.v6b.tar.gz
cd jpeg-6b
ln -s `which glibtool` ./libtool
export MACOSX_DEPLOYMENT_TARGET=10.4
./configure --enable-shared &amp;amp;&amp;amp; make &amp;amp;&amp;amp; sudo make install
cd ..&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;PNG:&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='bash'&gt;curl -O http://umn.dl.sourceforge.net/sourceforge/libpng/libpng-1.2.10-no-config.tar.gz
tar zxvf libpng-1.2.10-no-config.tar.gz
cd libpng-1.2.10
cp scripts/makefile.darwin Makefile
make &amp;amp;&amp;amp; sudo make install
cd ..&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;ImageMagick:&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='bash'&gt;curl -O http://umn.dl.sourceforge.net/sourceforge/imagemagick/ImageMagick-6.2.8-0.tar.gz
tar zxvf ImageMagick-6.2.8-0.tar.gz
cd ImageMagick-6.2.8
./configure &amp;amp;&amp;amp; make &amp;amp;&amp;amp; sudo make install
cd ..&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;RMagick (finally and thankfully):&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='bash'&gt;sudo gem install rmagick&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;That&amp;#8217;s it, goto &lt;a href='http://rmagick.rubyforge.org/'&gt;RMagick&lt;/a&gt;&amp;#8217;s web site for information on using RMagick in your apps. Be on the look out for an incredible little &lt;a href='http://code.whytheluckystiff.net/camping/'&gt;Camping&lt;/a&gt; app that uses the power of RMagick to appear on VD soon!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Why do online banking websites blow?</title>
   <link href="http://vandev.com/2006/05/13/why-do-online-banking-websites-blow.html" />
   <updated>2006-05-13T00:00:00+00:00</updated>
   <id>http://vandev.com/2006/05/13/why-do-online-banking-websites-blow</id>
   <content type="html">&lt;p&gt;Recently my health insurance changed from a high deductible plan to a more reasonable PPO. Anyway I still have an HSA from my previous plan. I thought it might be a good idea to transfer my HSA money into my IRA&amp;#8230; wow more acronyms than the w3c. After finding the &lt;a href='http://www.1hsa.com'&gt;website&lt;/a&gt; of my HSA provider, I decide to sign up for an account. This is what I got:&lt;/p&gt;

&lt;p&gt;&lt;img src='http://vandev.com/assets/2007/2/1/Picture_2.png' alt='Leesports Signup Page' /&gt;&lt;/p&gt;

&lt;p&gt;First off, the logo and the layout are simply stunning. Secondly, if you haven&amp;#8217;t already, take a closer look at the requirements for both the user id and the password. Why the H are they requiring such a random user id? It&amp;#8217;s requirements are way higher than that of the passords. Why only 4 characters of headway? How are you supposed to create anything even remotely meaningful? After 3 - 5 minutes of deep thought I was able to come up with something amusing, but I&amp;#8217;m a power user, I doubt there demographic is even capable of figuring out how to make a user id&amp;#8230; If they really need this crap to be that random, why not just hand out a random id?&lt;/p&gt;

&lt;p&gt;As if this weren&amp;#8217;t enough, I was prompted to use there advanced forgotten password system before I could continue. Take a look:&lt;/p&gt;

&lt;p&gt;&lt;img src='http://vandev.com/assets/2007/2/1/Picture_3.png' alt='Leesports Forgotten Password System' /&gt;&lt;/p&gt;

&lt;p&gt;Boy, they were right on the money with this one. For starters, they opened up a new window for me, thanks Leesport, can&amp;#8217;t get enough windows. And the questions&amp;#8230; &amp;#8220;my favorite president?&amp;#8221;, who has a favorite president? You&amp;#8217;ve gotta love the assumption that all of Leesport&amp;#8217;s customers have pets and love sports, why wouldn&amp;#8217;t they?&lt;/p&gt;

&lt;p&gt;Finally after getting into this valuable service that Leesport is offering it&amp;#8217;s customers, I found it to be utterly worthless. There was a transfers tab, but of course this did nothing. How can such a high profile site blow so hardcore? The friggin thing looks like a highschool project.&lt;/p&gt;

&lt;p&gt;I can honestly say that &lt;a href='http://www.leesportfc.com/'&gt;Leesport&lt;/a&gt;&amp;#8217;s service is by far the worst experience I have had with online banking. &lt;a href='http://us.hsbc.com'&gt;HSBC&lt;/a&gt; comes in at a close second. Fortunately, I found someone that cares about design and functionality in &lt;a href='http://www.bankofamerica.com'&gt;Bank of America&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Introducing AjaxSpy</title>
   <link href="http://vandev.com/2006/05/04/my-first-tool-for-you.html" />
   <updated>2006-05-04T00:00:00+00:00</updated>
   <id>http://vandev.com/2006/05/04/my-first-tool-for-you</id>
   <content type="html">&lt;p&gt;While playing with the new RJS templates in rails, I found it difficult to know what was actually being returned from my requests. Thus, AjaxSpy was born. It&amp;#8217;s a simple JavaScript and CSS file. All you need to do is include the js file in the header of your document, the css is automagically included (must be in the stylesheets directory). The script relies on Prototype 1.5.0rc0, and for it to be sexy you need the Scriptaculous effects library. You can include it conditionaly based on params in the query string, or do some fancy session stuff. That&amp;#8217;s all up to you. This is what I&amp;#8217;ve been doing&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;
    &lt;code class='ruby'&gt;&amp;lt;%= javascript_include_tag &amp;quot;prototype&amp;quot;, &amp;quot;effects&amp;quot; %&amp;gt;
&amp;lt;%= javascript_include_tag &amp;quot;debugger&amp;quot; if params[&amp;quot;debug&amp;quot;] %&amp;gt;&lt;/code&gt;
  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The script is currently only working with Firefox and Safari, I&amp;#8217;ll work on the bastard child that is IE down the road. Here&amp;#8217;s what it looks like, syntax highlighting and all:&lt;/p&gt;
&lt;a href='http://vandev.com/assets/2007/2/1/AjaxSpy.png' title='AjaxSpy Preview'&gt;&lt;img src='http://blog.vandev.com/files/AjaxSpy.png' alt='AjaxSpy Preview' width='640px' /&gt;&lt;/a&gt;
&lt;p&gt;I present to you, AjaxSpy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://vandev.com/assets/2007/2/1/debugger.js'&gt;debugger.js&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://vandev.com/assets/2007/2/1/debug.css'&gt;debug.css&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Again, to install simply include the js in the layout, it automagically includes the css (as long as it&amp;#8217;s in a directory named &amp;#8220;stylesheets&amp;#8221; relative to the site route). Let me know if you have any problems.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>A new beginning</title>
   <link href="http://vandev.com/2006/05/04/a-new-beginning.html" />
   <updated>2006-05-04T00:00:00+00:00</updated>
   <id>http://vandev.com/2006/05/04/a-new-beginning</id>
   <content type="html">&lt;p&gt;So, a little over a year ago, I started www.vanblog.net. It was my first experience blogging, and I didn&amp;#8217;t really know what I wanted. Well, I have a better idea now. The problem with VanBlog was that it was either too personal or too tech for different audiences. Enter, VanDev. This is my effort to take the tech out of VanBlog. I also needed a place to put projects that I&amp;#8217;m working on a place to thrive&amp;#8230; I don&amp;#8217;t even know what that means.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ll take this time to address questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Why VanDev?&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Last name = Van Pelt, it&amp;#8217;s both dutch and awesome.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;What&amp;#8217;s VanBlog?&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;That would be my personal blog now, where I talk about things like my feelings and changes occuring in my body.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;VD?&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;VanDev, it&amp;#8217;s not what you think.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;What&amp;#8217;s with these old entries?&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;They were brought over from VanBlog.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Do you where size 12 shoes?&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Yes, as a matter of fact I do.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, there it is. I&amp;#8217;ll post something awesome soon about the design of this blog. Oh, you just wait.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Adelphia, getting a taste of its own medicine</title>
   <link href="http://vandev.com/2005/07/25/adelphia-getting-a-taste-of-its-own-medicine.html" />
   <updated>2005-07-25T00:00:00+00:00</updated>
   <id>http://vandev.com/2005/07/25/adelphia-getting-a-taste-of-its-own-medicine</id>
   <content type="html">&lt;p&gt;Recently I moved to a new apartment. We decided to cancel service and get service with a new provider. Adelphia SUCKS. They questioned me for &amp;#8220;illegal&amp;#8221; server activity. I made an FTP server to back up one of my servers back home, and the freaked out because they saw activity on port 21 and 22. Anyway, it turns out that Adelphia is the only cable company that offers service in my area. A month ago I made an appointment with Adelphia to &amp;#8220;set up&amp;#8221; my Internet. It just so happened that during the 2 hour window they gave me to be home, I had other arrangements. I asked them to come towards the end of the window, instead they came at the beginning and all hope was lost. The next available slot was a week from the following Saturday from 1-5. I wasn&amp;#8217;t going to commit a four hour time slot on a Saturday afternoon, so I said &amp;#8216;F&amp;#8217; it and bought an external WIFI antenna for my laptop. That&amp;#8217;s when the fun started.&lt;/p&gt;

&lt;p&gt;Things were going swimmingly until my neighbor caught on. One day the connection was WEP&amp;#8217;ed. Fortunately I was able to hop on to another neighbors. It didn&amp;#8217;t last long until they WAP&amp;#8217;ed theirs (I have no idea how they knew I was on, probably bandwidth). Anyway, that was my last option. I ground my teeth, and called Adelphia to set up an appointment. That was when the unbelievable happened. I came home from work today, desperate for Internet, and I decided to try and plug my cable modem into the wall. I had thought about it before, but wrote off the possibility of the modem just hopping onto the network. Well, I&amp;#8217;ve waisted the past month without Internet, when I could have had it for free. I&amp;#8217;m cruising now, will Adelphia find out?&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Your own personal Geocoder... for FREE</title>
   <link href="http://vandev.com/2005/07/18/your-own-personal-geocoder-for-free.html" />
   <updated>2005-07-18T00:00:00+00:00</updated>
   <id>http://vandev.com/2005/07/18/your-own-personal-geocoder-for-free</id>
   <content type="html">&lt;p&gt;After the release of the google maps &lt;a href='http://www.google.com/apis/maps'&gt;api&lt;/a&gt;, I began working on custom applications. Because google doesn&amp;#8217;t allow address lookups in its api, you have to generate a latitude and longitude yourself for a given address. The immediate problem was the need for geocoding, preferably geocoding within php. This is where the &lt;a href='http://www.census.gov'&gt;US Census&lt;/a&gt; comes in. The easiest solution is to download a mysql dump of all the zips with there corresponding lat/longs. That mysql dump can be found &lt;a href='http://civicspacelabs.org/home/developers/download'&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, this is great, but it&amp;#8217;s not detailed enough. I needed to geocode to the street level. &lt;a href='http://geocoder.us'&gt;geocoder.us&lt;/a&gt; offers a free web service for doing this but you can only make one request every 15 seconds. I have a database of 3500 addresses, so that wasn&amp;#8217;t going to work. geocoder.us uses the US census&amp;#8217;s &lt;a href='http://www2.census.gov/geo/tiger/tiger2004fe/'&gt;Tiger Data&lt;/a&gt;, and the perl &lt;a href='http://search.cpan.org/~sderle/Geo-Coder-US/US.pm'&gt;Geo::Coder::US&lt;/a&gt; module. The problem with this solution is the amount of time it would take compile. You have to download every zip file from every state, and than compile it. I&amp;#8217;m not patient enough. Thats when I found &lt;a href='http://dan.egnor.name/google.html'&gt;Dan Egnor&lt;/a&gt;. Dan won the 2002 Google Programing contest with a program that does just what I needed it to. Read on to do it yourself.&lt;/p&gt;

&lt;p&gt;Ok, so the biggest issue is skipping out of the compile process. &lt;a href='http://dan.egnor.name/google.html'&gt;Dan&lt;/a&gt; offers a free &lt;a href='http://dan.egnor.name/all-map.bz2'&gt;download&lt;/a&gt; of a bz2&amp;#8217;ed version (~300mb) of the compiled address location data (by the way, the README on his site is good reading material). Dans program does more than I needed it to, so I simplified his source code (Thanks Dan) to do simply what needs to be down. It can be downloaded &lt;a href='http://gpx.vanblog.net/geocoder.tar.bz2'&gt;here&lt;/a&gt;. Simply download my source, &lt;code&gt;bunzip2&lt;/code&gt; the map data from Dans site (assuming Linux here), and tar -jxvf the source, run make on the source and issue a command like &lt;code&gt;./geo-coder (location of the map data ex. ../../all-map) &amp;#39;(the address you want to find)&amp;#39;&lt;/code&gt;. This returns either SUCCESS or FAILURE. Some simple php code will execute and return the address within your web app:&lt;/p&gt;
&lt;pre class='markdown-html-error' style='border: solid 3px red; background-color: pink'&gt;REXML could not parse this XML/HTML: 
&amp;lt;typo:code lang=&amp;quot;php&amp;quot;&amp;gt;
$progress = array();
exec(&amp;quot;./geo-coder ../all-map &amp;apos;$address&amp;apos;&amp;quot;, $progress);
if(substr($progress[0],0,7) == &amp;quot;SUCCESS&amp;quot;){
 //The below returns an array with, $ll[0] = longitude and $ll[1] = latitude from Dan&amp;apos;s program
 $ll = explode(&amp;quot;, &amp;quot;,trim(substr(strstr($progress[3], &amp;apos;@&amp;apos;),1)));
}else{
 //use a zipcode (from the query or DB table in my case) to find the lat/long in the mysql zip database
 $zips =&amp;amp; $db-&amp;gt;query(&amp;apos;SELECT latitude, longitude FROM zipcodes WHERE zip = &amp;apos;.$row[&amp;apos;zip&amp;apos;]);
}
&amp;lt;/typo:code&amp;gt;&lt;/pre&gt;
&lt;p&gt;So there it is. A geocoder in no time at all. The geocoder is about 80% effective (according to Dan). If enough interest is created with this post, I will create a torrent of the most up to date Tiger address information, which should improve the accuracy. Don&amp;#8217;t hesitate to email me at vanpelt@gmail.com if you have questions or requests.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Google maps continues to amaze me</title>
   <link href="http://vandev.com/2005/06/08/google-maps-continues-to-amaze-me.html" />
   <updated>2005-06-08T00:00:00+00:00</updated>
   <id>http://vandev.com/2005/06/08/google-maps-continues-to-amaze-me</id>
   <content type="html">&lt;p&gt;I was browsing around today, and I found an interesting &lt;a href='http://slashdot.org/articles/05/06/08/203208.shtml?tid=217&amp;tid=1'&gt;article&lt;/a&gt; on slashdot. It had to do with third party uses of google maps, and google cutting down on them. There turns out to be some amazing stuff being done google maps and third party software. As mentioned earlier, there was the gps in the car use but these applications are just too cool. My favorite was a tool that took craigslist rental listings and displayed them in your area dependent upon price. There is also a site that points out sites to see from the satellite imagery.&lt;/p&gt;

&lt;p&gt;In order of coolnees:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://www.housingmaps.com/'&gt;Housing Maps&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://googlesightseeing.com/'&gt;Google Siteseeing&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.chicagocrime.org/'&gt;Chicago Crime&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.ahding.com/cheapgas/'&gt;Cheap Gas&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Who knows what will pop up next???&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>WiFi in your car?</title>
   <link href="http://vandev.com/2005/04/20/wifi-in-your-car.html" />
   <updated>2005-04-20T00:00:00+00:00</updated>
   <id>http://vandev.com/2005/04/20/wifi-in-your-car</id>
   <content type="html">&lt;p&gt;I found this article in slashdot about wifi in your car. In all actuality I&amp;#8217;m writing this article on the 28th, but I&amp;#8217;ve been thinking about this idea for a while and it needs to be written down. I was un-aware of the ability to supply WiFi over the cell network at high speeds and a reasonable price until this was brought to my attention. Tor Amundson has a &lt;a href='http://moro.fbrtech.com/~tora/EVDO/index.html'&gt;site&lt;/a&gt; detailing the process of creating a WiFi access point for your car using an EVDO pcmcia card. EVDO can deliver around 300kbs in it&amp;#8217;s major supported areas (big cities), 100kbs in normal digital service areas (smaller cities), and 5kbs in remote areas (the sticks). The best part is, it is a flat fee of $80 a month for unlimited access.&lt;/p&gt;

&lt;p&gt;Tor uses his device for some pretty cool stuff. He hooked up a GPS unit to the router and it syncs with &lt;a href='http://stuff.rancidbacon.com/gmaps-standalone/'&gt;Google Maps Standalone&lt;/a&gt; on a server else where. This allows for a web application that displays the exact location of a given vehicle as long as it has Internet. The cellphone networks are key here. There is Internet offered via satellite, but the satellites are too small a target to hit in motion. The first application of this that came to mind was in the RV market. Because my father deals allot with RV&amp;#8217;s, and I generally deal with the technical end, I saw this as a great fit. Imagine the possibilities. Anyone in the coach could hook up to the WiFi and be surfing the net, going down the road. The server could be synced with the coach systems. In particular the engine heater and thermometers so you could check the temp of the coach from your house, or Japan for that matter. Security is also a big plus in this area. You could have web cams and the works, right there at your finger tips.&lt;/p&gt;

&lt;p&gt;Beyond the RV market, my next thought was Emergency Vehicles. The possibilities are endless. You have the Internet in your vehicle now, out of this world. I hope to be thinking about this idea further and hopefully applying it soon. I should be moving back to Iowa mid summer. I will soon be immersed once again in the RV world. Look out world, here comes the Internet!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Mi Casa... Google Maps</title>
   <link href="http://vandev.com/2005/04/11/mi-casa-google-maps.html" />
   <updated>2005-04-11T00:00:00+00:00</updated>
   <id>http://vandev.com/2005/04/11/mi-casa-google-maps</id>
   <content type="html">&lt;a href='maps.google.com'&gt;Google maps&lt;/a&gt;&lt;a href='http://maps.google.com/maps?q=3475+Roosevelt+St,Carlsbad+Ca&amp;ll=33.154625,-117.345507&amp;spn=0.005879,0.009291&amp;t=k&amp;hl=en'&gt;Try&lt;/a&gt;</content>
 </entry>
 
 <entry>
   <title>Bad things have happened</title>
   <link href="http://vandev.com/2005/04/02/bad-things-have-happened.html" />
   <updated>2005-04-02T00:00:00+00:00</updated>
   <id>http://vandev.com/2005/04/02/bad-things-have-happened</id>
   <content type="html">&lt;p&gt;The blog was down for over a day. With all of the traffic I&amp;#8217;ve been getting this is a huge deal&amp;#8230; Actually, I had a few other larger projects on the server that were down as well. After around 3 hours on the phone with my father, it&amp;#8217;s all up and running again.&lt;/p&gt;

&lt;p&gt;The downtime was due to a faulty cat5 cable, we believe. It was ridiculous. At first we figured it was the router so we bought a new one. After playing with cat5 configurations we discovered it wasn&amp;#8217;t the router. Our next step was to reboot the server. I was biting my teeth. The server had been running for 216 consecutive days (Debian!). It booted smoothly and we&amp;#8217;re up and running now!&lt;/p&gt;

&lt;p&gt;The experience will definitely force me to make more backups more often. It&amp;#8217;s really difficult living in California and having your personal server in Iowa. I&amp;#8217;m blessed to have a father with time and patience.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Seperating presentation and application logic</title>
   <link href="http://vandev.com/2005/03/23/seperating-presentation-and-application-logic.html" />
   <updated>2005-03-23T00:00:00+00:00</updated>
   <id>http://vandev.com/2005/03/23/seperating-presentation-and-application-logic</id>
   <content type="html">&lt;p&gt;I was browsing around for different web application development solutions. I&amp;#8217;m well acquainted with PHP and I have done some separation of logic with &lt;a href='http://smarty.php.net'&gt;Smarty&lt;/a&gt;. Smarty only does so much, and basically is just a cleaner way of presenting data. Almost a hybrid PHP. After a few articles dealing with J2EE and struts I found some php solutions for making a Model View Controller based web app. I also learned a little about Java based web design, which is interesting as well.&lt;/p&gt;

&lt;p&gt;As far as the Java solution goes there are really two decent ways of doing it from what I understand. You could use &lt;a href='http://struts.apache.org/'&gt;Struts&lt;/a&gt; or &lt;a href='http://jakarta.apache.org/tapestry/'&gt; Tapestry&lt;/a&gt;. Struts functions as a controller object for the web application realm. If you want to know more about the Model View Controller paradigm &lt;a href='http://en.wikipedia.org/wiki/Model_View_Controller'&gt;check out&lt;/a&gt; wikipedia&amp;#8217;s answer. Basically through the use of an XML configuration file you tell struts what to do with actions from the UI. The view and model stay the same as any web application would. In this case the view is generally written in JSP and the model done with servlets. I am by know means an expert so if you want to know more check out there website.&lt;/p&gt;

&lt;p&gt;After surfing around for a little while I found allot of complaint about the learning curve for Struts. I also read some complaints about the functionality. There was an interesting &lt;a href='http://books.slashdot.org/comments.pl?sid=49106&amp;threshold=1&amp;commentsort=0&amp;tid=108&amp;tid=6&amp;mode=thread&amp;pid=4989593'&gt;explanation&lt;/a&gt; of Tapestry on slashdot. Tapestry gives a level of abstraction to the web application. You know longer refer to URI&amp;#8217;s or add query parameters, you think of everything in terms of objects, methods, and parameters. This seems like a very helpful way of programming a large project. It is just one more step in making a web application more like a desktop app.&lt;/p&gt;

&lt;p&gt;Well, I&amp;#8217;m a PHP guy, and I don&amp;#8217;t see my self migrating to Java anytime soon. There are two good solutions out there that I know of currently: &lt;a href='http://wact.sourceforge.net/'&gt;WACT&lt;/a&gt; and &lt;a href='http://wact.sourceforge.net/'&gt;PHPTAL&lt;/a&gt;. Both seem like good solutions. WACT looks a little more feature rich, but PHPTAL is based on &lt;a href='http://zope.org'&gt;Zope&lt;/a&gt;. Zope a very mature application server. It too is an option for a large scale project. I&amp;#8217;ll be sure to experiment with the PHP implementations in all of my free time. I&amp;#8217;m just looking for the cleanest and most extensible way to create a web application. At the very least looking at all of these techniques gets the mind into learning mode.&lt;/p&gt;</content>
 </entry>
 
 
</feed>
