<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Fuel Your Coding &#187; Languages</title>
	<atom:link href="http://fuelyourcoding.com/category/languages/feed/" rel="self" type="application/rss+xml" />
	<link>http://fuelyourcoding.com</link>
	<description></description>
	<lastBuildDate>Tue, 03 Jan 2012 11:01:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>10 Tools &amp; Frameworks for Responsive Design</title>
		<link>http://fuelyourcoding.com/10-tools-frameworks-for-responsive-design/</link>
		<comments>http://fuelyourcoding.com/10-tools-frameworks-for-responsive-design/#comments</comments>
		<pubDate>Fri, 23 Dec 2011 00:33:03 +0000</pubDate>
		<dc:creator>Joel Falconer</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Languages]]></category>

		<guid isPermaLink="false">http://fuelyourcoding.com/?p=1448</guid>
		<description><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
]]></description>
			<content:encoded><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
<p>Like webfonts, <a href="http://www.alistapart.com/articles/responsive-web-design/" target="_blank">responsive design</a> wasn’t something you heard much about until CSS3 specs started making it into popular browsers. Now, it’s the cool thing to do, and for good reason — it means one site to maintain for all devices. But it’s also a really challenging approach to web design. In this article, we look at 10 tools that’ll help you handle the challenge.</p>
<h2>320 and up</h2>
<p style="text-align: center; "><a href="http://www.stuffandnonsense.co.uk/projects/320andup/"><img class="size-full wp-image-1453 aligncenter" title="320andup" src="http://fuelyourcoding.com/files/320andup.jpg" alt="320andup" width="592" height="208" /></a></p>
<p>Most responsive designs are built with full desktop size in mind and scaled down from there. Andy and Keith Clark, the developers behind 320 and up, believe the opposite approach works best: design for the small screen, and implement the layout working upwards in size. <a href="http://www.stuffandnonsense.co.uk/projects/320andup/" target="_blank">320 and up</a> contains Media Query increments for five viewport sizes, a vertical grid, preset styles for typography and components from HTML5 Boilerplate.</p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">inuit.css</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">inuit.css is a HTML5 framework that uses a grid system that scales down to small screens ‘out of the box’. It’s a minimalist approach, giving you just what you need to get started without unnecessary styles, but it’s extensible and there are a range of handy plugins available for it — such as one that creates breadcrumb trails out of ordered lists.</div>
<h2>inuit.css</h2>
<p style="text-align: center; "><a href="http://csswizardry.com/inuitcss/"><img class="size-full wp-image-1456 aligncenter" title="inuitcss" src="http://fuelyourcoding.com/files/inuitcss.jpg" alt="inuitcss" width="592" height="300" /></a></p>
<p><a href="http://csswizardry.com/inuitcss/" target="_blank">inuit.css</a> is a HTML5 framework that uses a grid system that scales down to small screens ‘out of the box’. It’s a minimalist approach, giving you just what you need to get started without unnecessary styles, but it’s extensible and there are a range of handy plugins available for it — such as one that creates breadcrumb trails out of ordered lists.</p>
<h2>Skeleton</h2>
<p style="text-align: center; "><a href="http://getskeleton.com/"><img class="size-full wp-image-1457 aligncenter" title="skeleton" src="http://fuelyourcoding.com/files/skeleton.jpg" alt="skeleton" width="592" height="374" /></a></p>
<p><a href="http://getskeleton.com/" target="_blank">Skeleton</a> is a light collection of CSS and JavaScript files that make designing responsive sites based on the 960px grid easy. Skeleton includes some basic styling and typography presets to get you out of the gate quickly. This project is the brainchild of Dave Gamache, formerly of esteemed UX firm ZURB and now on Twitter’s design team.</p>
<h2>Less Framework</h2>
<p style="text-align: center; "><a href="http://lessframework.com/"><img class="size-full wp-image-1458 aligncenter" title="lessframework" src="http://fuelyourcoding.com/files/lessframework.jpg" alt="lessframework" width="592" height="351" /></a></p>
<p><a href="http://lessframework.com/" target="_blank">Less Framework</a> is a CSS starter with four layouts — default at 992px, and tablet, mobile and wide mobile sizes — based on a grid system and including a selection of typography presets. Because Less Framework is one of the most popular options, there’s a range of supporting tools such as a Rails gem, OmniGraffle stencil and Compass plugin built around Less.</p>
<h2>BluCSS</h2>
<p style="text-align: center; "><a href="http://www.designlunatic.com/projects/blucss/"><img class="size-full wp-image-1459 aligncenter" title="blucss" src="http://fuelyourcoding.com/files/blucss.jpg" alt="blucss" width="592" height="289" /></a></p>
<p><a href="http://www.designlunatic.com/projects/blucss/" target="_blank">BluCSS </a>is a CSS framework that, as usual, uses a flexible grid to facilitate responsive design. One feature that stands out is its responsive images, something many of these frameworks leave out; apply a class to your images and they’ll scale with your design. No need to include multiple files at multiple sizes, though be wary of unnecessary load on mobile devices with this approach.</p>
<h2>Mobile Boilerplate</h2>
<p style="text-align: center; "><a href="http://html5boilerplate.com/mobile"><img class="size-full wp-image-1460 aligncenter" title="mobileboilerplate" src="http://fuelyourcoding.com/files/mobileboilerplate.jpg" alt="mobileboilerplate" width="592" height="186" /></a></p>
<p>From the developers behind the famous HTML5 Boilerplate comes <a href="http://html5boilerplate.com/mobile" target="_blank">Mobile Boilerplate</a>, a responsive template that puts the focus on mobile devices, namely those running Android, iOS, Blackberry and Symbian software. Everything from viewport scaling to HTML5 offline caching to home screen icons are ready to go.</p>
<h2>Tiny Fluid Grid</h2>
<p style="text-align: center; "><a href="http://www.tinyfluidgrid.com/"><img class="size-full wp-image-1461 aligncenter" title="tinyfluidgrid" src="http://fuelyourcoding.com/files/tinyfluidgrid.jpg" alt="tinyfluidgrid" width="592" height="265" /></a></p>
<p>If you find all these CSS frameworks to be too much for your needs, <a href="http://www.tinyfluidgrid.com/" target="_blank">Tiny Fluid Grid</a> may be the alternative you’re looking for. Simply tell it how many columns your grid will need, how big you want your gutters and how wide the site will be, and this site will spit out a responsive fluid grid you can use right away.</p>
<h2>Golden Grid System</h2>
<p style="text-align: center; "><a href="http://goldengridsystem.com/"><img class="size-full wp-image-1462 aligncenter" title="goldengrid" src="http://fuelyourcoding.com/files/goldengrid.jpg" alt="goldengrid" width="592" height="217" /></a></p>
<p>The <a href="http://goldengridsystem.com/" target="_blank">Golden Grid System</a> is a 16 column grid that uses a folding method inspired by the DIN paper system to collapse down to 8 columns on tablet-size screens and 4 columns on mobile screens, making it work for designs that range from 240 to 2560 pixels wide. The GGS developers say their folding method is superior to others because the gutters are better at staying in proportion with the content, producing less of a squeezed (or sparse, depending on direction) look.</p>
<h2>1140 CSS Grid</h2>
<p style="text-align: center;"><a href="http://cssgrid.net/"><img class="size-full wp-image-1463 aligncenter" title="1140" src="http://fuelyourcoding.com/files/1140.jpg" alt="1140" width="592" height="247" /></a></p>
<p>The <a href="http://cssgrid.net/" target="_blank">1140 CSS Grid</a> takes the opposite approach of the 320 and up system. This is primarily aimed at people who really want to design for a wider 1280 pixel screen, and are sick of catering to a 1024 pixel baseline. 1140 CSS Grid allows them to do that while fluidly re-arranging to fit on smaller screens all the way down to mobile.</p>
<h2>Respond.js</h2>
<p>Even before you start working on a responsive design, you may be worried about visitors using browsers that don’t support media queries, the CSS3 feature that responsive sites depend on. With <a href="https://github.com/scottjehl/Respond" target="_blank">Respond.js</a>, this problem is easily solved; the script makes min-width and max-width work in Internet Explorer 6, 7 and 8, and should work with other browsers lacking support.</p>
<h2>Bonus: ZURB Foundation</h2>
<p><img class="aligncenter size-full wp-image-1472" title="foundation" src="http://fuelyourcoding.com/files/foundation.jpg" alt="foundation" width="592" height="412" /></p>
<p>ZURB&#8217;s <a href="http://foundation.zurb.com/">Foundation</a> is a newer entry among responsive design frameworks, and is one of the most promising, having already won over many users of other frameworks. Billed as an easy-to-use yet powerful framework for building both prototypes and production deployments that work across all kinds of devices, Foundation makes use of a flexible grid, a library of styles and elements for rapid prototyping, and professes to take the pain out of creating layouts for different formats with the same markup.</p>
]]></content:encoded>
			<wfw:commentRss>http://fuelyourcoding.com/10-tools-frameworks-for-responsive-design/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Getting Started with jQuery Mobile &amp; Rails 3</title>
		<link>http://fuelyourcoding.com/getting-started-with-jquery-mobile-rails-3/</link>
		<comments>http://fuelyourcoding.com/getting-started-with-jquery-mobile-rails-3/#comments</comments>
		<pubDate>Tue, 26 Oct 2010 13:06:15 +0000</pubDate>
		<dc:creator>Jerod Santo</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Languages]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jquery mobile]]></category>
		<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">http://fuelyourcoding.com/?p=1341</guid>
		<description><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>

&#60;head&#62;
  &#60;title&#62;Jqmoblog&#60;/title&#62;
  &#60;link rel=&#34;stylesheet&#34; href=&#34;http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.css&#34; /&#62;
  &#60;%= javascript_include_tag :defaults %&#62;
  &#60;script src=&#34;http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.js&#34;&#62;&#60;/script&#62;
  &#60;%= csrf_meta_tag %&#62;
&#60;/head&#62;

Okay, everything is in place. Now we&#8217;re ready to turn this into a mobile app!
Getting Started
Before we flesh out our mobile CRUD actions, let&#8217;s get the posts index looking decent in mobile browsers. jQuery Mobile relies [...]]]></description>
			<content:encoded><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
<p>The very promising <a href="http://jquerymobile.com/">jQuery Mobile</a> project is now in its first Alpha release! What better time to give it a spin with our (err&#8230; my) <a href="http://rubyonrails.org">favorite web framework</a>?!</p>
<p>You should read jQuery Mobile&#8217;s <a href="http://jquerymobile.com/demos/1.0a1/#docs/about/intro.html">official introduction</a> section to familiarize yourself with its principles, but in a few words: you include it on the page, format your markup to conform to its requirements and reap the benefits. Yay, let&#8217;s write a (very contrived) <a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</a> application with Rails 3 and jQuery Mobile!</p>
<h2>Setup</h2>
<p>Our application will allow us to create, read, update and delete blog posts (remember when I said it was contrived? Uhm..yah) from mobile devices. If you don&#8217;t have Rails 3 installed yet, you can get it via <a href="http://rubygems.org">RubyGems</a>:</p>
<pre class="brush: plain;">
gem install rails
</pre>
<p>Use the <tt>rails</tt> command line tool to generate a new application. We&#8217;ll call it <strong>jqmoblog</strong>.</p>
<pre class="brush: plain;">
rails new jqmoblog
# ... a bunch of files are created
cd jqmoblog
</pre>
<p>As of Rails 3.0.1 you cannot specify jQuery as the JavaScript tool of choice when you generate a Rails application, but we can easily swap it in by using the handy, dandy <a href="http://github.com/indirect/jquery-rails">jquery-rails</a> gem. Edit the <tt>Gemfile</tt> in the project&#8217;s root directory and add a dependency on the gem. Once finished your <tt>Gemfile</tt> will look something like this:</p>
<pre class="brush: ruby;">
source 'http://rubygems.org'

gem 'rails', '3.0.1'
gem 'sqlite3-ruby', :require =&gt; 'sqlite3'
gem 'jquery-rails'
</pre>
<p>Install the required gems using the <tt>bundle</tt> command line tool:</p>
<pre class="brush: plain;">
bundle install
</pre>
<p>Now we&#8217;ll use the Rails generator added by the <tt>jquery-rails</tt> gem to get all the jQuery files we need:</p>
<pre class="brush: plain;">
rails generate jquery:install
</pre>
<p>When prompted, allow it to overwrite <tt>rails.js</tt>.</p>
<p>We&#8217;re almost ready. The application skeleton is in place and jQuery has replaced the Rails default JavaScript libraries, but we&#8217;re missing the basic model, controller, and views for our application.</p>
<p>Thankfully, Rails has a generator which will create these files for us and its called the <tt>scaffold</tt> generator. We&#8217;ll keep the blog posts in our app super-simple since we&#8217;re really just using them to learn about jQuery Mobile. Each post will have a title and a body. Generate the scaffold for a Post resource like this:</p>
<pre class="brush: plain;">
rails generate scaffold Post title:string body:text
</pre>
<p>This command will provide a list of files and directories it created. There should be a model (<tt>app/models/post.rb</tt>), a controller (<tt>app/controller/posts_controller.rb</tt>), and a directory of views (<tt>app/views/posts</tt>) for our Post resource.</p>
<p>Run the database migration that was created from the <tt>scaffold</tt> command so our database has a <tt>posts</tt> table with the required columns for storing our posts:</p>
<pre class="brush: plain;">
rake db:migrate
</pre>
<p>At this point you can fire up a Rails server and the app will load up in your browser:</p>
<pre class="brush: plain;">
rails server
</pre>
<p>Point your browser to <tt>http://localhost:3000</tt> and you should see this:</p>
<p style="text-align: center;"><img src="http://fuelyourcoding.com/files/default.png" alt="default" title="default" width="549" height="518" class="aligncenter size-full wp-image-1363" /></p>
<p>Hmm, before we get to mobilizing this application, let&#8217;s make the root url load the list of our posts instead of the default Rails index file:</p>
<pre class="brush: plain;">
rm public/index.html
</pre>
<p>Edit the <tt>config/routes.rb</tt> and set the root route like so:</p>
<pre class="brush: ruby;">
Jqmoblog::Application.routes.draw do
  resources :posts
  root :to =&gt; &quot;posts#index&quot;
end
</pre>
<p>Now load up <tt>http://localhost:3000</tt> again and you should see the empty list of posts.</p>
<p>We still need to get the jQuery Mobile files on the page. Lets use the ones hosted on <a href="http://jquery.com">jquery.com</a>. Add them to the application&#8217;s <tt>layout</tt> file so they&#8217;ll be on every page that gets served. In <tt>app/views/layouts/application.html.erb</tt>, edit the <tt>head</tt> section to look like this:</p>
<pre class="brush: xml;">
&lt;head&gt;
  &lt;title&gt;Jqmoblog&lt;/title&gt;
  &lt;link rel=&quot;stylesheet&quot; href=&quot;http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.css&quot; /&gt;
  &lt;%= javascript_include_tag :defaults %&gt;
  &lt;script src=&quot;http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.js&quot;&gt;&lt;/script&gt;
  &lt;%= csrf_meta_tag %&gt;
&lt;/head&gt;
</pre>
<p>Okay, everything is in place. <em>Now</em> we&#8217;re ready to turn this into a mobile app!</p>
<h2>Getting Started</h2>
<p>Before we flesh out our mobile CRUD actions, let&#8217;s get the posts index looking decent in mobile browsers. jQuery Mobile relies directly on the page&#8217;s markup to work its magic, so to invoke it we just need to change our views to conform to its conventions.</p>
<p>Each &#8220;page&#8221; in a jQuery Mobile application needs to be wrapped in a <tt>div</tt> with a <tt>data-role</tt> attribute of <tt>page</tt>. I put &#8220;page&#8221; in quotes because there can actually be many of them on a single webpage loaded from the server. In our app we&#8217;ll be loading each &#8220;page&#8221; from Rails, so we should just add this to our layout file which will wrap each of our individual views:</p>
<p><strong>Before</strong></p>
<pre class="brush: xml;">
&lt;body&gt;
  &lt;%= yield %&gt;
&lt;/body&gt;
</pre>
<p><strong>After</strong></p>
<pre class="brush: xml;">
&lt;body&gt;
  &lt;div data-role=&quot;page&quot;&gt;
    &lt;%= yield %&gt;
  &lt;/div&gt;
&lt;/body&gt;
</pre>
<p>Next edit the post&#8217;s index (<tt>index.html.erb</tt>) and change the markup to create a header and a content section which lists all the posts in the database.</p>
<p><strong>Before</strong></p>
<pre class="brush: xml;">
&lt;h1&gt;Listing posts&lt;/h1&gt;

&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;Title&lt;/th&gt;
    &lt;th&gt;Body&lt;/th&gt;
    &lt;th&gt;&lt;/th&gt;
    &lt;th&gt;&lt;/th&gt;
    &lt;th&gt;&lt;/th&gt;
  &lt;/tr&gt;

&lt;% @posts.each do |post| %&gt;
  &lt;tr&gt;
    &lt;td&gt;&lt;%= post.title %&gt;&lt;/td&gt;
    &lt;td&gt;&lt;%= post.body %&gt;&lt;/td&gt;
    &lt;td&gt;&lt;%= link_to 'Show', post %&gt;&lt;/td&gt;
    &lt;td&gt;&lt;%= link_to 'Edit', edit_post_path(post) %&gt;&lt;/td&gt;
    &lt;td&gt;&lt;%= link_to 'Destroy', post, :confirm =&gt; 'Are you sure?', :method =&gt; :delete %&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;% end %&gt;
&lt;/table&gt;

&lt;br /&gt;

&lt;%= link_to 'New Post', new_post_path %&gt;
</pre>
<p><strong>After</strong></p>
<pre class="brush: xml;">
&lt;div data-role=&quot;header&quot;&gt;
  &lt;h1&gt;Listing posts&lt;/h1&gt;
&lt;/div&gt;

&lt;div data-role=&quot;content&quot;&gt;
  &lt;ul data-role=&quot;listview&quot;&gt;
    &lt;% @posts.each do |post| %&gt;
    &lt;li&gt;
      &lt;%= link_to post.title, post %&gt;
      &lt;%= link_to 'edit post', edit_post_path(post), &quot;data-icon&quot; =&gt; &quot;gear&quot; %&gt;
    &lt;/li&gt;
    &lt;% end %&gt;
  &lt;/ul&gt;
&lt;/div&gt;
</pre>
<p>Load up the page and it should look like this:</p>
<p style="text-align: center;"><img src="http://fuelyourcoding.com/files/base.png" alt="base" title="base" width="472" height="615" class="aligncenter size-full wp-image-1365" /></p>
<p>Two things to note here. First, we are once again using the <tt>data-role</tt> attribute to create the header and the styled list. This is a major theme of jQuery Mobile (as of the Alpha, I&#8217;m told they <em>*might*</em> be switching to class names instead of data- attributes). Second, each list item has two links, and jQuery Mobile automatically knows that this means we want to use a <a href="http://jquerymobile.com/demos/1.0a1/#docs/lists/lists-split.html">split button list</a>. Pretty cool, huh?</p>
<p>Let&#8217;s add a button which will take us to a page where we can create new posts. Add this line to the end of the header <tt>div</tt>:</p>
<pre class="brush: xml;">
&lt;%= link_to 'Add', new_post_path, &quot;data-icon&quot; =&gt; &quot;plus&quot;, &quot;class&quot; =&gt; &quot;ui-btn-right&quot; %&gt;
</pre>
<p>Again, jQuery Mobile &#8220;just knows&#8221; that this should be a button in our header and we pass it a class and a <tt>data-icon</tt> attribute to tell it where to place it and which icon to use. We now have a button in the header which links to the new post path!</p>
<p style="text-align: center;"><img src="http://fuelyourcoding.com/files/base-add.png" alt="base-add" title="base-add" width="472" height="615" class="aligncenter size-full wp-image-1366" /></p>
<h2>Create</h2>
<p>We&#8217;re gonna need to create posts so we can read, update and delete them, so lets handle creation first. The &#8220;Add&#8221; button on the posts index links to the <tt>new.html.erb</tt> view. It works as is and looks okay too. We&#8217;ll just tweak the markup to make it fit into the jQuery Mobile styles:</p>
<pre class="brush: xml;">
&lt;div data-role=&quot;header&quot;&gt;
  &lt;h1&gt;New Post&lt;/h1&gt;
&lt;/div&gt;

&lt;div data-role=&quot;content&quot;&gt;
  &lt;%= render 'form' %&gt;
&lt;/div&gt;
</pre>
<p>We can now add new posts using the mobile interface! Go ahead and create a few so the posts index shows a list with links to edit each post:</p>
<p style="text-align: center;"><img src="http://fuelyourcoding.com/files/base-posts.png" alt="base-posts" title="base-posts" width="472" height="615" class="aligncenter size-full wp-image-1367" /></p>
<h2>Read</h2>
<p>People will read posts from their <tt>show.html.erb</tt> view. Again, no change to the underlying controller or model code needs to happen. Just update the view file to look like this:</p>
<pre class="brush: xml;">
&lt;div data-role=&quot;header&quot;&gt;
  &lt;h1&gt;&lt;%= @post.title %&gt;&lt;/h1&gt;
  &lt;%= link_to 'Home', posts_url, &quot;class&quot; =&gt; &quot;ui-btn-right&quot; %&gt;
&lt;/div&gt;

&lt;div data-role=&quot;content&quot;&gt;
  &lt;%= @post.body %&gt;
&lt;/div&gt;
</pre>
<p style="text-align: center;"><img src="http://fuelyourcoding.com/files/post-show.png" alt="post-show" title="post-show" width="472" height="615" class="aligncenter size-full wp-image-1368" /></p>
<h2>Update</h2>
<p>When we set up the posts index we added links to the <tt>edit.html.erb</tt> view using the gear icon on the right side of the split list. Now we just need to change the markup on that view to conform to jQuery Mobile&#8217;s requirements. Have you sniffed out a pattern to this development process yet?</p>
<pre class="brush: xml;">
&lt;div data-role=&quot;header&quot;&gt;
  &lt;h1&gt;Editing Post&lt;/h1&gt;
&lt;/div&gt;

&lt;div data-role=&quot;content&quot;&gt;
  &lt;%= render 'form' %&gt;
&lt;/div&gt;
</pre>
<p>Again, it just works as expected and it will look great on many mobile devices. On to the final action, delete!</p>
<h2>Delete</h2>
<p>To facilitate deleting a post we just have to modify the delete links created by Rails&#8217; scaffold generator to fit the rest of the mobile site. I think the edit page is a good place to add a delete link, so lets add a button to the header of <tt>edit.html.erb</tt>:</p>
<pre class="brush: xml;">
&lt;%= link_to 'Delete', @post, :method =&gt; :delete, &quot;data-icon&quot; =&gt; &quot;delete&quot;, &quot;class&quot; =&gt; &quot;ui-btn-right&quot; %&gt;
</pre>
<p>The edit view is now complete, and it lets us update and delete our post.</p>
<p style="text-align: center;"><img src="http://fuelyourcoding.com/files/post-edit.png" alt="post-edit" title="post-edit" width="472" height="615" class="aligncenter size-full wp-image-1369" /></p>
<h2>Closing Up</h2>
<p>If you&#8217;ve made it this far, you&#8217;ve probably realized that working with jQuery Mobile is pretty painless and it fits in with Rails quite well. There are a bunch of other things that jQuery Mobile can do, but this should hopefully whet your appetite. Remember, the framework is still in the <strong>Alpha</strong> stage so things can and probably will change.</p>
<p>I encourage you to <a href="http://jquerymobile.com/">read more</a> about the project and get involved at an early stage so we can all benefit from a strong community!</p>
<p style="text-align: center;"><a href="http://fuelyourcoding.com/files/jqmoblog.zip">***Download the source code for the application built in this post***</a></p>
]]></content:encoded>
			<wfw:commentRss>http://fuelyourcoding.com/getting-started-with-jquery-mobile-rails-3/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>WebKit&#8217;s JavaScript Profiler Explained</title>
		<link>http://fuelyourcoding.com/webkits-javascript-profiler-explained/</link>
		<comments>http://fuelyourcoding.com/webkits-javascript-profiler-explained/#comments</comments>
		<pubDate>Mon, 11 Oct 2010 12:56:41 +0000</pubDate>
		<dc:creator>Jerod Santo</dc:creator>
				<category><![CDATA[Developer Tools]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Languages]]></category>
		<category><![CDATA[Plugins / Add-Ons]]></category>
		<category><![CDATA[profiling]]></category>
		<category><![CDATA[web inspector]]></category>
		<category><![CDATA[webkit]]></category>

		<guid isPermaLink="false">http://fuelyourcoding.com/?p=1316</guid>
		<description><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
]]></description>
			<content:encoded><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
<p>The trend toward rich client-side web applications has brought with it a need for robust JavaScript development tools. <a href="http://getfirebug.com/">Firebug</a> lead the way in this arena, but WebKit&#8217;s <a href="http://trac.webkit.org/wiki/WebInspector">Web Inspector</a> has caught up in a big way and ships with all recent versions of Safari <strong>and</strong> Chrome.</p>
<p>One powerful tool inside Web Inspector that is likely under utilized is the <em><strong>Profiles</strong></em> pane. I write <strong>a lot</strong> of client-side JavaScript and it still took me a long time to work up the gusto to dig into this tool and get anything out of it. If you find yourself in the position I was in, hopefully this post will give you what you need to get up and running quickly.</p>
<h2>Basics</h2>
<p>The JavaScript profiler is used to find and alleviate CPU bottlenecks in your code. To use it you invoke one or more &#8220;profile&#8221; runs in which Web Inspector tracks all JavaScript executed on the page and the time taken to execute it. In the picture below you will see a single profile called &#8220;<strong>Profile 1</strong>&#8221; being displayed.</p>
<p><img src="http://fuelyourcoding.com/files/base-1.png" alt="base-1" title="base-1" width="600" height="400" class="aligncenter size-full wp-image-1320" /></p>
<p>There are two ways to run a profile:</p>
<h3>1) Manually</h3>
<p>The pane itself has a little button in the lower left-hand corner which can be used to start and stop a profile. This is the least precise of the two methods, but is sometimes good enough for one-off profiles. Click it once, go perform whatever action on the page that invokes the code you want profiled, and then click it again to stop.</p>
<h3>2) Programmatically</h3>
<p>The way I suggest you invoke profile runs is by calling into the console directly from your code. This will allow you to precisely position the start and stop of the profile for maximum signal to noise ratio. Here is how you might profile a totally contrived <tt>for</tt> loop programmatically:</p>
<pre class="brush: jscript;">
console.profile('for loop');
for (var i = 0; i &lt; 100; i++) {
  console.log('i is: ', i);
}
console.profileEnd('for loop');
</pre>
<p>After that bit of code is executed a new profile titled &#8220;for loop&#8221; will appear in the Profiles pane to be reviewed. The string argument to these functions is optional. If you don&#8217;t provide one it will simply increment &#8220;Profile [x]&#8221; like it does when run manually.</p>
<h2>The Lingo</h2>
<p>Now we know what the <em><strong>Profiles</strong></em> pane looks like and how to make it run, but its of no use unless we can derive meaning from the results. We can&#8217;t do that without understanding the terms used, so here are explanations as I understand them:</p>
<p><strong>Self</strong> &mdash; the amount of time spent directly in the corresponding function</p>
<p><strong>Total</strong> &mdash; the amount of time spent in the corresponding function and all functions called by it</p>
<p><strong>Calls</strong> &mdash; how many times the corresponding function was called</p>
<p><strong>Average</strong> &mdash; the value of the corresponding function&#8217;s <strong>Self</strong> divided by its <strong>Calls</strong></p>
<p>Of these, <strong>Self</strong> and <strong>Total</strong> are the most confusing. The key thing to know is that the profiler tracks not only the time spent in each individual function, but also the time spent in functions called by that function. This is very useful when &#8220;drilling down&#8221; on a stack of function calls because you can look to see if the <strong>Total</strong> is bigger than the <strong>Self</strong> and if it is you know the time-consuming function is nested beneath the current one. </p>
<h2>Everything&#8217;s Relative (or Absolute)</h2>
<p>By default the <strong><em>Profiles</em></strong> pane displays all information in relative times so that each function is assigned a percentage of the total time of the profile. This is helpful in some scenarios, but I find the absolute times (measured in milliseconds and seconds) much more useful most of the time. To switch the profile result to absolute times, just click the little % sign at the bottom of the pane.</p>
<p><img src="http://fuelyourcoding.com/files/absolute-time.png" alt="absolute-time" title="absolute-time" width="600" height="400" class="aligncenter size-full wp-image-1325" /></p>
<h2>Top to Bottom. Bottom to Top</h2>
<p>You can also sort the profile results using two different approaches. The default is the &#8220;Heavy&#8221; view or bottom up approach, which will more quickly float up the offending functions to the top of the heap. This is helpful to quickly identify trouble areas, but sometimes confusing because it doesn&#8217;t follow the logical structure of your code. For that, switch to the &#8220;Tree&#8221; view or top down approach. It looks like this instead:</p>
<p><img src="http://fuelyourcoding.com/files/tree-view.png" alt="tree-view" title="tree-view" width="600" height="400" class="aligncenter size-full wp-image-1327" /></p>
<h2>Focus</h2>
<p>One more feature of the <em><strong>Profiles</strong></em> pane is the ability to remove sections of the results and <strong>focus</strong> solely on the interesting bits. Do this by highlighting the interesting function and clicking the little eye icon in the lower lefthand corner. Other results will disappear and time percentages will be recalculated in the scope of the focused function.</p>
<h2>Conclusion</h2>
<p>I hope the above information explains what Web Inspector&#8217;s Profiles pane is, how to invoke it, what the results mean, and how to better organize them to increase their value. Give this power tool a try the next time you have some CPU intensive JavaScript that needs optimizing!</p>
]]></content:encoded>
			<wfw:commentRss>http://fuelyourcoding.com/webkits-javascript-profiler-explained/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Down &amp; Dirty with MongoDB Part 3: PHP ToDo</title>
		<link>http://fuelyourcoding.com/down-dirty-with-mongodb-part-3-php-todo/</link>
		<comments>http://fuelyourcoding.com/down-dirty-with-mongodb-part-3-php-todo/#comments</comments>
		<pubDate>Tue, 05 Oct 2010 12:35:33 +0000</pubDate>
		<dc:creator>John Hobbs</dc:creator>
				<category><![CDATA[Datastores]]></category>
		<category><![CDATA[Developer Tools]]></category>
		<category><![CDATA[Languages]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[nosql]]></category>

		<guid isPermaLink="false">http://fuelyourcoding.com/?p=1251</guid>
		<description><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
]]></description>
			<content:encoded><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
<p>
Earlier this summer, we kicked off a series on MongoDB where the goal was to write a simple todo application using native MongoDB drivers and three of our favorite scripting languages.
</p>
<ul>
<li><a href="/down-and-dirty-with-mongodb-part-1/">Part One: the Plot</a></li>
<li><a href="/down-and-dirty-with-mongodb-part-2/">Part Two: Ruby ToDo</a></li>
</ul>
<p>
This article is part 3 in that series, in which we write said application in PHP.
</p>
<h2>The Interface</h2>
<p>In case you missed it you can look back at the <a href="http://fuelyourcoding.com/down-and-dirty-with-mongodb-part-1/">introductory article</a> for the complete details, but real quick I&#8217;ll review interface here:</p>
<ul>
<li><strong>todo</strong> &#8211; list all incomplete tasks sorted by priority then chronologically</li>
<li><strong>todo next</strong> &#8211; list all incomplete tasks that are high priority</li>
<li><strong>todo done</strong> &#8211; list all complete tasks chronologically</li>
<li><strong>todo high &#8220;pay bills&#8221;</strong> &#8211; add high priority task called &#8220;pay bills&#8221;</li>
<li><strong>todo low &#8220;get milk&#8221;</strong> &#8211; add low priority task called &#8220;get milk&#8221;</li>
<li><strong>todo finish &#8220;pay bills&#8221;</strong> &#8211; complete task called &#8220;pay bills&#8221;</li>
<li><strong>todo dont &#8220;get milk&#8221;</strong> &#8211; delete task called &#8220;get milk&#8221;</li>
<li><strong>todo help</strong> &#8211; list all commands and their usage</li>
</ul>
<p>Looks simple enough, let&#8217;s dive in!</p>
<h2>The Driver</h2>
<p><a href="http://www.10gen.com/" target="_blank">10gen</a> distributes the PHP extension as a PECL package, or you can install from source. For more details, refer to the <a href="http://www.php.net/manual/en/mongo.installation.php">PHP.net Guide</a></p>
<p>We will go ahead and just use PECL, which is as easy as running one command.</p>
<p><pre class="brush: bash;">
pecl install mongo
</pre>
</p>
<p>You will also need to edit your php.ini file to add the following line, and probably reload your server.</p>
<p><pre class="brush: bash;">
extension=mongo.so
</pre>
</p>
<p>Go ahead and start a file called ToDo.php and stub out the first few lines.  Since this is a command line application, it&#8217;s a bit different from a standard PHP script.  We need to add a <a href="http://en.wikipedia.org/wiki/Shebang_%28Unix%29">shebang</a> and we&#8217;ll go ahead and change our error reporting levels to keep things quiet.  Changing your error reporting is optional, if you aren&#8217;t sure of your coding skills, just leave the error reporting at full blast, you can turn it down when we finish the app.</p>
<p><pre class="brush: php;">
#!/usr/bin/env php
&lt; ?php

error_reporting( E_ERROR | E_PARSE );
</pre>
<h2>The ToDo Class</h2>
</p>
<p>PHP5 has great support for object-oriented programming, so we will employ a single object of a class we’ll write called <tt>ToDo</tt>. The class will take in the required command-line arguments, connect to the MongoDB collection that stores our todos, and execute the appropriate commands on them.</p>
<p>To facilitate these needs, our object will need to take some arguments from the user and store a reference to the MongoDB collection when it is instantiated:</p>
<pre class="brush: php;">
  class ToDo {

    protected $argv = array();
    protected $mongo_connection = null;
    protected $mongo_db = null;

    public function __construct ( $argv ) {
      $this-&gt;argv = $argv;
      try {
        $this-&gt;mongo_connection = $mongo = new Mongo();
        $this-&gt;mongo_db = $this-&gt;mongo_connection-&gt;todo;
      }
      catch ( Exception $e ) {
        throw new Exception ( &quot;Oops! Error connecting to MongoDB: &quot; . $e-&gt;getMessage() );
     }
   }
</pre>
<p>The <tt>__construct function</tt> is the <a href="http://php.net/manual/en/language.oop5.decon.php">PHP5 way of adding a constructor to a class</a>. This is called when you instantiate an object, like this for instance:</p>
<pre class="brush: php;">
$my_todo = new ToDo( $argv );
</pre>
<p>When a new <tt>ToDo</tt> object is instantiated, our class will store the arguments passed in to it in an protected member called <tt>$argv</tt> and set up a connection to MongoDB in a member called <tt>$mongo_connection</tt>. <tt><a href="http://www.php.net/manual/en/class.mongo.php">Mongo</a></tt> is a class provided by the Mongo extension we installed earlier.</p>
<p>For convenience we will set up an instance of <tt><a href="http://www.php.net/manual/en/class.mongodb.php">MongoDB</a></tt> in the member called $mongo_db.  We do this since we will only be using one database.</p>
<p>Our <tt>ToDo</tt> class expects some arguments passed in to the constructor, so we need to provide them when we instantiate it. These arguments will be read in from the command-line when the program is executed, and PHP exposes these to our program via the <tt>$argv</tt> global variable.</p>
<p>However, <tt>$argv</tt> only exists in certain execution contexts of PHP, so we need to make sure we are executing from the command line.  To ascertain this, we look at the constant <tt>PHP_SAPI</tt>, then we instantiate a ToDo object with the <tt>$argv</tt> array.</p>
<p><pre class="brush: php;">
  if( 'cli' == PHP_SAPI ) {
    try {
      $app = new ToDo( $argv );
    }
    catch( Exception $e ) {
      print $e-&gt;getMessage() . &quot;\n&quot;;
    }
  }
</pre>
</p>
<p>At this point, the ToDo.php should look like this:</p>
<pre class="brush: php;">
#!/usr/bin/env php
&lt;?php
   error_reporting( E_ERROR | E_PARSE );
   class ToDo {
     protected $argv = array();
     protected $mongo_connection = null;
     protected $mongo_db = null;
     public function __construct ( $argv ) {
       $this-&gt;argv = $argv;
      try {
        $this-&gt;mongo_connection = $mongo = new Mongo();
        $this-&gt;mongo_db = $this-&gt;mongo_connection-&gt;todo;
      }
      catch ( Exception $e ) {
        throw new Exception ( &quot;Oops! Error connecting to MongoDB: &quot; . $e-&gt;getMessage() );
      }
    }
  }

  if( 'cli' == PHP_SAPI ) {
    try {
      $app = new ToDo( $argv );
    }
    catch( Exception $e ) {
      print $e-&gt;getMessage() . &quot;\n&quot;;
    }
  }
</pre>
<p>You can execute this program from the command-line, but nothing visible will happen. We still need to implement the bulk of the program, which parses the user’s command-line arguments and acts appropriately.</p>
<h2>A Little Help</h2>
<p>The first thing we’ll implement is also the simplest, a method that prints usage help for the program. It looks like this:</p>
<pre class="brush: php;">
protected function help ( $error = null ) {
  if( ! is_null( $error ) ) {
    print &quot;$error\n&quot;;
    print &quot;\n&quot;;
  }

  $out = &lt; &lt;&lt;EOF usage: {$this-&gt;argv[0]} &lt;method&gt;

== Methods ==

&lt;none&gt;             list all incomplete tasks sorted by priority then chronologically
help               show this help
next               list all incomplete tasks that are high priority
done               list all complete tasks chronologically
high &lt;argument&gt;    add high priority task called &lt;/argument&gt;&lt;argument&gt;
low &lt;/argument&gt;&lt;argument&gt;     add low priority task called &lt;/argument&gt;&lt;argument&gt;
finish &lt;/argument&gt;&lt;argument&gt;  complete task called &lt;/argument&gt;&lt;argument&gt;
dont &lt;/argument&gt;&lt;argument&gt;    delete unfinished task called &lt;/argument&gt;&lt;argument&gt;

EOF;
  print $out;
}
</pre>
<h2>Run, Baby, Run</h2>
<p>Now our application needs to be able to actually do it&#8217;s job, so lets create a method called <tt>run</tt> which will handle the program’s flow. In this method we examine the commands the user has given and call our other methods to get that work done. The default action is to list all incomplete tasks, and the catch-all is to execute the help method we implemented above. Here is what <tt>run</tt> looks like:</p>
<pre class="brush: php;">
public function run () {
	try {
		if ( 1 &gt;= count( $this-&gt;argv ) ) {
			$this-&gt;show(
				array( &quot;complete&quot; =&gt; false ),
				array( &quot;level&quot; =&gt; 1, &quot;added&quot; =&gt; 1 )
			);
		}
		else {
			$argument = strtolower( $this-&gt;argv[1] );
			if ( &quot;help&quot; == $argument )
				$this-&gt;help();
			else if ( &quot;next&quot; == $argument )
				$this-&gt;show(
					array( &quot;level&quot; =&gt; &quot;high&quot;, &quot;complete&quot; =&gt; false ),
					array( &quot;level&quot; =&gt; 1, &quot;added&quot; =&gt; 1 )
				);
			else if ( &quot;done&quot; == $argument )
				$this-&gt;show(
					array( &quot;complete&quot; =&gt; array( '$ne' =&gt; false ) ),
					array( 'completed' =&gt; 1 )
				);
			else if ( &quot;high&quot; == $argument )
				$this-&gt;add( &quot;high&quot;, $this-&gt;argv[2] );
			else if ( &quot;low&quot; == $argument )
				$this-&gt;add( &quot;low&quot;, $this-&gt;argv[2] );
			else if ( &quot;finish&quot; == $argument )
				$this-&gt;complete( true, $this-&gt;argv[2] );
			else if ( &quot;dont&quot; == $argument )
				$this-&gt;complete( false, $this-&gt;argv[2] );
			else
				throw new Exception( &quot;Bad Method&quot; );
		}
	}
	catch ( Exception $e ) {
		$this-&gt;help( $e-&gt;getMessage() );
	}
}
</pre>
<p><tt>$this->argv</tt> is an <tt>Array</tt> we were given when the <tt>ToDo</tt> constructor was run.  It should hold all of the options and arguments that the user provided when they ran the application from the command line.  If there is only one or fewer arguments we use a default action.  Otherwise we move into the <tt>switch</tt> statement and choose a method there.</p>
<p>One item worth noting is that we assume that <tt>$this->argv[0]</tt> is the name of the program itself, which is how PHP (and most other languages) handle command line arguments.</p>
<h2>Using Mongo</h2>
<p>So far we’ve only dealt with setting up our class and parsing user arguments, we’ve hardly event glanced at MongoDB! Time to change that!  I&#8217;ll work through each of the methods referenced in <tt>run</tt></p>
<p>First, the show method:</p>
<pre class="brush: php;">
protected function show ( $params = null, $sort = null ) {
  $cursor = $this-&gt;mongo_db-&gt;todos-&gt;find( $params );
  if( ! is_null( $sort ) )
    $cursor-&gt;sort( $sort );
  foreach ( $cursor as $row )
    print $row['task'] . &quot;\n&quot;;
}
</pre>
<p>This method takes an array of selection parameters and an array of sort options (both optional) and passes them directly to the MongoDB cursor.  The cursor will then let us extract the matching documents one at a time, sorted and returned as arrays. This style of interface is pretty easy to work with, it&#8217;s one of the great benefits of using a document store like MongoDB.</p>
<p>Now let&#8217;s find a way to store those item&#8217;s in MongoDB in the first place.  This requires us to implement the <tt>add</tt> method.</p>
<pre class="brush: php;">
protected function add ( $level, $item ) {
  if ( 2 &gt;= count( $this-&gt;argv ) )
    throw new Exception( &quot;missing argument&quot; );
  $this-&gt;mongo_db-&gt;todos-&gt;insert( array(
    &quot;task&quot; =&gt; $item,
    &quot;level&quot; =&gt; $level,
    &quot;complete&quot; =&gt; false,
    &quot;added&quot; =&gt; time()
   ) );
}
</pre>
</p>
<p>Our <tt>add</tt> method takes two arguments.  <tt>$level</tt> is the importance of the item, either &#8220;high&#8221; or &#8220;low&#8221;.  <tt>$item</tt> is the text of the item itself.  Once you have these two facts you can quickly pass them on to MongoDB&#8217;s <tt>insert</tt> method.</p>
<p>The <tt><a href="http://php.net/manual/en/mongocollection.insert.php">insert</a></tt> method in MongoDB takes an associative array and persists it to the datastore as a document.  You can store just about anything you like this way, as long as it can be serialized.</p>
<p>The final method we need is a bit more versatile, the <tt>complete</tt> method.  This method can either finish a task or remove it from the system.</p>
<pre class="brush: php;">
protected function complete ( $finish, $item ) {
  if ( 2 &gt;= count( $this-&gt;argv ) )
    throw new Exception( &quot;missing argument&quot; );
  $document = $this-&gt;mongo_db-&gt;todos-&gt;findOne( array( &quot;complete&quot; =&gt; false, &quot;task&quot; =&gt; $item ) );
  if ( is_null( $document ) )
    print &quot;No Matching ToDo Found\n&quot;;
  else {
    if ( $finish ) {
      $document['complete'] = time();
      $this-&gt;mongo_db-&gt;todos-&gt;save( $document );
    }
    else {
      $this-&gt;mongo_db-&gt;todos-&gt;remove( $document );
    }
  }
}
</pre>
<p>This method uses a variant of <tt><a href="http://www.php.net/manual/en/mongocollection.find.php">find</a></tt> (which we used in <tt>show</tt>) called <tt><a href="http://www.php.net/manual/en/mongocollection.findone.php">findOne</a></tt>.  Think of this as the MongoDB version of <tt>LIMIT 0,1</tt>.  After we&#8217;ve tried to find a task matching the requested title, we then either abort (if not found) or complete (if found).</p>
<p>When completing we will use one of two MongoDB methods, depending on whether we are finishing or skipping the task.  The <tt><a href="http://www.php.net/manual/en/mongocollection.save.php">save</a></tt> method will be used to finish a task.  This method takes a MongoDB document that was previously retrieved and saves it back into the database.  Any changes you make to the object (like setting the <tt>completed</tt> time, for instance) is persisted to the database.  This is done through a unique (but <u>not necessarily sequential</u>) ID given to each document in the datastore.</p>
<p>To delete a task from our list we need to use <tt><a href="http://www.php.net/manual/en/mongocollection.remove.php">remove</a></tt>. This method takes an existing document object (with a document id) and deletes it from the database.</p>
<h2>Finishing Up</h2>
<p>So there you have it, we&#8217;ve completed all of our methods.  Now all we have to do is call run and we should have a working todo program!
</p>
<pre class="brush: php;">
if( 'cli' == PHP_SAPI ) {
  try {
    $app = new ToDo( $argv );
    $app-&gt;run();
  }
  catch( Exception $e ) {
    print $e-&gt;getMessage() . &quot;\n&quot;;
  }
}
</pre>
<p>You can view/download the program in its entirety <a href="http://gist.github.com/405143">here</a>. One thing to note is how little datastore code is needed to add CRUD to an application when using MongoDB as a datastore.</p>
<p>Hopefully this article has helped you with PHP or MongoDB, or both. Stay tuned for our next article in the series when we write the exact same application in Python!</p>
]]></content:encoded>
			<wfw:commentRss>http://fuelyourcoding.com/down-dirty-with-mongodb-part-3-php-todo/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>jQuery Events: Stop (Mis)Using Return False</title>
		<link>http://fuelyourcoding.com/jquery-events-stop-misusing-return-false/</link>
		<comments>http://fuelyourcoding.com/jquery-events-stop-misusing-return-false/#comments</comments>
		<pubDate>Mon, 20 Sep 2010 13:53:37 +0000</pubDate>
		<dc:creator>Douglas Neiner</dc:creator>
				<category><![CDATA[Concepts & Training]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[bubbling]]></category>
		<category><![CDATA[events]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://fuelyourcoding.com/?p=1266</guid>
		<description><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>

&#60;div class=&#34;post&#34;&#62;
    &#60;h2&#62;&#60;a href=&#34;/path/to/page&#34;&#62;My Page&#60;/a&#62;&#60;/h2&#62;
    &#60;div class=&#34;content&#34;&#62;
        Teaser text...
    &#60;/div&#62;
&#60;/div&#62;
&#60;div class=&#34;post&#34;&#62;
    &#60;h2&#62;&#60;a href=&#34;/path/to/other_page&#34;&#62;My Other Page&#60;/a&#62;&#60;/h2&#62;
    &#60;div class=&#34;content&#34;&#62;
        Teaser text...
    &#60;/div&#62;
&#60;/div&#62;

Now lets say we [...]]]></description>
			<content:encoded><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
<p>Probably one of the first topics covered when you get started learning about jQuery events is the concept of canceling the browser&#8217;s default behavior. For instance, a beginner <code>click</code> tutorial may include this:</p>
<pre class="brush: jscript;">
$(&quot;a.toggle&quot;).click(function () {
    $(&quot;#mydiv&quot;).toggle();
    return false; // Prevent browser from visiting `#`
});
</pre>
<p>This function toggles the hiding and displaying of <code>#mydiv</code>, then cancels the browser&#8217;s default behavior of visiting the <code>href</code> of the anchor tag. </p>
<p>It is in these very first examples that bad habits are formed as users continue to use <code>return false;</code> whenever they want to cancel the default browser action. I am going to cover two very important topics in this article relating to the canceling of browser events:</p>
<ul>
<li>Use the right method for the job: <code>return false</code> vs. <code>preventDefault</code>, <code>stopPropagation</code>, and <code>stopImmediatePropagation</code></li>
<li>Top, bottom or somewhere in the middle: where in the event callback should you cancel default behavior?</li>
</ul>
<p><em>Note: in this article when I refer to event bubbling, I am talking about how most events will fire on the original DOM element, and then on each parent element in the DOM tree. Events do not bubble to siblings or children (When events &#8220;bubble&#8221; downward, it is called event capturing). <a href="http://www.nczonline.net/blog/2009/06/30/event-delegation-in-javascript/">Learn more about bubbling and capturing.</a></em></p>
<h2 id="use_the_right_method_for_the_job">Use the Right Method for the Job</h2>
<p>The main reason <code>return false</code> is so widely misused is because it <em>appears</em> to be doing what we want. Link callbacks no longer redirect the browser, form submit callbacks no longer submit the form, etc. So why is it so bad?</p>
<h3 id="what_return_false_is_really_doing">What <code>return false</code> is <em>really</em> doing</h3>
<p>First off, <code>return false</code> is actually doing three very separate things when you call it:</p>
<ol>
<li>event.preventDefault();</li>
<li>event.stopPropagation();</li>
<li>Stops callback execution and returns immediately when called.</li>
</ol>
<p>&#8220;Wait a minute,&#8221; you cry! I only needed to stop the default behavior! I don&#8217;t need these other two items&#8230; I think. </p>
<p>The only one of those three actions needed to cancel the default behavior is <code>preventDefault()</code>. Unless you mean to actually stop event propagation (bubbling), using <code>return false</code> will greatly increase the brittleness of your code. Lets see how this misuse plays out in a real world scenario:</p>
<p>Here is our HTML for the example:</p>
<pre class="brush: xml;">
&lt;div class=&quot;post&quot;&gt;
    &lt;h2&gt;&lt;a href=&quot;/path/to/page&quot;&gt;My Page&lt;/a&gt;&lt;/h2&gt;
    &lt;div class=&quot;content&quot;&gt;
        Teaser text...
    &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;post&quot;&gt;
    &lt;h2&gt;&lt;a href=&quot;/path/to/other_page&quot;&gt;My Other Page&lt;/a&gt;&lt;/h2&gt;
    &lt;div class=&quot;content&quot;&gt;
        Teaser text...
    &lt;/div&gt;
&lt;/div&gt;
</pre>
<p>Now lets say we want the actual article to load into the corresponding <code>div.content</code> when a user clicks on either title link:</p>
<pre class="brush: jscript;">
jQuery(document).ready(function ($) {
   $(&quot;div.post h2 a&quot;).click(function () {
      var a    = $(this),
          href = a.attr('href'), // Let jQuery normalize `href`,
          content  = a.parent().next();
      content.load(href + &quot; #content&quot;);
      return false; // &quot;cancel&quot; the default behavior of following the link
   });
});
</pre>
<p>All is well (currently) and our dynamic page is well under way. Down the road we decide another piece of functionality we want is to add the class <code>"active"</code> to any <code>div.post</code> that has been clicked (or when a child element has been clicked) most recently. So, we decide to add a <code>click</code> handler to them as well:</p>
<pre class="brush: jscript;">
// Inside Document Ready:
var posts = $(&quot;div.post&quot;);
posts.click(function () {
    // Remove active from all div.post
    posts.removeClass(&quot;active&quot;);
    // Add it back to this one
    $(this).addClass(&quot;active&quot;);
});
</pre>
<p>Will this work when we click a title link? NO! The reason it won&#8217;t work is because we used <code>return false</code> in the link click event instead of using what we really meant! Because <code>return false</code> really means <code>event.preventDefault(); event.stopPropagation();</code> the <code>click</code> event never bubbled up to the parent <code>div.post</code> and our new event has not been called. </p>
<p>This becomes even more of an issue when mixing normal events with <code>live</code> or <code>delegate</code> events:</p>
<pre class="brush: jscript;">
$(&quot;a&quot;).click(function () {
    // do something
    return false;
});

$(&quot;a&quot;).live(&quot;click&quot;, function () {
    // THIS WON'T FIRE
});
</pre>
<h3 id="so_what_do_you_really_want">So what DO you really want?</h3>
<h4 id="preventdefault"><code>preventDefault()</code></h4>
<p>In most situations where you would use <code>return false</code> what you <em>really</em> want is <code>e.preventDefault()</code>. Using <code>preventDefault</code> requires you allow for the event parameter to be accessed in your callback (In this example, I use <code>e</code>):</p>
<pre class="brush: jscript;">
$(&quot;a&quot;).click(function (e) {
    // e == our event data
    e.preventDefault();
});
</pre>
<p>This does everything we want without prohibiting parent elements from receiving these events as well. The fewer restrictions you place on your code the more flexible it will be to maintain. </p>
<h4 id="stoppropagation"><code>stopPropagation()</code></h4>
<p>Sometimes you just want to stop the propagation. Take the following example:</p>
<pre class="brush: xml;">
&lt;div class=&quot;post&quot;&gt;
    Normal text and then a &lt;a href=&quot;/path&quot;&gt;link&lt;/a&gt; and then more text.
&lt;/div&gt;
</pre>
<p>Now, lets pretend we want one thing to happen when you click anywhere in the <code>div</code> <strong>except</strong> on the link, and you want the user to actually be able to follow the link if they click on it. (From a usability standpoint, this is a poor example. You probably don&#8217;t want something else to happen if a user slightly misses clicking on the link!)</p>
<pre class="brush: jscript;">
$(&quot;div.post&quot;).click(function () {
   // Do the first thing;
});

$(&quot;div.post a&quot;).click(function (e) {
    // Don't cancel the browser's default action
    // and don't bubble this event!
    e.stopPropagation();
});
</pre>
<p>In this case if we had used <code>return false</code> the <code>div</code>&#8217;s click event would not have fired, but the user would also not have been directed to the correct destination either.</p>
<h4 id="stopimmediatepropagation"><code>stopImmediatePropagation()</code></h4>
<p>This method stops any further execution of an event, even to other handlers bound on the same object. All events bound to a particular item will fire in the order they were bound.  Take the following example:</p>
<pre class="brush: jscript;">
$(&quot;div a&quot;).click(function () {
   // Do something
});

$(&quot;div a&quot;).click(function (e) {
   // Do something else
   e.stopImmediatePropagation();
});

$(&quot;div a&quot;).click(function () {
   // THIS NEVER FIRES
});

$(&quot;div&quot;).click(function () {
   // THIS NEVER FIRES
});
</pre>
<p>If you think this example looks contrived, it really is. However, the situation is a very real one. As you build more abstracted code, different widgets and plugins may be adding events to the same code you are working with. This makes understanding and using <code>stopImmediatePropagation</code> worth while when you come across a situation that needs it!</p>
<h4><code>return false</code></h4>
<p>Only use <code>return false</code> when you want both <code>preventDefault()</code> and <code>stopPropagation()</code> and your code can support not canceling the default behavior until you reach the end of your callback execution. <em>I strongly encourage against using this method in any examples you may write for new jQuery developers. It promotes a poor use of event cancellation and should only be used when you are consciously deciding you need what it provides.</em>.</p>
<h2 id="top_bottom_or_somewhere_in_the_middle">Top, Bottom or Somewhere in the Middle</h2>
<p>Before, when you were (mis)using <code>return false</code>, it always had to go at the end of your function, or at least at the end of a particular line of logic where no further execution was needed. With <code>e.preventDefault</code> we have more choices. It can be called at any time during a callback function to take effect. So where should you put it?</p>
<p><strong>1. During development, it should <em>(almost) always</em> be the very first line.</strong> The last thing you want is for your form you are trying to AJAXify to actually submit to another page while you try to debug a JavaScript error in the callback. </p>
<p><strong>2. In production, if you are following progressive enhancement, put it at the bottom of the callback, or at the end of execution flow.</strong> If you are progressively enhancing a normal page, then your link <code>click</code> event or form <code>submit</code> event has the proper server side fallbacks needed for browsers that don&#8217;t support JavaScript (or don&#8217;t have support enabled). The benefit here, however, is <strong>not</strong> related to browsers with JS turned off, but rather browsers with it turned on in the situation where <em>your code throws an error</em>! Take a look at the following code:</p>
<pre class="brush: jscript;">
var data = {};
$(&quot;a&quot;).click(function (e) {
    e.preventDefault(); // cancel default behavior

    // Throws an error because `my` is undefined
    $(&quot;body&quot;).append(data.my.link); 

    // The original link doesn't work AND the &quot;cool&quot;
    // JavaScript has broken. The user is left with NOTHING!
});
</pre>
<p>Now, lets take a look at the same event with the <code>preventDefault</code> call being placed at the bottom:</p>
<pre class="brush: jscript;">
var data = {};
$(&quot;a&quot;).click(function (e) {
    // Throws an error because `my` is undefined
    $(&quot;body&quot;).append(data.my.link); 

    // This line is never reached, and your website
    // falls back to using the `href` instead of this
    // &quot;cool&quot; broken JavaScript!

    e.preventDefault(); // cancel default behavior
});
</pre>
<p>The same applies for <code>form submit</code> events as well, provided you have the proper fallback information in place. Never count on your code always working. It is far better to plan for a nice fallback than assume errors will never occur!</p>
<p><strong>3. In production, if the functionality is JavaScript only, keep the call on the first line.</strong> Remember, it doesn&#8217;t necessarily have to be the first line in the function, but it should come as early as fits with your program logic. The concept here is this: If this part of your functionality was added with JavaScript in the first place, then a fallback is not really as necessary. In this case, having it first will just ensure random <code>#</code> characters don&#8217;t appear in the URL or cause the page to jump around. Obviously, provide as much error handling as needed to ensure your users aren&#8217;t left with nothing for their efforts!</p>
<h2 id="conclusion">Conclusion</h2>
<p>I hope this article presented enough information for you to make the right choice when you cancel events. Remember to only use <code>return false</code> when you really need it, and make sure you cancel the default behavior at the right location in your callback. Always work to make your code as flexible as possible, and stop using return false!</p>
]]></content:encoded>
			<wfw:commentRss>http://fuelyourcoding.com/jquery-events-stop-misusing-return-false/feed/</wfw:commentRss>
		<slash:comments>61</slash:comments>
		</item>
		<item>
		<title>Down &amp; Dirty with MongoDB Part 2: Ruby ToDo</title>
		<link>http://fuelyourcoding.com/down-and-dirty-with-mongodb-part-2/</link>
		<comments>http://fuelyourcoding.com/down-and-dirty-with-mongodb-part-2/#comments</comments>
		<pubDate>Mon, 09 Aug 2010 14:40:31 +0000</pubDate>
		<dc:creator>Jerod Santo</dc:creator>
				<category><![CDATA[Datastores]]></category>
		<category><![CDATA[Developer Tools]]></category>
		<category><![CDATA[Languages]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[nosql]]></category>

		<guid isPermaLink="false">http://fuelyourcoding.com/?p=1235</guid>
		<description><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
]]></description>
			<content:encoded><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
<p>Earlier this summer, we kicked off <a href="/down-and-dirty-with-mongodb-part-1/">a series on MongoDB</a> where the goal was to write a simple todo application using native <a href="http://mongodb.org">MongoDB</a> drivers and three of our favorite scripting languages.</p>
<p>This article is part 2 in that series, in which we write said application in <a href="http://ruby-lang.org">Ruby</a>.</p>
<h2>The Interface</h2>
<p>You can refer back to the <a href="http://fuelyourcoding.com/down-and-dirty-with-mongodb-part-1/">introductory article</a> for all the details, but I&#8217;ll reiterate the command-line interface here for easy reference:</p>
<ul>
<li><strong>todo</strong> &#8211; list all incomplete tasks sorted by priority then chronologically</li>
<li><strong>todo next</strong> &#8211; list all incomplete tasks that are high priority</li>
<li><strong>todo done</strong> &#8211; list all complete tasks chronologically</li>
<li><strong>todo high &#8220;pay bills&#8221;</strong> &#8211; add high priority task called &#8220;pay bills&#8221;</li>
<li><strong>todo low &#8220;get milk&#8221;</strong> &#8211; add low priority task called &#8220;get milk&#8221;</li>
<li><strong>todo finish &#8220;pay bills&#8221;</strong> &#8211; complete task called &#8220;pay bills&#8221;</li>
<li><strong>todo dont &#8220;get milk&#8221;</strong> &#8211; delete task called &#8220;get milk&#8221;</li>
<li><strong>todo help</strong> &#8211; list all commands and their usage</li>
</ul>
<p>Okay, let&#8217;s write this thing!</p>
<h2>The Driver</h2>
<p><a href="http://www.10gen.com/">10gen</a> distributes the Ruby driver using Ruby&#8217;s most popular package distribution tool, <a href="http://rubygems.org">RubyGems</a>. To install the driver on your machine simply execute:</p>
<pre class="brush: bash;">
gem install mongo
</pre>
<p>Our program will need to load in the driver before anything else, and we&#8217;ll use RubyGems to do it, so create a new text file called <tt>mongo_todo.rb</tt> and begin it with the following:</p>
<pre class="brush: ruby;">
require 'rubygems'
require 'mongo'
</pre>
<h2>The ToDo Class</h2>
<p>Ruby is a purely object-oriented language, so our program will employ a single object of a class we&#8217;ll write called <tt>ToDo</tt>. The class will take in the required command-line arguments, connect to the MongoDB collection that stores our todos, and execute the appropriate command on them.</p>
<p>To facilitate these needs, our object will need to take some arguments from the user and store a reference to the MongoDB collection when it is instantiated:</p>
<pre class="brush: ruby;">
class ToDo
  def initialize(args)
    @args  = args
    @mongo = Mongo::Connection.new.db(&quot;todo&quot;).collection(&quot;todos&quot;)
  end
end
</pre>
<p>In Ruby, the <tt>initialize</tt> instance method is called when a new object of a class is instantiated, most often using the <tt>new</tt> class method, like this:</p>
<pre class="brush: ruby;">
my_todo = ToDo.new
</pre>
<p>When a new <tt>ToDo</tt> object is instantiated, our class will store the arguments passed in to it in an instance variable called <tt>@args</tt> and store a connection to MongoDB in an instance variable called <tt>@mongo</tt>. <a href="http://api.mongodb.org/ruby/current/Mongo/Collection.html">Mongo::Connection</a> is a class provided by the <tt>mongo</tt> gem that we&#8217;re using.</p>
<p>Since our class expects some arguments passed in to the initializer, we need to provide them to the <tt>new</tt> method. The arguments will be read in from the command-line when the program is executed, and Ruby exposes these to our program via the <tt>ARGV</tt> variable. So, we call <tt>new</tt> like this instead:</p>
<pre class="brush: ruby;">
my_todo = ToDo.new(ARGV)
</pre>
<p>At this point, the entire program should look like this:</p>
<pre class="brush: ruby;">
require 'rubygems'
require 'mongo'

class Todo
  def initialize(args)
    @args  = args
    @mongo = Mongo::Connection.new.db(&quot;todo&quot;).collection(&quot;todos&quot;)
  end
end

ToDo.new(ARGV)
</pre>
<p>You can execute this program from the command-line, but nothing will happen. Well, stuff will happen but you won&#8217;t see it displayed back to you. We still need to implement the bulk of the program, which parses the user&#8217;s command-line arguments and acts appropriately.</p>
<h2>A Little Help</h2>
<p>The first thing we&#8217;ll implement is a method that prints usage help for the program. It looks like this:</p>
<pre class="brush: ruby;">
def help
  abort &lt;&lt;-HELP
  usage: #{__FILE__} &lt;method&gt;

  == Methods ==
  &lt;none&gt;            list all incomplete tasks sorted by priority
  help              show this help
  next              list all incomplete tasks that are high priority
  done              list all complete tasks chronologically
  high &quot;argument&quot;   add high priority task called argument
  low &quot;argument&quot;    add low priority task called argument
  finish &quot;argument&quot; complete task called argument
  dont &quot;argument&quot;   delete unfinished task called argument
  HELP
end
</pre>
<p>In Ruby, <a href="http://ruby-doc.org/ruby-1.9/classes/Kernel.html#M002645">abort</a> is a method you can call which will exit the application and display a string you pass to it. The string we&#8217;re passing in shows all the ways the program can be used, which will be displayed back to the user. This will be executed by default if the user doesn&#8217;t pass in an argument that we want to handle. More on that in the next section.</p>
<h2>Run, Baby, Run</h2>
<p>At some point, our application needs to run, so lets create an instance method called <tt>run</tt> which will handle the program&#8217;s flow. In this method we will determine what the user passed in from the command-line and call another method that handles the different use cases. The default action is to list all incomplete tasks, and the catch-all is to execute the <tt>help</tt> method we implemented above. Here is what <tt>run</tt> looks like:</p>
<pre class="brush: ruby;">
def run
  if @args.empty?
    show :complete =&gt; false
  else
    case @args.first
    when &quot;help&quot;   then help
    when &quot;high&quot;   then add &quot;high&quot;
    when &quot;low&quot;    then add &quot;low&quot;
    when &quot;next&quot;   then show :complete =&gt; false, :level =&gt; &quot;high&quot;
    when &quot;done&quot;   then show :complete =&gt; true
    when &quot;dont&quot;   then complete false
    when &quot;finish&quot; then complete true
    else
      help
    end
  end
end
</pre>
<p><tt>ARGV</tt> is an <a href="http://ruby-doc.org/ruby-1.9/classes/Array.html">Array</a>, so we can call methods like <a href="http://ruby-doc.org/ruby-1.9/classes/Array.html#M000711">empty?</a> and <a href="http://ruby-doc.org/ruby-1.9/classes/Array.html#M000698">first</a> on it. The meat of the run method is a Ruby <tt>case</tt> statement which checks if the first argument passed in by the user matches any of our predetermined keywords and calls other methods, <tt>add</tt><tt>, </tt><tt>show</tt>, and <tt>complete</tt>. These methods are the ones that actually interact with MongoDB and display information back to the user. We&#8217;ll implement them next.</p>
<h2>Using Mongo</h2>
<p>So far we&#8217;ve only dealt with setting up our class and parsing user arguments, we&#8217;ve barely even touched MongoDB! This is the meat of the application, so let&#8217;s get straight to it. First, the <tt>show</tt> method:</p>
<pre class="brush: ruby;">
def show(params)
  sort = [[&quot;level&quot;, Mongo::ASCENDING], [&quot;added&quot;, Mongo::ASCENDING]]
  @mongo.find(params, :sort =&gt; sort).each { |todo| puts &quot;#{todo[&quot;task&quot;]} (#{todo[&quot;level&quot;]})&quot; }
end
</pre>
<p><tt>show</tt> takes a hash of <tt>params</tt> as an argument and passes that hash on directly to the <tt>mongo</tt> library&#8217;s <a href="http://api.mongodb.org/ruby/current/Mongo/Collection.html#find-instance_method">find</a> method, which will return an array of the found items in the collection.</p>
<p>We print each of the todo items returned from <a href="http://api.mongodb.org/ruby/current/Mongo/Collection.html#find-instance_method">find</a> along with the level of the todo. How do those items get in there in the first, place? That is up to the <tt>add</tt> method, which we will implement next.</p>
<pre class="brush: ruby;">
def add(level)
  help unless @args.length == 2
  @mongo.insert &quot;task&quot; =&gt; @args.last, &quot;level&quot; =&gt; level, &quot;complete&quot; =&gt; false, &quot;added&quot; =&gt; Time.now
  puts &quot;added #{level} level task: #{@args.last}&quot;
end
</pre>
<p><tt>add</tt> takes a single argument, the level of the todo to create (e.g.- &#8220;high&#8221; or &#8220;low&#8221;). It then makes sure that the user had passed in two arguments at the command line because it needs the second one for the name of the task. If not, it calls <tt>help</tt> which aborts the application.</p>
<p>If so, It calls Mongo&#8217;s <a href="http://api.mongodb.org/ruby/current/Mongo/Collection.html#insert-instance_method">insert</a> method and passes it all the information to be stored in the datastore.</p>
<p>Finally, we need to implement the <tt>complete</tt> method, which is the most complex of the lot. Like <tt>add</tt>, it makes sure there were two command-line arguments given. Then it tries to find the todo by the &#8220;task&#8221; name. If found, it will either &#8220;finish&#8221; the task or &#8220;remove&#8221; the task depending on a boolean argument passed in. The method looks like this:</p>
<pre class="brush: ruby;">
def complete(finish)
  help unless @args.length == 2
  if (document = @mongo.find_one(&quot;task&quot; =&gt; @args.last, &quot;complete&quot; =&gt; false))
    if finish
      document[&quot;complete&quot;] = Time.now
      @mongo.save(document)
      puts &quot;finished: #{@args.last}&quot;
    else
      @mongo.remove(document)
      puts &quot;removed: #{@args.last}&quot;
    end
  else
    puts &quot;No ToDo matching #{@args.length} found&quot;
  end
end
</pre>
<p>The mongo-related calls in the <tt>complete</tt> method are <a href="http://api.mongodb.org/ruby/current/Mongo/Collection.html#find_one-instance_method">find_one</a>, <a href="http://api.mongodb.org/ruby/current/Mongo/Collection.html#save-instance_method">save</a>, and <a href="http://api.mongodb.org/ruby/current/Mongo/Collection.html#remove-instance_method">remove</a>.</p>
<h2>Finishing Up</h2>
<p>So, we&#8217;ve written our <tt>run</tt> method which calls the other methods using the user&#8217;s passed in arguments. Now all we have to do to get the class going is finish the program by creating a ToDo class object and calling <tt>run</tt> on it, like this:</p>
<pre class="brush: ruby;">
ToDo.new(ARGV).run
</pre>
<p>You can view/download the program in its entirety <a href="http://gist.github.com/409729">here</a>. One thing to note is how little code is needed to add CRUD to an application when using MongoDB as a datastore.</p>
<p>Hopefully this article has helped you with Ruby or MongoDB or both. Stay tuned for our next article in the series when we write the exact same application in PHP!</p>
]]></content:encoded>
			<wfw:commentRss>http://fuelyourcoding.com/down-and-dirty-with-mongodb-part-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>WordPress: Auto URL Shortening</title>
		<link>http://fuelyourcoding.com/wordpress-auto-url-shortening/</link>
		<comments>http://fuelyourcoding.com/wordpress-auto-url-shortening/#comments</comments>
		<pubDate>Mon, 24 May 2010 12:39:29 +0000</pubDate>
		<dc:creator>Designerfoo</dc:creator>
				<category><![CDATA[Languages]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[bitly]]></category>
		<category><![CDATA[Plugins / Add-Ons]]></category>
		<category><![CDATA[themes]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://fuelyourcoding.com/?p=985</guid>
		<description><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
]]></description>
			<content:encoded><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
<p><img src="http://fuelyourcoding.com/files/urlshortner_mini.jpg" alt="WP Auto URL Shortening" title="WP Auto URL Shortening" width="250" height="188" class="alignright size-full wp-image-1031" />Everyday there are scores of new links shared, re-tweeted, posted, and emailed by people like you and I. Because of social media platforms like Twitter and Facebook, our love for sharing information, tutorials, freebies, etc., has never been stronger!</p>
<h2>The Proposition</h2>
<p>As a <a href="http://wordpress.org">WordPress</a> developer/designer, how would you like if URLs on your WordPress site were automatically shortened as soon as you publish? This would mean instantly available shortened URLs for sharing/posting AND statistics of your links!</p>
<h2>Here&#8217;s How</h2>
<p>We are going to build the Auto URL Shortening feature within your WordPress theme using the <a href="http://bit.ly/">bit.ly</a> API. Let&#8217;s start with the <tt>functions.php</tt> file found within your theme.</p>
<p>The <tt>functions.php</tt> file is included in most WordPress themes as a place to drop custom functions to be used from the theme. If this file doesn&#8217;t exist in the theme you are using, go ahead and create it.</p>
<h3>Add 3 functions within the functions.php file</h3>
<pre class="brush: php;">
function makeshorturl()
{

}

function shorturl_metabox()
{

}

function showshorturlbox()
{

}
</pre>
<p>The first function, <tt>makeshorturl()</tt>, as the name suggests will be creating a short URL for us. The second and the third functions will work together to show us the short URL in the admin editor.</p>
<h3>Shortening the link</h3>
<pre class="brush: php;">
function makeshorturl()
{
    global $post;

    $short_url = json_decode(file_get_contents('http://api.bit.ly/v3/shorten?login=[username]&amp;apiKey=[apikey]&amp;longURL='.urlencode(get_permalink($post-&gt;ID)).'&amp;format=json'));

    if($short_url-&gt;status_code==&quot;200&quot;)
    {
         $short_url = $short_url-&gt;data-&gt;url;
    }
    else
    {
        $short_url = &quot;Bit.ly Error! &quot;.$short_url-&gt;status_txt;
    }

    do_action('makeshorturl');

    return $short_url;
}
</pre>
<p>The first line in this function declares WordPress&#8217;s global <tt>$post</tt> variable which holds all the data for the current post. We extract the permalink of the current post using the <tt>get_permalink()</tt> function and supplying the current post&#8217;s id. We then take the permalink and pass it on to bit.ly&#8217;s API which returns us a short URL within a JSON object. Next we extract the short URL. If an error occurs we simply return the error.</p>
<p>The <tt>do_action()</tt> method in WordPress makes this function hookable with other functions/hooks and the function can be used within theme using the hook &#8211; <strong>makeshorturl()</strong>.</p>
<p>Want to know more about <a href="http://codex.wordpress.org/Function_Reference/do_action" target="_new" rel="nofollow">do_action()</a> and <a href="http://codex.wordpress.org/Plugin_API"  target="_new" rel="nofollow">wordpress hooks</a>?</p>
<h3>Lets look at the api call in more detail</h3>
<pre class="brush: php;">
http://api.bit.ly/v3/shorten?login=[username]&amp;apiKey=[apikey]&amp;longURL='.urlencode(get_permalink($post-&gt;ID)).'&amp;format=json
</pre>
<p>It&#8217;s really quite simple.</p>
<p>The <tt>login</tt> parameter would expect your login over at bit.ly (<a href="http://bit.ly/a/sign_up" target="_new" rel="nofollow">don&#8217;t have one? create one here</a>). The <tt>apiKey</tt> parameter accepts the API key given to each bit.ly account. If you already have an account you can find <a href="http://bit.ly/a/your_api_key" target="_new" rel="nofollow">the API key here</a>. The <tt>longURL</tt> parameter expects an encoded long URL string that needs to be shortened, and this is where our custom permalinks get passed. The <tt>format</tt> parameter expects one of the three values &#8211; json, xml or text; depending on the format value specified, the API returns the shortened url (and more data) as JSON, XML or text respectively. By default, if format is not specified, it returns a JSON object. For more info on the bit.ly API, refer the <a href="http://code.google.com/p/bitly-api/wiki/ApiDocumentation">API documentation</a>. Once the bit.ly API sends the JSON object back, we use PHP&#8217;s <tt>json_decode</tt> function to decode the JSON object into a PHP5 object.</p>
<h3>Adding the shortened URL to the admin editor</h3>
<p>Once the permalink has been shortened, we need to make it available in the backend. To do this, we use the two functions as outlined below.</p>
<pre class="brush: php;">
function shorturl_metabox()
{
    if(is_admin())
    {
        add_meta_box('bitlyurl',__('Short URL','short-url'),'showshorturlbox','post','side');
        add_meta_box('bitlyurl',__('Short URL','short-url'),'showshorturlbox','page','side');
    }
}
</pre>
<p>The <tt>shorturl_metabox</tt> will first check if the user is within the admin section of the wordpress based site/blog. Then we add a meta box to the admin page.</p>
<p><img src="http://fuelyourcoding.com/files/shorturlmaker.png" alt="Short URL Admin" title="Short URL Admin" width="297" height="79" class="alignleft size-full wp-image-1019" /> A Meta box in WordPress basically is a box which sets and gets meta information about a post. Default meta boxes include Post Tags, Discussions and so forth. </p>
<p><a href="http://codex.wordpress.org/Writing_Posts" target="_new" rel="nofollow">More on meta boxes.</a></p>
<p>The <tt>add_meta_box</tt> function takes five parameters:</p>
<ol>
<li> the HTML id of the box</li>
<li>the label/title of the box</li>
<li>the callback function which would render the box contents</li>
<li>the type of write screen &#8211; post or a page
</li>
<li>the position or context where the box would be located &#8211; Normal, Advanced or Side.</li>
</ol>
<p><a href="ttp://codex.wordpress.org/Function_Reference/add_meta_box" target="_new" rel="nofollow">More on add_meta_box()</a>.</p>
<p>As you can see, that when the function &#8220;<em>adds</em>&#8221; the meta box to the admin view, it calls the <tt>showshorturlbox</tt> function which renders the contents of the meta box, as shown below.</p>
<pre class="brush: php;">
function showshorturlbox()
{
    echo '&lt;label for=&quot;bitlyurl&quot;&gt;'.__('Shortened URL','short-url-label').': '.makeshorturl().'&lt;/label&gt;&lt;br/&gt;&lt;br/&gt;';
}
</pre>
<p>The function echoes the short URL in a label, thus making it available to be shared by the authors of the post/page. We are calling <tt>makeshorturl()</tt> which fetches or generates the shortened URL via the bitly API.</p>
<h3>Bringing it together</h3>
<p>Finally we use the following three lines which attach our <tt>makeshorturl()</tt> function to the <tt>publish_post</tt> and <tt>publish_page</tt> hooks and attaches <tt>shorturl_metabox</tt> to the <tt>do_meta_boxes</tt> hook that generates the meta boxes.</p>
<pre class="brush: php;">
add_action('publish_post','makeshorturl');
add_action('publish_page','makeshorturl');
add_action('do_meta_boxes','shorturl_metabox');
</pre>
<h3>Complete Code within functions.php</h3>
<pre class="brush: php;">
function makeshorturl()
{
global $post;

$short_url = json_decode(file_get_contents('http://api.bit.ly/v3/shorten?login=[username]&amp;apiKey=[apikey]&amp;longURL='.urlencode(get_permalink($post-&gt;ID)).'&amp;format=json'));

if($short_url-&gt;status_code==&quot;200&quot;)
    {
         $short_url = $short_url-&gt;data-&gt;url;
    }
    else
    {
        $short_url = &quot;Bit.ly Error! &quot;.$short_url-&gt;status_txt;
    }
    do_action('makeshorturl');
    return $short_url;
}

function shorturl_metabox()
{
    if(is_admin())
    {
        add_meta_box('bitlyurl',__('Short URL','short-url'),'showshorturlbox','post','side');
        add_meta_box('bitlyurl',__('Short URL','short-url'),'showshorturlbox','page','side');
    }
}

function showshorturlbox()
{
    echo '&lt;label for=&quot;bitlyurl&quot;&gt;'.__('Shortened URL','short-url-label').': '.makeshorturl().'&lt;/label&gt;&lt;br/&gt;&lt;br/&gt;';
}

add_action('publish_post','makeshorturl');
add_action('publish_page','makeshorturl');
add_action('do_meta_boxes','shorturl_metabox');
</pre>
<h3>Usage</h3>
<p>If you did like to show off the shortened URL to your users simply insert this code where you want the short URL to show up:</p>
<pre class="brush: php;">
&lt;?php echo makeshorturl(); ?&gt;
</pre>
<h2>BONUS</h2>
<p>Want a ready-to-use solution? Here&#8217;s the plugin version of the above code that will generate the shortened URLs on the fly for you to share. If you did like to call the functions from within the theme template, you can do so by using: </p>
<pre class="brush: php;">
&lt;?php echo wps_hook(); ?&gt;
</pre>
<p><em><strong>Note: </strong>Above tag is for the plugin only. </em></p>
<p><em>PS:</em> The plugin can also show number of clicks on a shortened link :) per shortened URL</p>
<h3>Download it!</h3>
<p><a href="http://fuelyourcoding.com/files/wp_shorturlmaker.zip" rel="nofollow"><img src="http://fuelyourcoding.com/files/downloadplugin1.jpg" alt="Download Plugin - WP Short URL Maker" title="Download Plugin - WP Short URL Maker" width="300" height="60" class="alignleft size-full wp-image-1043" border="0"/></a></p>
]]></content:encoded>
			<wfw:commentRss>http://fuelyourcoding.com/wordpress-auto-url-shortening/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Create a simple &#8220;shop&#8221; page in Textpattern</title>
		<link>http://fuelyourcoding.com/create-a-simple-shop-page-in-textpattern/</link>
		<comments>http://fuelyourcoding.com/create-a-simple-shop-page-in-textpattern/#comments</comments>
		<pubDate>Thu, 20 May 2010 12:32:19 +0000</pubDate>
		<dc:creator>Marie Poulin</dc:creator>
				<category><![CDATA[Concepts & Training]]></category>
		<category><![CDATA[Developer Tools]]></category>
		<category><![CDATA[Languages]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Textpattern]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://fuelyourcoding.com/?p=881</guid>
		<description><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
&#60;txp:cbs_category_list parent=&#34;shop&#34; wraptag=&#34;ul&#34; break=&#34;li&#34; class=&#34;subnav&#34; section=&#34;shop&#34; showcount=&#34;false&#34; class=&#34;subnav&#34; activeclass=&#34;active&#34;/&#62;
Using the plugin cbs_category_list, this pulls a list of all of the categories with a parent category of &#8220;shop&#8221;, wraps each category in a list tag, wraps the whole thing in an unordered list with a class of subnav, and assigns a class of active on list [...]]]></description>
			<content:encoded><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
<p>This tutorial assumes that you have a fairly strong understanding of  HTML and CSS, as well as a basic understanding of Textpattern and its  tags. (I won&#8217;t be going into detail about the css) We will be building a very simple &#8220;shop&#8221; type page in Textpattern.  There are plugins which allow Textpattern to integrate paypal support,  but this is a fairly simple alternative. This allows you to feature  products which you may sell through paypal, e-junkie, Amazon (or  whatever else you may be using) The structure of this page is built with  the client in mind &#8211; they don&#8217;t need to format the page with any html  or div&#8217;s in order to get the products laid out nicely.</p>
<p>Two example links of this simple functionality in action are:</p>
<p>1. <a href="http://www.meghantelpner.com/shop/?c=books" target="_blank">http://www.meghantelpner.com/shop/?c=books</a></p>
<p>2. <a href="http://www.elmwoodspa.com/shop/">http://www.elmwoodspa.com/shop/</a></p>
<p>In the first example, you can click on one of Meghan&#8217;s books to see more information before deciding to purchase. If you click on &#8220;buy now&#8221;, you will be taken to her e-junkie store. Additionally, if you click on a specific book to see more information, you get a small navigation block at the top of the article that allows you to quickly browse the next and previous products. You may notice that if you click on one of the other submenus within her store, such as the Books/DVDs/Audio, that you will be taken directly to the Amazon affiliate link for that product. The client has the capacity to choose whether or not to link the product to an external link (Amazon, e-junkie, paypal) or whether or not to link to the full product page itself first, with a &#8220;buy now&#8221; button.</p>
<p>In the second example, you can click to see details/shop online which takes you immediately to Elmwood Spa&#8217;s online store.</p>
<p>I will be using the first example as a basis for the tutorial.</p>
<p>Plugins used: <a href="http://textpattern.org/plugins/470/cbs_category_list">cbs_category_list</a>, <a href="http://textpattern.org/plugins/186/zem_nth">zem_nth</a> (both optional) and <a href="http://utterplush.com/txp-plugins/upm-image">upm_image</a></p>
<p>First you&#8217;ll want to set up some custom fields, depending on how you want your shop to function. For Meghan&#8217;s shop, there are instances where she links to external products via a buy now button. Other times, she&#8217;ll want to link to an external site without the buy now button. So I have created 2 custom fields, &#8220;link to this site&#8221; and &#8220;buynow.&#8221; If you link exclusively to Paypal links, you could name it paypal, or whatever is easy for you to remember. (As long as you adjust it accordingly in the article forms)</p>
<p><img class="alignnone size-full wp-image-883" title="customfields" src="http://fuelyourcoding.com/files/customfields.jpg" alt="customfields" width="547" height="99" /></p>
<p>Now let&#8217;s take a look at one of the product pages inside textpattern:</p>
<p><img class="alignnone size-full wp-image-884" title="shop1" src="http://fuelyourcoding.com/files/shop1.jpg" alt="shop1" width="606" height="411" /></p>
<p>1. The title that will appear on the shop landing page</p>
<p>2. The description that will appear only one the item is clicked on</p>
<p>3. This is the link that the thumbnail and title will link to if you put a link (full url) here, otherwise:</p>
<p>4. A buy now button will appear and will link to the full url pasted here (if a link is not placed in either field, the title and thumbnail will merely link to the full article page automatically)</p>
<p>5. Place the image id number here that you want to associate with the article (the thumbnail version of this image will appear on the shop landing page, while the full image size will show on the individual article page.)</p>
<p>6. Choose the appropriate section for your article, in this instance, &#8220;shop.&#8221;</p>
<p>7. Select the appropriate categoryfor the article (if applicable. You may not have a need for categories)</p>
<p>8. IF USING THE BUY NOW FIELD you must use the override form named shop_listing2 (I&#8217;ll explain below)</p>
<p>SAVE your article!</p>
<div id="attachment_886" class="wp-caption alignnone" style="width: 616px"><img class="size-full wp-image-886" title="shop2" src="http://fuelyourcoding.com/files/shop2.jpg" alt="shop subnav" width="606" height="365" /><p class="wp-caption-text">shop subnav</p></div>
<p>In the actual page template for the shop, the code that calls the shop submenu (books and guides, etc) looks like this:</p>
<pre class="brush: xml;">&lt;txp:cbs_category_list parent=&quot;shop&quot; wraptag=&quot;ul&quot; break=&quot;li&quot; class=&quot;subnav&quot; section=&quot;shop&quot; showcount=&quot;false&quot; class=&quot;subnav&quot; activeclass=&quot;active&quot;/&gt;</pre>
<p>Using the plugin cbs_category_list, this pulls a list of all of the categories with a parent category of &#8220;shop&#8221;, wraps each category in a list tag, wraps the whole thing in an unordered list with a class of subnav, and assigns a class of active on list items when they are active. Handy dandy! You don&#8217;t necessarily need to use this plugin if your shop does not need this type of subnav.</p>
<p>Ok, so how do we pull all of our shop items into the page? The article tag in our shop page template looks like this:</p>
<div>
<pre class="brush: xml;">&lt;txp:article listform=&quot;shop_listing&quot; form=&quot;shop&quot; limit=&quot;99&quot; sort=&quot;posted asc&quot;/&gt;</pre>
</div>
<p>So this tag basically says: on the landing page (or listform version of the page), display the articles using the form of &#8220;shop_listing&#8221;. If you&#8217;re looking at an individual article page, (i.e. an individual product page) display the article using the form &#8220;shop&#8221;. Limit the amount of articles shown to 99, and sort them by date of Posted Ascending.</p>
<p>The &#8220;shop_listing&#8221; form looks like this:</p>
<div>
<pre class="brush: xml;">&lt;div class=&quot;shop-item&quot;&gt;  &lt;a href=&quot;&lt;txp:permlink  /&gt;&quot;&gt;&lt;txp:upm_article_image type=&quot;thumbnail&quot;  class=&quot;shopimg&quot;/&gt;&lt;/a&gt;  &lt;h3&gt;&lt;txp:permlink&gt;&lt;txp:title  /&gt;&lt;/txp:permlink&gt;&lt;/h3&gt;  &lt;span&gt;&lt;a href=&quot;&lt;txp:custom_field  name=&quot;buynow&quot; /&gt;&quot;&gt;BUY NOW&lt;/a&gt;&lt;/span&gt;  &lt;/div&gt;</pre>
</div>
<p>Translation: the thumbnail version of the article&#8217;s image is being pulled from the &#8220;Article image&#8221; field in the article, and assigned the class of &#8220;shopimg&#8221; for styling purposes. Both the title and thumbnail are linked to the permanent link to the article (which will show the body/description of the product. The Buy Now button links to whatever gets put into the custom field named &#8220;buynow.&#8221; The shop-item css looks something like: .shop-item {float:left; margin:20px 25px 10px 0; width:175px; }</p>
<p><em>Alternately, if you want to get really nerdy, you could use the plugin <a href="http://textpattern.org/plugins/186/zem_nth">zem_nth</a> to tell every third (or whatever number) post to display with different class. I use it to apply &#8220;shop-item-last&#8221; (<span style="font-style: normal;"><em>which has a margin-right of zero) <span style="font-style: normal;"><em>to every third item , so the last item in every row doesn&#8217;t have any extra margin space on the right. You can choose to do your layouts with or without zem_nth. This is what my shop_listing article form really looks like:</em></span></em></span></em></p>
<pre class="brush: xml;">&lt;txp:zem_nth step=&quot;1&quot; of=&quot;3&quot;&gt;&lt;div class=&quot;shop-item&quot;&gt;&lt;/txp:zem_nth&gt;&lt;txp:zem_nth step=&quot;2&quot; of=&quot;3&quot; &gt;&lt;div class=&quot;shop-item&quot;&gt;&lt;/txp:zem_nth&gt;&lt;txp:zem_nth step=&quot;3&quot; of=&quot;3&quot; &gt;&lt;div class=&quot;shop-item-last&quot;&gt;&lt;/txp:zem_nth&gt;&lt;a href=&quot;&lt;txp:permlink /&gt;&quot;&gt;&lt;txp:upm_article_image type=&quot;thumbnail&quot; class=&quot;shopimg&quot;/&gt;&lt;/a&gt;&lt;h3&gt;&lt;txp:permlink&gt;&lt;txp:title /&gt;&lt;/txp:permlink&gt;&lt;/h3&gt;&lt;span class=&quot;register&quot;&gt;&lt;a href=&quot;&lt;txp:custom_field name=&quot;buynow&quot; /&gt;&quot;&gt;BUY NOW&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;txp:zem_nth step=&quot;3&quot; of=&quot;3&quot; &gt;&lt;hr class=&quot;space&quot; /&gt;&lt;/txp:zem_nth&gt;</pre>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 2145px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">&lt;txp:zem_nth step=&#8221;1&#8243; of=&#8221;3&#8243;&gt;&lt;div&gt;&lt;/txp:zem_nth&gt;</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 2145px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">&lt;txp:zem_nth step=&#8221;2&#8243; of=&#8221;3&#8243; &gt;&lt;div&gt;&lt;/txp:zem_nth&gt;</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 2145px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">&lt;txp:zem_nth step=&#8221;3&#8243; of=&#8221;3&#8243; &gt;&lt;div&gt;&lt;/txp:zem_nth&gt;</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 2145px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">&lt;a href=&#8221;&lt;txp:permlink /&gt;&#8221;&gt;</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 2145px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">&lt;txp:upm_article_image type=&#8221;thumbnail&#8221;/&gt;&lt;/a&gt;</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 2145px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">&lt;h3&gt;&lt;txp:permlink&gt;&lt;txp:title /&gt;&lt;/txp:permlink&gt;&lt;/h3&gt;</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 2145px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">&lt;span&gt;&lt;a href=&#8221;&lt;txp:custom_field name=&#8221;buynow&#8221; /&gt;&#8221;&gt;BUY NOW&lt;/a&gt;&lt;/span&gt;</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 2145px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">&lt;/div&gt;</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 2145px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">&lt;txp:zem_nth step=&#8221;3&#8243; of=&#8221;3&#8243; &gt;&lt;hr /&gt;&lt;/txp:zem_nth&gt;</div>
<p>The &#8220;shop_listing2&#8243; form (for products without a buy now button, linking externally) looks like this:</p>
<div>
<pre class="brush: xml;">&lt;div class=&quot;shop-item&quot;&gt;
 &lt;a href=&quot;&lt;txp:custom_field name=&quot;link to this site&quot; /&gt;&quot;  rel=&quot;external&quot;&gt;&lt;txp:upm_article_image type=&quot;thumbnail&quot;  class=&quot;shopimg&quot;/&gt;&lt;/a&gt;
 &lt;h3&gt;&lt;a href=&quot;&lt;txp:custom_field name=&quot;link to this site&quot;  /&gt;&quot;&gt;&lt;txp:title /&gt;&lt;/a&gt;&lt;/h3&gt;
 &lt;/div&gt;</pre>
</div>
<p>This tells the title and thumbnail on the listing page to link directly (in a new window/tab) to the link that is found in the &#8220;link to this site&#8221; field shown in the image above, #3. You could also include the &lt;txp:excerpt /&gt; tag if you wanted to include an excerpt. If you want the article to appear this way (without the buy now button), you need to ensure that you are using the override_form in the article named &#8220;shop_listing2&#8243;.</p>
<p>Now that we have set up what the listing page looks like for product pages, let&#8217;s look at how the individual product pages look. If you will recall the article form we used:</p>
<div>
<pre class="brush: xml;">&lt;txp:article listform=&quot;shop_listing&quot; form=&quot;shop&quot; limit=&quot;99&quot;  sort=&quot;posted asc&quot;/&gt;</pre>
</div>
<p>We need to create a form called &#8220;shop&#8221; that will determine how the individual pages look once you click on the thumbnail/title.</p>
<p>The &#8220;shop&#8221; article form looks like this:</p>
<div>
<pre class="brush: xml;">&lt;p&gt;&lt;a href=&quot;/shop&quot;&gt;Back to Shop&lt;/a&gt; |  &lt;txp:link_to_prev&gt;Previous Product&lt;/txp:link_to_prev&gt; |  &lt;txp:link_to_next&gt;Next Product&lt;/txp:link_to_next&gt;&lt;/p&gt;
 &lt;div class=&quot;right&quot;&gt;&lt;txp:upm_article_image/&gt;&lt;br /&gt;&lt;span  class=&quot;register&quot; &gt;&lt;a href='&lt;txp:custom_field  name=&quot;buynow&quot;/&gt;' &gt;BUY NOW&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;txp:body /&gt;</pre>
</div>
<p>Translation: The tags inside the paragraphs set up a small subnav which allows the user to click through to the next/previous products. Then it puts the full version of the article image in a div labelled &#8220;right&#8221; (which I float right in my css), below that place a Buy Now button which links to the url provided in the &#8220;buynow&#8221; custom field. Then display the body of the article. You could of course format the tags however you want. (image on top with text below, etc). Individual product page pictured below:</p>
<div id="attachment_888" class="wp-caption alignnone" style="width: 616px"><img class="size-full wp-image-888" title="individualpage" src="http://fuelyourcoding.com/files/individualpage.jpg" alt="individual product page" width="606" height="525" /><p class="wp-caption-text">individual product page</p></div>
<p>Using custom fields is a great way to allow the client (who doesn&#8217;t know how to code) to be able to add new items to the shop easily without having to see any textpattern or html tags, and avoid them forgetting to close link tags and add things like rel=&#8221;external&#8221;. Yay!</p>
<p>This tutorial assumes that you have textpattern installed and ready to go, and have a good grasp of the tags.</p>
<p>( Download the latest version of Textpattern here: http://textpattern.com/download )</p>
<p>Did I miss anything? If you need any more clarity or have any questions, please feel free to put them in the comments, and I will do my best to help.</p>
<p>Happy Coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://fuelyourcoding.com/create-a-simple-shop-page-in-textpattern/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Emailify Your App with Gmail and Ruby</title>
		<link>http://fuelyourcoding.com/emailify-your-app-with-gmail-and-ruby/</link>
		<comments>http://fuelyourcoding.com/emailify-your-app-with-gmail-and-ruby/#comments</comments>
		<pubDate>Thu, 13 May 2010 14:00:52 +0000</pubDate>
		<dc:creator>Jerod Santo</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[gems]]></category>
		<category><![CDATA[gmail]]></category>
		<category><![CDATA[google]]></category>

		<guid isPermaLink="false">http://fuelyourcoding.com/?p=965</guid>
		<description><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
]]></description>
			<content:encoded><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
<p>Sending and receiving email from your application isn&#8217;t hard, but lets be honest, its not as easy as you&#8217;d like either. If you haven&#8217;t considered using <a href="http://mail.google.com">Gmail</a> to manage inbound/outbound email, you really should! The advantages of using Gmail over a local SMTP server or Sendmail include:</p>
<ul>
<li>No tricky mail server configuration</li>
<li>Google&#8217;s spam filtering is excellent</li>
<li>Free archive/backup of your email history</li>
<li>Easy manual administration when necessary</li>
</ul>
<p>Any language with <a href="http://en.wikipedia.org/wiki/Imap">IMAP</a> capabilities in its core, standard library, or 3rd party ecosystem can connect to Gmail for email processing. If that language happens to be <a href="http://www.ruby-lang.org/en/">Ruby</a>, it&#8217;s even easier thanks the the <a href="http://dcparker.github.com/ruby-gmail/">ruby-gmail</a> gem by <a href="http://BehindLogic.com">Daniel Parker</a>. Check it out.</p>
<h2>Installing</h2>
<p>Easy peasy.</p>
<pre class="brush: bash;">
gem install ruby-gmail
</pre>
<h2>Connecting to Gmail</h2>
<p>Connecting up is quite easy, and there are two options for how to proceed. First, you can perform all your activities inside a block. The advantage of this is the library will automatically log you out at the end of the block:</p>
<pre class="brush: ruby;">
require 'gmail'

Gmail.new(username, password) do |gmail|
  # send commands
end
# logged out
</pre>
<p>Second, you can store the connection in a variable and logout it explicitly when done:</p>
<pre class="brush: ruby;">
require 'gmail'

gmail = Gmail.new(username, password)
# send commands
gmail.logout
# logged out
</pre>
<h2>Managing Email</h2>
<p>The <tt>mailbox</tt> method takes a label as an argument and returns an object which has access to email with the given label.</p>
<pre class="brush: ruby;">
inbox  = gmail.mailbox('inbox')
urgent = gmail.mailbox('urgent')
</pre>
<p>Since <tt>inbox</tt> is such a common label to access, there&#8217;s a handy shortcut method:</p>
<pre class="brush: ruby;">
inbox = gmail.inbox
</pre>
<p>Now that you have a mailbox object in hand, you can access its emails or get counts:</p>
<pre class="brush: ruby;">
inbox.emails #  an array of all emails in mailbox
inbox.emails(:unread) # an array of unread emails
inbox.emails(:from =&gt; &quot;phb@work.com&quot;) # an array of emails from PHB
</pre>
<pre class="brush: ruby;">
inbox.count # how many emails in the mailbox
inbox.count(:unread) # how many unread
inbox.count(:from =&gt; &quot;phb@work.com&quot;) # how many from PHB
</pre>
<p>You can also perform many tasks on an individual email:</p>
<pre class="brush: ruby;">
email = inbox.emails.first

email.mark(:read)
email.archive!
email.delete!
email.label('urgent')
email.move_to('followup')
</pre>
<h2>Sending Email</h2>
<p>Creating and sending emails is also a breeze. Just like connecting you can use the idiomatic Ruby block method, or the more object-oriented approach:</p>
<pre class="brush: ruby;">
# with a block
gmail.deliver do
  to &quot;phb@work.com&quot;
  subject &quot;Not feeling well&quot;
  text_part do
    body &quot;I won't be coming in today.&quot;
  end
  html_part do
    body &quot;&lt;p&gt;I &lt;em&gt;won't&lt;/em&gt; be coming in today.&lt;/p&gt;&quot;
  end
end

# or generate message and send it later
email = gmail.generate_message do
  to &quot;phb@work.com&quot;
  subject &quot;Not feeling well&quot;
  body &quot;I won't be coming in today.&quot;
end

email.deliver!
</pre>
<p>The library will take care of sending it out your Gmail account and even set the &#8220;From&#8221; header for you. Nice!</p>
<h2>Try It</h2>
<p>If you&#8217;re already using Ruby to build an application and you need it to send or receive email, there is little excuse not to let <a href="http://dcparker.github.com/ruby-gmail">Ruby-Gmail</a> do the heavy lifting for you. Give it a try!</p>
]]></content:encoded>
			<wfw:commentRss>http://fuelyourcoding.com/emailify-your-app-with-gmail-and-ruby/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Meet Storytlr</title>
		<link>http://fuelyourcoding.com/meet-storytlr/</link>
		<comments>http://fuelyourcoding.com/meet-storytlr/#comments</comments>
		<pubDate>Mon, 10 May 2010 14:08:17 +0000</pubDate>
		<dc:creator>John Hobbs</dc:creator>
				<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Languages]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://fuelyourcoding.com/?p=932</guid>
		<description><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
]]></description>
			<content:encoded><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
<h2>What is Storytlr?</h2>
<p><a href="http://en.wikipedia.org/wiki/Lifestreaming">Lifestreaming</a> is the aggregation of all of your actions throughout the web in one place to present a complete picture of your digital life. There are several lifestreaming applications out there, and <a href="http://storytlr.org/">Storytlr</a> was one of the first.</p>
<p>Storytlr was originally a closed source, hosted web application started by Laurent Eschenauer and Alard Weisscher in 2008. In October 2009 they decided to close the service and in December they open sourced the code.</p>
<p>Considerable community development has occurred since the project was open sourced, including many new plugins, bug fixes and features.</p>
<h2>Installing Storytlr</h2>
<p>Storytlr is written in PHP and based around the <a href="http://framework.zend.com/">Zend</a> framework. It is usually run on Apache, but works fine on lighttpd and Nginx. The current stable release is 0.9.2, although there is an RC 0.9.3 that works well.  Additionally you can use the bleeding edge code on <a href="http://github.com/storytlr/core">GitHub</a>.  I currently maintain my own version of 0.9.3 that has a few more features and plugins you won&#8217;t find in the core. You can find it <a href="http://github.com/jmhobbs/storytlr">here</a>.</p>
<p>Since it&#8217;s coming out of a close source system, expect some rough edges and thin documentation.  This is improving all the time with the growing <a href="http://code.google.com/p/storytlr/wiki/WikiHome?tm=6">wiki</a> and the <a href="http://code.google.com/p/storytlr/issues/list">issues board</a>.  Installation is still one of those rough edges, but it&#8217;s fairly easy anyway.</p>
<p>For simplicity I&#8217;ll be using the 0.9.2 release from the <a href="http://code.google.com/p/storytlr/downloads/list">Google Code site</a>, but these instructions can be easily adapted to other versions.  I&#8217;ll be doing just about everything from the command line, so if you don&#8217;t have shell access, be prepared to tweak things a bit.</p>
<h3>Requirements</h3>
<p>First, let&#8217;s make sure our server is compatible.  0.9.2 has the following requirements:</p>
<ul>
<li>PHP 5</li>
<li>mcrypt</li>
<li>PDO</li>
<li>Tidy</li>
<li>MySQL</li>
<li>Zend Framework</li>
</ul>
<p>An easy way to check compatibility is to use <a href="http://gist.github.com/raw/393739/storytlr_requirements_check.php">this script</a>.</p>
<p>Most hosts have these extensions. The rarest one is Tidy.  For instance, Dreamhost does not run Tidy.  If your host doesn&#8217;t have Tidy, you can work around it by using a different version with the <a href="http://code.google.com/p/storytlr/issues/detail?id=64&amp;can=1&amp;q=htmLawed#c1">htmLawed patch</a>.</p>
<p>If you are missing Zend, that can be downloaded <a href="http://framework.zend.com/download/current/">here</a>. Make sure to put it in your PHP include path.</p>
<h3>Getting Started</h3>
<p>Now that you&#8217;ve got the requirements met, download the <a href="http://code.google.com/p/storytlr/downloads/list">0.9.2 file</a> and unpack it into your root web directory.</p>
<pre class="brush: bash;">
jmhobbs@katya:/var/www/lifestream$ wget http://storytlr.googlecode.com/files/storytlr-0.9.2.tgz
--2010-05-07 13:33:05--  http://storytlr.googlecode.com/files/storytlr-0.9.2.tgz
Resolving storytlr.googlecode.com... 74.125.45.82
Connecting to storytlr.googlecode.com|74.125.45.82|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 8748114 (8.3M) [application/x-gzip]
Saving to: “storytlr-0.9.2.tgz”

100%[============================================&gt;] 8,748,114    233K/s   in 36s

2010-05-07 13:33:41 (239 KB/s) - “storytlr-0.9.2.tgz” saved [8748114/8748114]

jmhobbs@katya:/var/www/lifestream$ tar -zxf storytlr-0.9.2.tgz
jmhobbs@katya:/var/www/lifestream$ ls -a
.  ..  feeds  flash  friendconnect  .htaccess  images  index.php  INSTALL  js  LICENSE  protected  storytlr-0.9.2.tgz  style  themes
jmhobbs@katya:/var/www/lifestream$
</pre>
<h3>The Database</h3>
<p>Now you need to load the database schema. The schema files is located at <tt>protected/install/database.sql</tt>.  If you don&#8217;t have a database or user set up, now is the time to do that as well.</p>
<pre class="brush: bash;">
jmhobbs@katya:/var/www/lifestream$ cd protected/install/
jmhobbs@katya:/var/www/lifestream/protected/install$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 5515
Server version: 5.0.81-1 (Debian)

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql&gt; create database lifestream;
Query OK, 1 row affected (0.05 sec)

mysql&gt; grant all on lifestream.* to lifestream@localhost identified by 'supersecretpassword';
Query OK, 0 rows affected (0.11 sec)

mysql&gt; flush privileges;
Query OK, 0 rows affected (0.08 sec)

mysql&gt; use lifestream;
Database changed
mysql&gt; source database.sql
Query OK, 0 rows affected (0.00 sec)

(Lines Removed For Brevity)

Query OK, 0 rows affected (0.00 sec)

mysql&gt; Bye
jmhobbs@katya:/var/www/lifestream/protected/install$
</pre>
<h3>Configuration</h3>
<p>Your last major step is the configuration file, which goes at <tt>protected/config/config.ini</tt>.  Storytlr provides an example file with good defaults, so we&#8217;ll edit that.  The key settings to change are:</p>
<ul>
<li>db.username</li>
<li>db.password</li>
<li>db.dbname</li>
<li>security.cookie</li>
<li>web.host</li>
<li>web.timezone</li>
</ul>
<pre class="brush: bash;">
jmhobbs@katya:/var/www/lifestream$ cd protected/config/
jmhobbs@katya:/var/www/lifestream/protected/config$ ls
config.ini.sample
jmhobbs@katya:/var/www/lifestream/protected/config$ cp config.ini.sample config.ini
jmhobbs@katya:/var/www/lifestream/protected/config$ vim config.ini

[general]

;Database connection settings
db.adapter=PDO_MYSQL
db.host=localhost
db.username=lifestream
db.password=supersecretpassword
db.dbname=lifestream

;Security
security.cookie = kg89y6gbval

;Caching
;cache.content = 1
;cache.metadata = 1
;cache.path = /tmp/cache/

;Web deployment settings
web.host=lifestream.velvetcache.org
web.path=/
web.redirect = 1
web.timezone=America/Chicago
jmhobbs@katya:/var/www/lifestream/protected/config$
</pre>
<h3>The Fruits of Our Labor</h3>
<p>At this point your lifestream should be working, open a browser and take a look.</p>
<p><img class="alignnone size-medium wp-image-934" title="It Works!" src="http://fuelyourcoding.com/files/storytlr-1-600x429.png" alt="It Works!" width="600" height="429" /></p>
<p>Now we need to change our password, so go to the admin page <tt>http://www.example.com/admin</tt> and log in. The default username and password are <tt>admin</tt> and <tt>storytlr</tt> respectively.  You can find that under <strong>Configure » Password</strong>.</p>
<p><img class="alignnone size-medium wp-image-936" title="Change Password" src="http://fuelyourcoding.com/files/storytlr-3-600x429.png" alt="Change Password" width="600" height="429" /></p>
<p>There are lots of options to browse through, and I won&#8217;t cover them all, but I&#8217;d like to run through setting up a source. Sources are the core of lifestreaming, and there are lots of options to choose from. In the admin interface go to <strong>Sources</strong> and click <strong>Add</strong> next to a source you want to add, I&#8217;ll use Delicious in my example.</p>
<p>This should present you with a form asking for some information. Each source is going to be slightly different, but all should be pretty easy to understand. Fill that out and it should import what it can from that source.</p>
<p><img class="alignnone size-medium wp-image-938" title="Delicious" src="http://fuelyourcoding.com/files/storytlr-5b-600x429.png" alt="Delicious" width="600" height="429" /></p>
<p><img class="alignnone size-medium wp-image-939" title="Importing" src="http://fuelyourcoding.com/files/storytlr-6b-600x429.png" alt="Importing" width="600" height="429" /></p>
<p>There you have it! Add some more sources until your lifestream really fleshes out.</p>
<p><img class="alignnone size-medium wp-image-940" title="Lifestream!" src="http://fuelyourcoding.com/files/storytlr-8b-600x429.png" alt="Lifestream!" width="600" height="429" /></p>
<h3>Keeping Current</h3>
<p>The very last step, which is often overlooked, is updating your sources. The primary means for this is the PHP script <tt>protected/tools/update.php</tt>. This must be run from the command line with the name of the user to update.  Here&#8217;s an example:</p>
<pre class="brush: bash;">
jmhobbs@katya:/var/www/lifestream$ php5 protected/tools/update.php admin
Memory usage on startup: 4997940
Memory: 5351904
Memory: 5351904
Updating source delicious for user admin [0/2] (5).... found 0 items
Updated 1 out of 2 sources in 1 seconds.
jmhobbs@katya:/var/www/lifestream$
</pre>
<p>It&#8217;s common to set up a cron job to handle these updates. It&#8217;s often important to put in full paths for your cron jobs.  This example will update my sources every 10 minutes. You can learn more about cron <a href="http://www.linuxhelp.net/guides/cron/">here</a>.</p>
<pre class="brush: bash;">
jmhobbs@katya:/var/www/lifestream$ crontab -e
MAILTO=jmhobbs@towncommons.com
# m h  dom mon dow   command
*/10 * * * * /usr/bin/php5 /var/www/lifestream/protected/tools/update.php admin
jmhobbs@katya:/var/www/lifestream$
</pre>
<p>Storytlr has lots more features and configuration options, I would encourage you to browse around and make your installation suit your taste. To see an example of a fully customized Storytlr installation, you can visit mine at <a href="http://lifestream.velvetcache.org/">http://lifestream.velvetcache.org/</a></p>
<h2>Going Further</h2>
<p>Storytlr is rich with opportunities to contribute. It&#8217;s fairly young and has lots of finicky little things to figure out, and it can always use one more plugin.  Lots of stuff is in the works, including a much simpler installer which will make most of this article obsolete!</p>
<p>Documentation is in need of some TLC, and more eyes on the bug reports would be great.</p>
<p>To get involved visit the <a href="http://code.google.com/p/storytlr">Storytlr Google Code</a> site or hop onto Github and <a href="http://github.com/storytlr/core">fork the project</a>.  Finally, you can also join us on Freenode IRC in <a href="irc://chat.freenode.net/storytlr">#storytlr</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://fuelyourcoding.com/meet-storytlr/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Open-Source Spotlight: Underscore.js</title>
		<link>http://fuelyourcoding.com/open-source-spotlight-underscorejs/</link>
		<comments>http://fuelyourcoding.com/open-source-spotlight-underscorejs/#comments</comments>
		<pubDate>Thu, 01 Apr 2010 16:20:36 +0000</pubDate>
		<dc:creator>Jerod Santo</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Languages]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://fuelyourcoding.com/?p=856</guid>
		<description><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
]]></description>
			<content:encoded><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
<p>JavaScript is a powerful language, but it lacks some of the handy utilities that developers of other languages like Ruby &amp; Python have come to know and love. <a href="http://documentcloud.github.com/underscore/">Underscore.js</a> is your utility belt. In the author&#8217;s own words:</p>
<blockquote><p>Underscore is a utility-belt library for JavaScript that provides a lot of the functional programming support that you would expect in Prototype.js (or Ruby), but without extending any of the built-in JavaScript objects. It&#8217;s the tie to go along with jQuery&#8217;s tux.</p></blockquote>
<p><a href="http://documentcloud.github.com/underscore/">Underscore.js</a> provides collection functions like <tt>each</tt>, <tt>map</tt>, <tt>include</tt>, and <tt>reduce</tt>. It makes arrays more powerful by adding <tt>flatten</tt>, <tt>uniq</tt>, and <tt>intersect</tt>. It extends objects with many useful functions like <tt>keys</tt>, <tt>values</tt>, <tt>functions</tt>, <tt>isNaN</tt>, and many more.</p>
<p>A few examples to whet your appetite:</p>
<p>Using the <tt>each</tt> function to write each array value to the console:</p>
<pre class="brush: jscript;">
// object-oriented way
_(['John', 'Paul', 'George', 'Ringo']).each(function(beatle) {
    console.log(beatle);
});
// functional way
_.each(['John', 'Paul', 'George', 'Ringo'], function(beatle) {
    console.log(beatle);
});
</pre>
<p>Using the <tt>reduce</tt> method to round three numbers down and sum the results:</p>
<pre class="brush: jscript;">
_.reduce([1.5,2,3.7], 0, function(memo, num) { return memo + Math.floor(num) });
// =&gt; 6
</pre>
<p>Using the <tt>pluck</tt> method to to extract just the names from an array of objects:</p>
<pre class="brush: jscript;">
var beatles = [
  {name: 'John', dead: true},
  {name: 'Paul', dead: false},
  {name: 'Ringo', dead: false},
  {name: 'George', dead: true}
]

_.pluck(beatles, 'name');
// =&gt; [&quot;John&quot;, &quot;Paul&quot;, &quot;Ringo&quot;, &quot;George&quot;]
</pre>
<p>The library weighs in at just <strong>2.5kb</strong> once packed and gzipped, so there is little excuse not to take advantage of its offerings. There are over 60 functions included, the documentation on how to use each function is great, the source code is freely available <a href="http://github.com/documentcloud/underscore/">on GitHub</a>, and the library is completely DOM-free which means you can use it server-side as well.</p>
<p>Thanks to <a href="http://github.com/jashkenas">Jeremy Ashkenas</a> and the folks at <a href="http://www.documentcloud.org/home">DocumentCloud</a> for a great open-source library that we can all benefit from!</p>
]]></content:encoded>
			<wfw:commentRss>http://fuelyourcoding.com/open-source-spotlight-underscorejs/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Set Rails Logging on Fire</title>
		<link>http://fuelyourcoding.com/set-rails-logging-on-fire/</link>
		<comments>http://fuelyourcoding.com/set-rails-logging-on-fire/#comments</comments>
		<pubDate>Fri, 19 Mar 2010 17:10:14 +0000</pubDate>
		<dc:creator>Jerod Santo</dc:creator>
				<category><![CDATA[Plugins / Add-Ons]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[firebug]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://fuelyourcoding.com/?p=842</guid>
		<description><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
]]></description>
			<content:encoded><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
<p>Rails 2.3+ and Rails 3 rely on <a href="http://rack.rubyforge.org/">Rack</a>, a minimal (and awesome) interface between Ruby and webservers. This has many advantages, one of which is the ability to easily swap Rack applications (middlewares) in &#038; out of your Rails app. Modularity FTW!</p>
<p>One fun (and useful) example of a Rack middleware is a Firebug logger written by <a href="http://sjjdev.com">Simon Jefford</a> for the <a href="http://coderack.org/">CodeRack</a> competition. This middleware allows you to send arbitrary messages directly to <a href="http://getfirebug.com/">Firebug</a>. Why? Since you&#8217;re already debugging much of your Rails app in a browser anyway, sending debug output to your browser&#8217;s console (instead of tailing a log file) makes a lot of sense.</p>
<p><em>NOTE: FirebugLogger plays nice with WebKit&#8217;s Web Inspector as well.</em></p>
<p>Simon also released a <a href="http://github.com/simonjefford/rack_firebug_logger">Rails plugin</a> that you can install to set up the middleware for you, but it&#8217;s more fun (and informative) to set it up yourself. Here&#8217;s how:</p>
<h2>Setup</h2>
<p>The goal is to be able to send arbitrary messages to Firebug from any controller or view.</p>
<p>Rails autoloads (and namespaces) any code placed in the <tt>lib</tt> directory, so that is where we&#8217;ll place our FirebugLogger code. Grab the code from <a href="http://gist.github.com/252575">my gist</a>, which is a fork of <a href="http://gist.github.com/210069">Simon&#8217;s original</a> with minor improvements, and place it inside your Rails app in:</p>
<pre class="brush: plain;">
lib/rack/firebug_logger.rb
</pre>
<p>Rails will load the code for us, but we need to manually activate the middleware. Since this bit of code is only useful during development, we&#8217;ll load it up in that environment only.</p>
<pre class="brush: ruby;">
# config/environments/development.rb
# ... other stuff ...
config.middleware.use ::Rack::FirebugLogger
</pre>
<h2>Using FirebugLogger</h2>
<p>Using the middleware is pretty straight forward. It will process an array of arrays, each of which has a log level and a message. Add a single line like the one below to an existing controller action and load up the page:</p>
<pre class="brush: ruby;">
# app/controllers/posts_controller.rb
class PostsController &lt; ApplicationController
  def index
    @posts = Post.all
    request.env['firebug.logs'] = [[:info, &quot;hello from rack!&quot;]]
  end
  # ... other actions ...
end
</pre>
<p>Open Firebug and you should see &#8220;hello from rack!&#8221; glaring back at you. You can do the same thing in views:</p>
<pre class="brush: ruby;">
# app/views/posts/index.html.erb
&lt;% request.env['firebug.logs'] = [[:warn, &quot;inside a view!&quot;]] %&gt;
</pre>
<h2>Adding a Helper</h2>
<p>Using the logger like this is a bit tedious, and it&#8217;s not easy to create multiple messages for a single request. Let&#8217;s wrap the functionality up into a method that we can call. This method should be placed in the application controller so that all other controllers inherit it.</p>
<pre class="brush: ruby;">
# app/controllers/application_controller.rb
class ApplicationController &lt; ActionController::Base
# ... other stuff ...
helper_method :firebug

  private

  def firebug(message,type = :debug)
    request.env['firebug.logs'] ||= []
    request.env['firebug.logs'] &lt;&lt; [type.to_sym, message.to_s]
  end
end
</pre>
<p>This method will initialize an empty array the first time it is called and then push new messages on to the array on subsequent calls. Notice that it calls <tt>to_s</tt> on the <tt>message</tt> variable before passing it on. This means you can send the method a string or any object that responds to <tt>to_s</tt> and it will just work. Specifying a log type is optional, the method is private and it is explicitly added as a <tt>helper_method</tt> so that you can access it from views as well.</p>
<p>Now writing logs to Firebug is as easy as:</p>
<pre class="brush: ruby;">
firebug &quot;woop woop!&quot;
# optionally specify a log level
firebug &quot;it's a trap!&quot;, :warning
</pre>
<p>Here are a few ideas of helpful messages to send to Firebug:</p>
<pre class="brush: ruby;">
# inspect the attributes of an object
firebug @posts.first.inspect
# dump the session
firebug session
# check a user's roles
firebug current_user.roles.inspect
</pre>
<p>I highly encourage you to try this in one of your Rails apps. It has proven a useful addition to my toolkit. Let me know how it works for you by leaving a comment!</p>
]]></content:encoded>
			<wfw:commentRss>http://fuelyourcoding.com/set-rails-logging-on-fire/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Simple Debugging with WordPress</title>
		<link>http://fuelyourcoding.com/simple-debugging-with-wordpress/</link>
		<comments>http://fuelyourcoding.com/simple-debugging-with-wordpress/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 19:13:36 +0000</pubDate>
		<dc:creator>Douglas Neiner</dc:creator>
				<category><![CDATA[Concepts & Training]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[wp_debug]]></category>

		<guid isPermaLink="false">http://fuelyourcoding.com/?p=826</guid>
		<description><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
]]></description>
			<content:encoded><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
<p>For simple WordPress theme development, what is the first thing most PHP developers do to troubleshoot problems?</p>
<pre class="brush: php;">
print_r( $post );
die();
</pre>
<p>One the statements are in place, the programmer refreshes the page and looks at the source to view a nicely indented array or object. Next they comment out the <tt>print_r</tt> and <tt>die</tt> statements, change some lines, and try the code again. If it fails, they are back to square one and in go the <tt>print_r</tt>,<tt>echo</tt> and <tt>die</tt> statements so the brutal cycle can begin again.</p>
<p>We know these methods <em>partially</em> work (who hasn&#8217;t done the above during a PHP project!), but we also know they are less than optimal. Is there a better way?</p>
<h2>WordPress Debug Mode</h2>
<p>WordPress offers quite a few ways to enable and customize a debug mode while developing. To enable debug mode, you want to define <tt>WP_DEBUG</tt> as <tt>true</tt> in your wp-config.php. Here is the complete code block I suggest you use. We will look at the individual parts shortly. Place this in your <tt>wp-config.php</tt> file after the lines that define the database variables. Be sure to change <tt>development_user</tt> to be your development database user name:</p>
<pre class="brush: php;">
@ini_set('display_errors',0);
if( 'development_user' === DB_USER ){
  define('WP_DEBUG',         true);  // Turn debugging ON
  define('WP_DEBUG_DISPLAY', false); // Turn forced display OFF
  define('WP_DEBUG_LOG',     true);  // Turn logging to wp-content/debug.log ON
}
</pre>
<h3>display_errors</h3>
<p>The first line in our code block turns off the display of errors, regardless of php.ini or .htaccess settings to the contrary. This is important because though WordPress can force the display of errors to be on, it won&#8217;t force them to be off if <tt>display_errors</tt> is already turned on.</p>
<h3>Testing for local vs. production</h3>
<p>There are probably fifty ways of doing this part, so use a method that works for you. In my environments, my local development database rarely if <em>ever</em> has the same user name as the production database. Simply checking what I expect the local user name to be against what is defined in <tt>DB_USER</tt> is a simple way of knowing if the files are on the development or production servers.</p>
<h3>WP_DEBUG</h3>
<p>This is the most important constant as it determines if WordPress will use any of the other debugging constants. Thankfully it is quite simple. If set to <tt>true</tt>, debug mode is turned on. If <tt>undefined</tt> or set to <tt>false</tt>, debug mode is kept off.</p>
<h3>WP_DEBUG_DISPLAY</h3>
<p>This constant confused me at first, but it is actually quite simple. If set to <tt>true</tt>, it will override the current <tt>display_errors</tt> configuration setting and turn it on. However, if set to <tt>false</tt> it <strong>will not turn off <tt>display_errors</tt>.</strong> This setting is simply an override. This is the reason we turn <tt>display_errors</tt> off before setting any of these constants.</p>
<p>Set this constant to <tt>true</tt> if you want to see errors displayed in your browser when they occur. Keep in mind this will sometimes complicate errors because once at least one error has been written to the page, all redirect requests will fail. This is because the header information can no longer be modified once content is sent, and a displayed error counts as content.</p>
<h3>WP_DEBUG_LOG</h3>
<p>This constant is the whole reason I found the WordPress debug methods so helpful. Set this constant to <tt>true</tt> and WordPress will set up PHP to write to an error log in <tt>wp-content/debug.log</tt>. Sadly you can&#8217;t specify a different file location that is not in the content folder, but at least you know where it is!</p>
<p><em>Note: because this is written to a public directly, be extremely careful not to upload the log by mistake. Additionally, if you run WP_DEBUG on a production server, do so only for immediate troubleshooting then turn it off and remove <tt>wp-content/debug.log</tt>.</em></p>
<h2>Leveraging WP_DEBUG</h2>
<p>In addition to PHP errors being sent to <tt>debug.log</tt> we can also send our own output using the <tt>error_log</tt> PHP function. The only problem with this, is even in production mode your errors will still most likely be written to a PHP log; it just won&#8217;t be <tt>debug.log</tt>. Because of this, its a good idea to provide a wrapper function to handle the logging for your theme or plugin.</p>
<p>Place the following code in your <tt>functions.php</tt> in your theme, or in the plugin file for your WordPress plugin:</p>
<pre class="brush: php;">
if(!function_exists('_log')){
  function _log( $message ) {
    if( WP_DEBUG === true ){
      if( is_array( $message ) || is_object( $message ) ){
        error_log( print_r( $message, true ) );
      } else {
        error_log( $message );
      }
    }
  }
}
</pre>
<p>Feel free to expand on this function if it doesn&#8217;t exactly meet your needs, but the concept is simple: Centralize all your log calls to use your custom function. Then, in that <tt>_log</tt> function, only output the message if <tt>WP_DEBUG</tt> is set to <tt>true</tt>. There is no reason to test if <tt>WP_DEBUG</tt> has been defined because as soon as <tt>wp-settings.php</tt> is processed, <tt>WP_DEBUG</tt> <em>will be</em> defined, even if it wasn&#8217;t already defined in <tt>wp-config.php</tt>.</p>
<p>This particular <tt>_log</tt> snippet will call a <tt>print_r</tt> on arrays and objects passed to the function for simple debugging.</p>
<h2>Trying it Out</h2>
<p>If you have followed these steps, you can run a quick test by adding these lines into your <tt>header.php</tt> file in your theme folder:</p>
<pre class="brush: php;">
_log('Testing the error message logging');
_log(array('it' =&gt; 'works'));
</pre>
<p>After refreshing your page once, you should see a newly created <tt>debug.php</tt> file with a few lines of output. Use any log viewing utility that supports tailing the file for maximum productivity. On Mac, Unix and Linux systems, you can use this command from the main directory of your site:</p>
<pre class="brush: plain;">
tail -f wp-content/debug.log
</pre>
<h2>More Solutions</h2>
<p>If you are looking for a more interactive console for debugging, be sure to look at our review on the <a href="http://fuelyourcoding.com/plugin-review-wordpress-console/">WordPress Console</a>.</p>
<p><strong>What about you?</strong> If you didn&#8217;t already know about this built in WordPress feature, what methods did you come up with to make debugging WordPress easier? Please leave us your tips in the comments below!</p>
]]></content:encoded>
			<wfw:commentRss>http://fuelyourcoding.com/simple-debugging-with-wordpress/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>jQuery Plugin Design Patterns: Part I</title>
		<link>http://fuelyourcoding.com/jquery-plugin-design-patterns-part-i/</link>
		<comments>http://fuelyourcoding.com/jquery-plugin-design-patterns-part-i/#comments</comments>
		<pubDate>Wed, 20 Jan 2010 18:21:06 +0000</pubDate>
		<dc:creator>Douglas Neiner</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Languages]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[Plugins / Add-Ons]]></category>

		<guid isPermaLink="false">http://fuelyourcoding.com/?p=798</guid>
		<description><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
]]></description>
			<content:encoded><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
<p>jQuery plugins come in all shapes and sizes. They perform very simple or very complex tasks depending on their intended use. When it comes time for you to design your own plugin, its really important to understand what patterns other developers use and what will best suits your needs.</p>
<p>As a side note, I have built a number of plugins for my own projects and client work that will <em>never be released</em>. The jQuery community needs to stop thinking of plugins only as releasable, open-source projects, and start thinking of them instead as a reusable pieces of code that can help optimize and <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a> up a complex website. Take this little plugin as an example:</p>
<pre class="brush: jscript;">
$.fn.notice = function(){
    return this.slideDown(500).delay(4000).slideUp(500);
}
</pre>
<p>It simply abstracts the animation for displaying a notice (using jQuery 1.4). Would I ever release this on an open source site? Of course not! But it is still a fully functioning jQuery plugin that can be used over and over throughout a website.</p>
<h2>Design Pattern Series Overview</h2>
<ul>
<li>Basics &amp; Structure (this article)</li>
<li>Options &amp; Updating</li>
<li>Callbacks &amp; Custom Events</li>
<li>Misc. General Practices</li>
</ul>
<h2>Basics</h2>
<h3>Filename</h3>
<p>Every jQuery plugin sits in its own JS file, and is normally named using the following pattern:</p>
<pre class="brush: plain;">
jquery.pluginname.js
jquery.pluginname.min.js
</pre>
<p>Released plugins often also have a version number:</p>
<pre class="brush: plain;">
jquery.pluginname-1.3.js
jquery.pluginname-1.3.min.js
</pre>
<p>If you end up building a lot of plugins for your website, consider also including a namespace to keep all your files together (And of course you would combine and minify them for production, right?):</p>
<pre class="brush: plain;">
jquery.mysite.pluginname.js
jquery.mysite.pluginname.js
</pre>
<h3>Basic File Layout</h3>
<p>After any comments you choose to put at the top of your file, the very next thing you should have is a self executing anonymous function that will actually wrap your entire plugin. Say what!? Don&#8217;t worry, you have seen it before, and it looks like this:</p>
<pre class="brush: jscript;">
(function($){

   ... code here ...

})(jQuery);
</pre>
<p>This gives your plugin a private scope to work in, and also allows your plugin to be used with <code>$.noConflict</code> mode without creating a problem. By passing <tt>jQuery</tt> into the function, the <tt>$</tt> will equal jQuery <em>inside</em> the function even if <code>$</code> means something different outside your plugin.</p>
<h2>Structure</h2>
<p>There are three basic structures you will see when you look at released plugins:</p>
<h3>Contained Function</h3>
<p>In this structure, (almost) all the code to run your plugin is contained within the function used to call your plugin. This is the most common format:</p>
<pre class="brush: jscript;">
(function($){

   $.fn.myPlugin = function(){
      return this.each(function(){
         // do something
      });
   }

})(jQuery);
</pre>
<p>You <strong>should</strong> use this this structure when you are writing a simple plugin that acts once upon the jQuery result set on each execution. For complex plugins that need to maintain an adjustable state, you should consider the &#8220;Class and Function&#8221; structure.</p>
<h3>Class and Function</h3>
<p>In this structure, a class is used and an instance is created for each DOM element in the result set. You may see these objects attached in some way to the DOM elements they modify:</p>
<pre class="brush: jscript;">
(function($){
   var MyClass = function(el){
       var $el = $(el);

       // Attach the instance of this object
       // to the jQuery wrapped DOM node
       $el.data('MyClass', this);
   }

   $.fn.myPlugin = function(){
      return this.each(function(){
         (new MyClass(this));
      });
   }

})(jQuery);
</pre>
<p>You <strong>should</strong> use this structure if you need to be able to access the object later that is associated with a DOM element. It is far easier to attach a single object vs several key/value pairs using the <tt>data()</tt> method. In this approach, you can access the object by calling <tt>$('selector').data('MyClass')</tt>. This functions more like a widget and is a plugin that maintains state and can adjust its state on the fly (Learn how in the next article.).</p>
<p><em><strong>Note: </strong> Widget Factory: The next release of jQuery UI is going to see the addition of a Widget Factory that will be designed to specially assist in developing widget-like plugins. </em></p>
<h3>Extend</h3>
<p>In my opinion, this is the least idiomatic way to create a jQuery plugin. It uses the <tt>jQuery.fn.extend</tt> method instead of <tt>jQuery.fn.pluginName</tt>:</p>
<pre class="brush: jscript;">
(function($){

   $.fn.extend({
     myPlugin: function(){
      return this.each(function(){
         // do something
     },
     myOtherPlugin: function(){
      return this.each(function(){
         // do something
     }
   });

})(jQuery);
</pre>
<p>You will find this structure helpful if you need to add a <em>large number</em> of plugin methods to jQuery. I would contend, however, that if your plugin needs to add that many methods, there may be a better way to structure its implementation.</p>
<p>I feel the extend method is used more by programmers transitioning from other JS libraries. I personally find the simple <tt>$.fn.pluginName =</tt> structure to be easier to read, and more in line with what you will normally see in jQuery plugins.</p>
<h2>Up Next</h2>
<p>In the next part of this series, we will look at passing options and providing methods for updating settings and functionality after a plugin has been called.</p>
]]></content:encoded>
			<wfw:commentRss>http://fuelyourcoding.com/jquery-plugin-design-patterns-part-i/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>jQuery Enlightenment: Book Review and Giveaway (Winners Announced!)</title>
		<link>http://fuelyourcoding.com/jquery-enlightenment-book-review-and-giveaway/</link>
		<comments>http://fuelyourcoding.com/jquery-enlightenment-book-review-and-giveaway/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 20:04:58 +0000</pubDate>
		<dc:creator>Douglas Neiner</dc:creator>
				<category><![CDATA[Books / Magazines]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[books]]></category>
		<category><![CDATA[review]]></category>

		<guid isPermaLink="false">http://fuelyourcoding.com/?p=782</guid>
		<description><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
]]></description>
			<content:encoded><![CDATA[<p><p><a href="http://rss.buysellads.com/click.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1271313&k=f16d4ddc81a95a47348dcddb230bad58&a=<?php echo($a); ?>&c=<?php echo(rand()); ?>" border="0" alt="" /></a></p><p><a href="http://buysellads.com/buy/sitedetails/pubkey/f16d4ddc81a95a47348dcddb230bad58/zone/1271313" target="_blank">Advertise here via BSA</a></p></p>
<h2>Winners Announced</h2>
<p>I was really happy to see so much participation in this giveaway! After seeing how many people entered, I was feeling really bad that only one of them would leave with a copy of the book. I talked to Cody, and he graciously provided two more free copies so we can award a total of three books! I randomly picked three winners (using <a href="http://random.org">Random.org</a>) and am happy to announce the following winners:</p>
<ul>
<li>Brad Rhine (<a href="http://truetech.org">truetech.org</a>)</li>
<li>Mila</li>
<li>Geoff Woodburn (<a href="http://woodburndesigns.com">woodburndesigns.com</a>)</li>
</ul>
<h2>Book Review</h2>
<p>Late in 2009, <a href="http://www.codylindley.com">Cody Lindley</a> published a PDF book on jQuery titled <a href="http://jqueryenlightenment.com">jQuery Enlightenment</a>. Today we are presenting our view of the book as well as offering a free copy to one lucky reader.</p>
<p><img class="alignnone size-full wp-image-792" title="jqueryen" src="http://fuelyourcoding.com/files/jqueryen.jpg" alt="jqueryen" width="600" height="300" /></p>
<h2>About The Author</h2>
<p>Cody Lindley is a core team member of the <a href="http://jquery.com">jQuery</a> project, and the original developer of the well known Thickbox plugin for jQuery. I had the pleasure of meeting and listening to Cody present at the jQuery Conference last year in Boston. He describes himself on his website:</p>
<blockquote><p>Today I am a Christian, husband, son, brother, professional Web developer, and outdoor enthusiast. I spend a majority of my time sleeping and working, but who doesn’t? In between the daily routines of the average American, I desire an existence that entails a relationship with God, my family, and nature. I would like to consider myself a bookworm (a novice theologian at best), but truth be told, I simply enjoy watching movies and playing xBox way too much. I guess I also have the luxury of pursuing my profession as a personal passion. Yes, I often work even when I am not at work.</p></blockquote>
<h2>Overview</h2>
<p>jQuery Enlightenment is a different type of book than I am used to seeing in the tech field. A list of what it is <em>not</em> might help shed light on what I mean. It is not documentation, a tutorial/walkthrough, or just conceptual material. jQuery Enlightenment is an amazingly clear montage of principals and code samples every jQuery developer needs to know grouped by topic. Cody covered topics both basic and profound throughout the pages of the book.</p>
<p>I consider myself quite adept at using jQuery, but found myself constantly amazed at the things I was learning while reading this book.  Cody says it picks up where the jQuery documentation leaves off. I can see his point, but I think this book would be a better starting place for a new jQuery developer than even reading through the jQuery API site.</p>
<h2>Pros</h2>
<h3>Code Samples</h3>
<p><img class="alignnone size-full wp-image-783" title="code" src="http://fuelyourcoding.com/files/code.jpg" alt="code" width="568" height="104" /></p>
<p>Code samples make up over 70% of the book (rough estimation). The book is not written in an editorial way at all. It is about presenting what you need to know, demonstrating it with an example, and moving on. For this reason the book is an extremely fast read and perfect for reference on a day to day basis.</p>
<p>Possibly one of the neatest features of the book itself is that (almost) every code sample provided in the book has a link to the same code on JSBin.com. JSBin is an online playground for testing and demonstrating JavaScript, HTML, and CSS technologies. jQuery Enlightenment isn&#8217;t a flat reading experience, it allows you to immediately jump in and play with the code samples until everything makes sense.</p>
<h3>Additional Notes</h3>
<p><img class="alignnone size-full wp-image-784" title="notes" src="http://fuelyourcoding.com/files/notes.jpg" alt="notes" width="568" height="104" /></p>
<p>Many of the topics are followed by a little box titled &#8216;Notes&#8217;. I am glad Cody didn&#8217;t choose some cheesy title for these boxes, but &#8216;Notes&#8217; really does not sum up what they provide. You will find many undocumented (or hard to find) tips and tricks about the finer points of jQuery in these boxes. Skip over them at your own peril!</p>
<h3>No Fluff Quality</h3>
<p>Cody doesn&#8217;t waste any time on any of the topics presented in the book. The pattern used is simple: explain, demonstrate, move on. I personally will be using this book not just for reference, but for a quick read-through every few weeks to keep my jQuery senses sharp.</p>
<h2>Cons</h2>
<p>You will be hard pressed to find something negative to say about this book, and it wasn&#8217;t until I reached the end that I had one complaint about the content. The chapter on Ajax (Chapter 11) was far too short. Perhaps this is because the documentation is very clear, but I still wanted to learn more and have more examples to glean from. Perhaps the second edition of the book (which will cover jQuery 1.4) will provide more detail on jQuery&#8217;s AJAX implementation and associated methods.</p>
<h2>Conclusion</h2>
<p>I am confident new users and seasoned users alike will find much to learn in jQuery Enlightenment. After reading the book, my only concern is that I won&#8217;t remember all of the cool things I learned while reading it!</p>
<h2>Win a FREE Copy!</h2>
<p>Next Wednesday we will be selecting a winner to receive a free copy of jQuery Enlightenment. Entering the competition is easy!</p>
<p>Head over to <a href="http://jqueryenlightenment.com">jQuery Enlightenment</a> and quickly look through table of contents. Then, leave a comment below telling us what chapter you think you would learn the most from if you were to win the book. Only comments referencing one of the actual chapters in the book will be eligible to win. <strike>We will randomly select a winner next Wednesday and announce it here on the site.</strike>. <strong>Sorry, but the contest is over!</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://fuelyourcoding.com/jquery-enlightenment-book-review-and-giveaway/feed/</wfw:commentRss>
		<slash:comments>43</slash:comments>
		</item>
	</channel>
</rss>

