<?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>Jeff Gran</title>
	<atom:link href="http://jeffgran.com/feed" rel="self" type="application/rss+xml" />
	<link>http://jeffgran.com</link>
	<description>Artist, Designer, Developer</description>
	<lastBuildDate>Wed, 09 Nov 2011 15:59:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Quick Tip: Bash Script for Running RSpec Tests Under Rails</title>
		<link>http://jeffgran.com/309/blog/quick-tip-bash-script-for-running-rspec-tests-under-rails</link>
		<comments>http://jeffgran.com/309/blog/quick-tip-bash-script-for-running-rspec-tests-under-rails#comments</comments>
		<pubDate>Tue, 11 Oct 2011 19:41:32 +0000</pubDate>
		<dc:creator>Jeff Gran</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://jeffgran.com/?p=309</guid>
		<description><![CDATA[This will be specific to our particular setup but could easily be adapted for other similar use cases. Basically, I got tired of typing: $ rake spec SPEC=spec/acceptance/path/to/file.rb SPEC_OPTS='--line 42' &#8230;in order to re-run a single test after attempting to fix it. The rspec output gives a stack trace that shows the file/line number the [...]]]></description>
			<content:encoded><![CDATA[<p>This will be specific to our particular setup but could easily be adapted for other similar use cases.</p>
<p>Basically, I got tired of typing:</p>
<pre>$ rake spec SPEC=spec/acceptance/path/to/file.rb SPEC_OPTS='--line 42'</pre>
<p>&#8230;in order to re-run a single test after attempting to fix it. The rspec output gives a stack trace that shows the file/line number the failure occured on, like this:</p>
<pre>./spec/acceptance/path/to/file.rb:42</pre>
<p>So I made a bash script that lets me just copy that line and then run </p>
<pre>$ test [pasted line]</pre>
<p> and it will run the test again. Here it is:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="color: #ccc;"><span style="color: #4080ff;">function</span> <span style="color: cyan;">test</span><span style="color: grey;">&#40;</span><span style="color: grey;">&#41;</span> <span style="color: grey;">&#123;</span>
   <span style="color: cyan;">local</span> <span style="color: #007800;">a1</span>=<span style="color: #ff8080;">&quot;$1&quot;</span>
   <span style="color: cyan;">local</span> <span style="color: #007800;">a2</span>=<span style="color: #ff8080;">&quot;$2&quot;</span>
   <span style="color: #4080ff;">if</span> <span style="color: grey;">&#91;</span><span style="color: grey;">&#91;</span> <span style="color: #007800;">$1</span> == <span style="color: grey;">*</span>:<span style="color: grey;">*</span> <span style="color: grey;">&#93;</span><span style="color: grey;">&#93;</span>; <span style="color: #4080ff;">then</span> <span style="color: #007800;">arr</span>=<span style="color: grey;">&#40;</span><span style="color: #80ff80">${1//:/ }</span><span style="color: grey;">&#41;</span>; <span style="color: #007800;">a1</span>=<span style="color: #ff8080;">&quot;<span style="color: #007800;">${arr[0]}</span>&quot;</span>; <span style="color: #007800;">a2</span>=<span style="color: #ff8080;">&quot;<span style="color: #007800;">${arr[1]}</span>&quot;</span>; <span style="color: #4080ff;">fi</span>;
   <span style="color: cyan;">local</span> <span style="color: #007800;">spec</span>=<span style="color: #ff8080;">&quot;<span style="color: #007800;">$a1</span>&quot;</span>
   <span style="color: #4080ff;">if</span> <span style="color: grey;">&#91;</span> <span style="color: #660033;">-n</span> <span style="color: #ff8080;">&quot;<span style="color: #007800;">$a2</span>&quot;</span> <span style="color: grey;">&#93;</span>; <span style="color: #4080ff;">then</span> <span style="color: cyan;">local</span> <span style="color: #007800;">opts</span>=<span style="color: #ff8080;">&quot;--line <span style="color: #007800;">${a2}</span>&quot;</span>; <span style="color: #4080ff;">fi</span>;
   <span style="color: #4080ff;">if</span> <span style="color: grey;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff8080;">&quot;<span style="color: #007800;">$opts</span>&quot;</span> <span style="color: grey;">&#93;</span>; <span style="color: #4080ff;">then</span>
     <span style="color: cyan;">echo</span> rake spec <span style="color: #007800;">SPEC</span>=<span style="color: #80ff80">${spec}</span>
     bundle <span style="color: cyan;">exec</span> rake spec <span style="color: #007800;">SPEC</span>=<span style="color: #80ff80">${spec}</span>
   <span style="color: #4080ff;">else</span>
     <span style="color: cyan;">echo</span> rake spec <span style="color: #007800;">SPEC</span>=<span style="color: #80ff80">${spec}</span> <span style="color: #007800;">SPEC_OPTS</span>=<span style="color: #ff8080;">&quot;<span style="color: #007800;">${opts}</span>&quot;</span>
     bundle <span style="color: cyan;">exec</span> rake spec <span style="color: #007800;">SPEC</span>=<span style="color: #80ff80">${spec}</span> <span style="color: #007800;">SPEC_OPTS</span>=<span style="color: #ff8080;">&quot;<span style="color: #007800;">${opts}</span>&quot;</span>
   <span style="color: #4080ff;">fi</span>
 <span style="color: grey;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://jeffgran.com/309/blog/quick-tip-bash-script-for-running-rspec-tests-under-rails/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bootstrapping an Ubuntu Server on Rackspace Using Cloud-Init and Fog</title>
		<link>http://jeffgran.com/276/blog/ubuntu-cloud-init-rackspace-fog-ruby</link>
		<comments>http://jeffgran.com/276/blog/ubuntu-cloud-init-rackspace-fog-ruby#comments</comments>
		<pubDate>Fri, 19 Aug 2011 19:11:26 +0000</pubDate>
		<dc:creator>Jeff Gran</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://jeffgran.com/?p=276</guid>
		<description><![CDATA[Recently at work I needed to figure out how to bootstrap a server image on Rackspace, preferably using Ubuntu&#8217;s Cloud-Init package since we already had that working on EC2. I couldn&#8217;t find a single person who had done this before, so after struggling for a day or two and finally figuring out that it does [...]]]></description>
			<content:encoded><![CDATA[<p>Recently at work I needed to figure out how to bootstrap a server image on Rackspace, preferably using Ubuntu&#8217;s Cloud-Init package since we already had that working on EC2.</p>
<p>I couldn&#8217;t find a single person who had done this before, so after struggling for a day or two and finally figuring out that it does indeed work (and it turns out to be pretty simple) I thought I would share the knowledge on how to do it.</p>
<h3>Set up the Machine Image</h3>
<p>EC2 has ready-made Ubuntu images with Cloud-Init already installed, but for Rackspace the first thing you need to do is create a similar image. All we did was to get a stock Ubuntu image (11.04) and run `apt-get install cloud-init` on it.</p>
<p>That&#8217;s it. Then just save out that image to your account.</p>
<h3>Bootstrap the Image with Fog</h3>
<p>Note: We&#8217;re using Ruby, so we can use the awesome <a href="https://github.com/geemus/fog" target="_blank">Fog gem</a> as a wrapper around the <a href="http://docs.rackspace.com/servers/api/v1.0/cs-devguide/content/Create_Server-d1e1937.html" target="_blank">Rackspace REST API</a>, but you could also accomplish the same thing with the raw API.</p>
<p>A couple of notes, and then I&#8217;ll show the code:</p>
<ul>
<li>We are generating an SSH key-pair to initialize the server with. This is not strictly required, but if you don&#8217;t do this, you must save the password attribute of the returned server object on the initial create call. Subsequent queries against the server will not return the password for security reasons.</li>
</ul>
<ul>
<li>The &#8220;Personality&#8221; field is the crux of this process. It allows you to send up to 5 files to be put on the server in a location of your choosing at boot time. It turns out that this can be used to &#8220;seed&#8221; cloud-init with the files it needs, mimicking the &#8220;user-data&#8221; field you would pass to EC2. Note that the path to the file you supply does not have to exist on the image. Rackspace will create the directories for you if they don&#8217;t.</li>
</ul>
<ul>
<li>The path where you put the files is also important. In the code below the `/nocloud-net/` part of the path can be interchanged with a few others, though I&#8217;m not sure what some of them mean. Don&#8217;t quote me on this, but I believe that `/nocloud/` is supposed to mean that you&#8217;re not in the cloud, and `/nocloud-net/` is the same, except that you are guaranteed that you will have a connection to the internet when it runs (a little bit later in the boot process than `nocloud`). But we can hijack either one for our use in seeding cloud-init.</li>
</ul>
<ul>
<li>Very important: you must supply BOTH the &#8220;user-data&#8221; and the &#8220;meta-data&#8221; files in order for cloud-init to run. In EC2, <a href="http://bazaar.launchpad.net/~cloud-init-dev/cloud-init/trunk/view/head:/doc/examples/seed/meta-data">the meta-data file</a> has a bunch of EC2-specific data in it (and some generic data, to be fair), but I found that we didn&#8217;t need any of that data and the defaults worked fine. But you still have to create that file, and an empty string doesn&#8217;t work (the file doesn&#8217;t get created), which is why we have specified a single space for the contents of the file.</li>
</ul>
<ul>
<li>The `user-data` file can be any type of file that cloud-init normally expects, including the multi-part format, so you can include multiple files that way. The code below shows how we compiled some files from the local file system into a multipart document (each with the appropriate `#` or `#!` header). See the <a href="https://help.ubuntu.com/community/CloudInit" target="_blank">cloud-init documentation</a> for more info.</li>
</ul>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="color: #ccc;"><span style="color: #80ff80"># get a handle to the fog compute abstraction</span>
compute_adapter = <span style="color:#6666ff; font-weight:bold;">Fog::Compute</span>.<span style="color: magenta;">new</span><span style="color: grey;">&#40;</span><span style="color: grey;">&#123;</span>
  provider: <span style="color: #ff8080;">&quot;Rackspace&quot;</span>,
  rackspace_api_key: <span style="color: #ff8080;">&quot;&quot;</span>,
  rackspace_username: <span style="color: #ff8080;">&quot;&quot;</span>
<span style="color: grey;">&#125;</span><span style="color: grey;">&#41;</span>
&nbsp;
<span style="color: #80ff80"># generate the ssh key-pair</span>
keys = SSHKey.<span style="color: magenta;">generate</span>
&nbsp;
<span style="color: #80ff80"># let's make a multi-part document</span>
scripts = <span style="color:#6666ff; font-weight:bold;">MIME::MultipartMedia::Mixed</span>.<span style="color: magenta;">new</span>
&nbsp;
<span style="color: #80ff80"># assuming `files` is an array of File objects corresponding</span>
<span style="color: #80ff80"># to real, properly formatted cloud-init script files</span>
files.<span style="color: magenta;">each</span> <span style="color: #4080ff;">do</span> <span style="color: grey;">|</span>f<span style="color: grey;">|</span> <span style="color: #4080ff;">do</span>
  scripts.<span style="color: magenta;">add_entity</span><span style="color: grey;">&#40;</span><span style="color:#6666ff; font-weight:bold;">MIME::TextMedia</span>.<span style="color: magenta;">new</span><span style="color: grey;">&#40;</span>file, <span style="color: #ff8080;">&quot;text/plain&quot;</span><span style="color: grey;">&#41;</span><span style="color: grey;">&#41;</span>
<span style="color: #4080ff;">end</span>
&nbsp;
compute_adapter.<span style="color: magenta;">servers</span>.<span style="color: magenta;">bootstrap</span><span style="color: grey;">&#40;</span><span style="color: grey;">&#123;</span>
  image_id: <span style="color:#006666;">39</span>,
  flavor_id: <span style="color:#006666;">1</span>,
  name: <span style="color: #ff8080;">&quot;A Name for the Server&quot;</span>,
  personality: <span style="color: grey;">&#91;</span>
    <span style="color: grey;">&#123;</span>
      <span style="color: #ff8080;">'path'</span> <span style="color: grey;">=&gt;</span> <span style="color: #ff8080;">'/var/lib/cloud/seed/nocloud-net/user-data'</span>,
      <span style="color: #ff8080;">'contents'</span> <span style="color: grey;">=&gt;</span> scripts.<span style="color: magenta;">to_s</span>
    <span style="color: grey;">&#125;</span>,<span style="color: grey;">&#123;</span>
      <span style="color: #ff8080;">'path'</span> <span style="color: grey;">=&gt;</span> <span style="color: #ff8080;">'/var/lib/cloud/seed/nocloud-net/meta-data'</span>,
      <span style="color: #ff8080;">'contents'</span> <span style="color: grey;">=&gt;</span> <span style="color: #ff8080;">' '</span>
    <span style="color: grey;">&#125;</span>
  <span style="color: grey;">&#93;</span>,
  public_key: keys.<span style="color: magenta;">ssh_public_key</span>,
  private_key: keys.<span style="color: magenta;">private_key</span>
<span style="color: grey;">&#41;</span></pre></div></div>

<p>Helpful links:</p>
<ul>
<li><a href="https://code.launchpad.net/~cloud-init-dev/cloud-init/trunk">Cloud-init project with source code browser (including example files)</a></li>
<li><a href="http://fog.io/0.10.0/rdoc/Fog/Compute/Rackspace/Server.html" target="_blank">Fog Documentation</a></li>
<li><a href="https://github.com/bensie/sshkey" target="_blank">sshkey gem used to generate the proper type of keys</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://jeffgran.com/276/blog/ubuntu-cloud-init-rackspace-fog-ruby/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>WordPress: Sort Posts by Multiple Fields (Part II)</title>
		<link>http://jeffgran.com/262/blog/wordpress-sort-posts-by-multiple-fields-part-ii</link>
		<comments>http://jeffgran.com/262/blog/wordpress-sort-posts-by-multiple-fields-part-ii#comments</comments>
		<pubDate>Sun, 17 Jul 2011 23:17:39 +0000</pubDate>
		<dc:creator>Jeff Gran</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://jeffgran.com/?p=262</guid>
		<description><![CDATA[Here's a fast and easy way to sort your posts by multiple fields, using the posts_orderby filter hook and a simple function.]]></description>
			<content:encoded><![CDATA[<h3>The Sequel!</h3>
<p>Because my previous post (<a href="http://jeffgran.com/218/blog/wordpress-sort-posts-by-multiple-fields" title="WordPress: Sort Posts by Multiple Fields">WordPress: Sort Posts by Multiple Fields</a>) was one of my most popular posts, and because I have realized since then that the solution it proposes is an inadequate one, I felt the need to write an update.  I don&#8217;t want to be spreading bad information, and for a blog with any significant number of posts, that solution is untenable.</p>
<p>As <a href="http://jeffgran.com/218/blog/wordpress-sort-posts-by-multiple-fields#comment-254" title="WordPress: Sort Posts by Multiple Fields">progzy</a> points out, sorting by multiple fields can be accomplished using the `posts_orderby` filter hook, which uses MySQL directly to sort the posts, instead of getting all the posts from the database into a gigantic array, and then sorting them with php code. Here&#8217;s how to do it.</p>
<h3>Writing an orderby Function</h3>
<p>You&#8217;ll need to write a function that returns a SQL fragment represented as a string, and then connect it to the filter hook. The SQL fragment is the `ORDER BY` segment of the SQL query that gets your posts from the database. See <a href="http://dev.mysql.com/doc/refman/5.0/en/sorting-rows.html">the MySQL Documentation on sorting</a> for more info on this.</p>
<p>Here&#8217;s an example of a custom sorting function:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="color: #ccc;"><span style="color: #ffff00;">function</span> order_by_multiple<span style="color: grey;">&#40;</span> <span style="color: #ffc080;">$orderby</span><span style="color: grey;">&#41;</span> <span style="color: grey;">&#123;</span>
  <span style="color: #4080ff;">return</span> <span style="color: #ff8080;">&quot;post_date ASC, post_title DESC&quot;</span><span style="color: grey;">;</span>
<span style="color: grey;">&#125;</span></pre></div></div>

<p>The above would sort the posts by date in ascending order first, and secondarily by title in descending (reverse) order. </p>
<h3>Only Sort on a certain page</h3>
<p>You can also make this much more complex, if you want to. One important way is by using the different &#8220;<a href="http://codex.wordpress.org/Conditional_Tags">Conditional Tags</a>&#8221; WordPress provides. Here&#8217;s an example that only applies the custom sort on the home page:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="color: #ccc;"><span style="color: #ffff00;">function</span> order_by_multiple<span style="color: grey;">&#40;</span> <span style="color: #ffc080;">$orderby</span><span style="color: grey;">&#41;</span> <span style="color: grey;">&#123;</span>
  <span style="color: #4080ff;">if</span> <span style="color: grey;">&#40;</span><span style="color: grey;">!</span>is_home<span style="color: grey;">&#40;</span><span style="color: grey;">&#41;</span><span style="color: grey;">&#41;</span> <span style="color: grey;">&#123;</span>
    <span style="color: #4080ff;">return</span> <span style="color: #ff8080;">&quot;post_date ASC, post_title DESC&quot;</span><span style="color: grey;">;</span>
  <span style="color: grey;">&#125;</span>
<span style="color: grey;">&#125;</span></pre></div></div>

<h3>Hook up the sort function</h3>
<p>Then, once you have your ordering function written, you just need to hook it into the WordPress code like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="color: #ccc;">add_filter<span style="color: grey;">&#40;</span><span style="color: #ff8080;">&quot;posts_orderby&quot;</span><span style="color: grey;">,</span> <span style="color: #ff8080;">&quot;order_by_multiple&quot;</span><span style="color: grey;">&#41;</span><span style="color: grey;">;</span></pre></div></div>

<p>Make the second string argument there match your function name, of course (it doesn&#8217;t have to be the same name as mine, it can be anything). And you can have more than one function hook into the same hook. They will be executed in the same order they are added. In that case, the `$orderby` argument that&#8217;s coming into the function is the existing SQL fragment. So you could add to it, remove something from it, etc.</p>
<h3>Use Debug Query to help figure out what to return</h3>
<p>So the question is, how do you know what to put in your SQL fragment string? If you know your SQL well, you might be able to figure it out by intuition/trial-and-error. For the rest of us, there is a very helpful WordPress Plugin called <a href="http://wordpress.org/extend/plugins/debug-queries/">Debug Queries</a> which will print out all of the MySQL queries that are run for every page you visit (only for logged-in admins, of course. It&#8217;s just a debugging tool for use while developing).</p>
<p>If you install it, it will print out many queries per page. You have to look for the one that&#8217;s querying for posts. In my testing, mine looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="color: #ccc;"><span style="color: #4080ff;">SELECT</span> SQL_CALC_FOUND_ROWS wp_posts<span style="color: grey;">.*</span> <span style="color: #4080ff;">FROM</span> wp_posts <span style="color: grey;">&#40;</span><span style="color: grey;">...</span><span style="color: grey;">&#41;</span></pre></div></div>

<p>The important part is the `FROM wp_posts`. That means you&#8217;re selecting rows from the posts table. So if you have plugins or metadata that you&#8217;re selecting on, you will see them in that query, and it may help you figure out what incantation you need to put in that `orderby` string.</p>
<p>If you need to sort by category, tag, custom meta-data, etc. as one of your sort values, you may need to alter your MySQL query even more, perhaps <a href="http://codex.wordpress.org/Custom_Queries">using other hooks</a> (very similar to the `posts_orderby` hook), such as `posts_join`, `posts_where`, etc. Each of these modify different parts of the query.</p>
<p>Beyond that, if you still need help figuring out how to get the exact set of posts in the right order, you may need to read up on MySQL in general and learn how to manipulate the queries in more detail. Good Luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffgran.com/262/blog/wordpress-sort-posts-by-multiple-fields-part-ii/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>University of Denver</title>
		<link>http://jeffgran.com/247/blog/university-of-denver</link>
		<comments>http://jeffgran.com/247/blog/university-of-denver#comments</comments>
		<pubDate>Wed, 16 Sep 2009 05:24:21 +0000</pubDate>
		<dc:creator>Jeff Gran</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[announcement]]></category>

		<guid isPermaLink="false">http://jeffgran.com/?p=247</guid>
		<description><![CDATA[Yesterday was my first day of classes at the University of Denver. I&#8217;m entering into the Information and Communications Technology program. I&#8217;m excited to start learning, and it&#8217;s interesting (and validating my decision) that I&#8217;m already learning things that I never even knew I needed to know. Next quarter will be more about specific techniques [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-thumbnail wp-image-248" title="DU Logo" src="http://jeffgran.com/img/du_logo-180x180.gif" alt="DU Logo" width="180" height="180" />Yesterday was my first day of classes at the University of Denver.  I&#8217;m entering into the Information and Communications Technology program.  I&#8217;m excited to start learning, and it&#8217;s interesting (and validating my decision) that I&#8217;m already learning things that I never even knew I needed to know.</p>
<p>Next quarter will be more about specific techniques (javascript, for example), but so far this quarter is focused on things like the Software Development Life Cycle, Requirements and Use Case gathering, object oriented analysis and design, etc.</p>
<p>Someone wise once said that any newcomer into any field or discipline will always want to learn the fancy tricks and techniques first, when what they really need to start with are the fundamentals.  So, here&#8217;s to fundamentals.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffgran.com/247/blog/university-of-denver/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Web Experiments #1: Ajax Convo</title>
		<link>http://jeffgran.com/239/blog/web-experiments-1-ajax-convo</link>
		<comments>http://jeffgran.com/239/blog/web-experiments-1-ajax-convo#comments</comments>
		<pubDate>Sat, 05 Sep 2009 03:02:05 +0000</pubDate>
		<dc:creator>Jeff Gran</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Web Experiments]]></category>

		<guid isPermaLink="false">http://jeffgran.com/?p=239</guid>
		<description><![CDATA[1) I&#8217;m learning object-oriented design, design patterns, object-oriented PHP, and object-oriented JavaScript right now. I wanted to do some experimenting with building systems using these concepts, so I came up with the idea of doing a series of &#8220;Web Experiments&#8221; where I take an idea for some kind of web application and make a demo [...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-full wp-image-243 alignleft" title="ac" src="http://jeffgran.com/img/ac.jpg" alt="Ajax Convo" width="200" height="200" /></p>
<p>1) I&#8217;m learning object-oriented design, design patterns, object-oriented PHP, and object-oriented JavaScript right now.  I wanted to do some experimenting with building systems using these concepts, so I came up with the idea of doing a series of &#8220;Web Experiments&#8221; where I take an idea for some kind of web application and make a demo of it, for fun and learning.</p>
<p>2) I think ajax is the future of the web.  Somebody somewhere wrote &#8220;full page refreshes are so last year&#8221;, or something to that effect.  I sometimes find myself clicking a link or a tab somewhere out there on the web, mentally crossing my fingers in hopes that it won&#8217;t send me to a new page.  I think more and more people are going to expect slicker interfaces in web sites and web applications, and ajax is the way to get that accomplished.</p>
<p>3) I really like the comment/reply interface on Facebook.  There&#8217;s a series of boxes, each with a comment, and the last box is minimized and says &#8220;Write a comment&#8230;&#8221;.  When you click on it, it expands to look exactly like the other comments, with your picture there, just like it will look once it&#8217;s posted.  You type your brilliant quip, and when you click the button, the comment &#8220;melts&#8221; right into the page, and the next would-be comment appears below..  I think it&#8217;s lovely.</p>
<p>With these three things in mind, I started building my own little &#8220;comment thread&#8221; app. </p>
<p>Features:</p>
<ul>
<li>Add, edit, and remove comments from the &#8220;thread&#8221;.</li>
<li>No page refreshes &#8211; all done with ajax (jQuery)</li>
<li>Comments are stored in a tab-separated text file.</li>
<li>Shift-enter for a line break within a comment.</li>
</ul>
<p>I&#8217;ve also built a class structure that I believe will help me expand the project going forward.  The planned additions/expansions are:</p>
<ul>
<li>MySQL Database support (will be able to switch between text file and MySQL with a single setting)</li>
<li>Rewrite the JavaScript without using jQuery just for fun and practice, and to prove that I can.</li>
<li>Multiple &#8220;threads&#8221; of comments</li>
<li>Only load the latest 10 comments or so, and load more twitter-style.</li>
<li>More to each message, like time/date of post, &#8220;last edited at&#8230;&#8221;, etc.</li>
<li>Maybe a simple user system. I loathe to make people &#8220;sign up&#8221; for things though.</li>
</ul>
<p>If you&#8217;re interested, you can download the files <a title="Ajax Convo Zip File" href="http://jeffgran.com/stuff/ac.zip">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffgran.com/239/blog/web-experiments-1-ajax-convo/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Book Review: PHP Solutions</title>
		<link>http://jeffgran.com/230/blog/book-review-php-solutions</link>
		<comments>http://jeffgran.com/230/blog/book-review-php-solutions#comments</comments>
		<pubDate>Tue, 01 Sep 2009 00:54:20 +0000</pubDate>
		<dc:creator>Jeff Gran</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[book review]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://jeffgran.com/?p=230</guid>
		<description><![CDATA[In my quest to expand my knowledge of the web industry, I knew I needed to understand more PHP.  PHP is one of the (if not the) most popular languages used on the web today.  I had been exposed to it a little, and I have experience with other C-ish syntax languages, but I needed [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-231" title="php_solutions" src="http://jeffgran.com/img/php_solutions.jpg" alt="PHP Solutions: Dynamic Web Design Made Easy" width="200" height="240" />In my quest to expand my knowledge of the web industry, I knew I needed to understand more PHP.  PHP is one of the (if not <em>the</em>) most popular languages used on the web today.  I had been exposed to it a little, and I have experience with other C-ish syntax languages, but I needed to brush up on the fundamentals and the unique qualities of PHP.</p>
<p>I chose <em>PHP Solutions: Dynamic Web Design Made Easy</em> because I wanted to have some real-world projects to play with as I learned the language, as opposed to just the dry information.  The book delivered in that respect.  As per the name, the book focuses on specific needs and solutions for those needs using PHP and MySQL.  I got to see how PHP works with forms and databases, and how these techniques could be applied in a simple database-driven blog, for example.</p>
<p>However, probably the most useful part of the book for me were the tutorials on getting the Apache server, PHP and MySQL running on my local machine so that I could just jump into a code editor and start playing around.  I actually ended up skipping to these two chapters (one for Apache/PHP and one for MySQL) and then put the book down for a month or so before I picked it back up and finished reading it.</p>
<p>I started out by following along with the solutions and the code samples, typing them in and trying it out as I was reading, but soon realized that this was unnecessary.  I finished reading the better part of the book by simply reading and understand the code examples.  Whether this is a good thing or bad is up for debate.  It means the writing was clear, but also that the content was less challenging.</p>
<p>Besides the setup chapters mentioned above, the other most useful takeaway I had from this book was all the little things about the language that I mentioned above.  Things like &#8220;the truth according to PHP&#8221; (&#8220;false&#8221; evaluates to true because of type coercion), how the $_POST and $_GET superglobal arrays work, and other little things that really help put it all together in my head.</p>
<p>Another very useful aspect to the way the solutions in the book are constructed is the focus on security and thoroughness.  Some books leave out details, only hinting at it with phrases like &#8220;in a real application, we&#8217;d check this or that&#8221;, but in this book we are treated to some very useful (and usually very simple) techniques to make sure the code we&#8217;re building is secure and bulletproof.</p>
<p>All in all, I&#8217;m glad I now have the information I gained from this book, but I&#8217;m not sure it was exactly what I was looking for.  As with other introductory-level books, I found myself a bit annoyed by the &#8220;if that last part made your head explode, don&#8217;t worry, just copy the code and know that it works&#8221; -type attitude.  My head didn&#8217;t explode &#8211; on the contrary, that was one part where my brain actually felt that tingle of a concept falling into place.  Most of the book was spent thinking to myself, &#8220;yeah, I get it.  OK.  What&#8217;s next?&#8221;  I think I would recommend this book to others, but only if you&#8217;re newer to programming in general, and have very little or no PHP experience.  For me, with quite a bit of general programming, and some hands-on PHP experience from working with WordPress themes, it just felt a little bit too slow, but it did fill in some crucial gaps in my knowledge.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffgran.com/230/blog/book-review-php-solutions/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPress: Sort Posts by Multiple Fields</title>
		<link>http://jeffgran.com/218/blog/wordpress-sort-posts-by-multiple-fields</link>
		<comments>http://jeffgran.com/218/blog/wordpress-sort-posts-by-multiple-fields#comments</comments>
		<pubDate>Tue, 21 Jul 2009 21:05:16 +0000</pubDate>
		<dc:creator>Jeff Gran</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://jeffgran.com/?p=218</guid>
		<description><![CDATA[UPDATE: I have written a new post about how to better accomplish this task: WordPress: Sort Posts by Multiple Fields (Part II) Please see the above link for a much more efficient way to sort by multiple fields. I was recently creating a star-rating system for a client, and we were sorting the reviews (or [...]]]></description>
			<content:encoded><![CDATA[<h3>UPDATE: I have written a new post about how to better accomplish this task: <a href="http://jeffgran.com/262/blog/wordpress-sort-posts-by-multiple-fields-part-ii">WordPress: Sort Posts by Multiple Fields (Part II)</a></h3>
<p>Please see the above link for a much more efficient way to sort by multiple fields.</p>
<p>I was recently creating a star-rating system for a client, and we were sorting the reviews (or &#8220;posts&#8221;) by the number of stars.  The problem that came up was that with a 5 star system, and increments of half-stars, you will necessarily end up with many of the ratings being equal.  We wanted to be able to control the exact order the reviews were shown in the case of a tie.  Here&#8217;s how I did it.</p>
<h3>Adding a &#8220;Priority&#8221; Custom Field</h3>
<p>The first step was to add a custom field called &#8220;priority&#8221;, which would act as the tie-breaker.  Basically, if two posts have the same star rating, we&#8217;ll check the priority and see which one is higher, and that one will be displayed first.  I was using the <a title="Flutter WordPress Plugin Homepage" href="http://flutter.freshout.us/" target="_blank">Flutter plugin</a>, so adding another custom field was as simple as clicking a few buttons in the admin panel.</p>
<h3>Custom Query</h3>
<p>Sorting by a single field is relatively easy.  You would create a custom query for the posts by using something like this (to sort alphabetically):</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="color: #ccc;">query_posts<span style="color: grey;">&#40;</span><span style="color: #ff8080;">&quot;orderby=title&amp;order=ASC&quot;</span><span style="color: grey;">&#41;</span><span style="color: grey;">;</span></pre></div></div>

<p>Using Flutter&#8217;s syntax for sorting by its custom fields, we&#8217;d use:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="color: #ccc;">query_posts<span style="color: grey;">&#40;</span><span style="color: #ff8080;">&quot;customorderby=x_stars-overall-rating&amp;order=DESC&quot;</span><span style="color: grey;">&#41;</span><span style="color: grey;">;</span></pre></div></div>

<h3>Refining the Order with usort()</h3>
<p>But you can&#8217;t sort by more than one field using the above methods.  That&#8217;s where usort comes in.  PHP has <a title="PHP Manual: usort" href="http://us2.php.net/manual/en/function.usort.php" target="_blank">a function called usort()</a> which sorts an array based on a custom function which &#8220;compares&#8221; the two array items in any way you like.  So all we need to do is run our array of posts through a function which does the more complex comparison using both the &#8220;stars&#8221; field and then the &#8220;priority&#8221; field for tie-breakers.</p>
<p>First, we insert this in the category listing page (or whichever page you&#8217;re working on) to run the custom sort function:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="color: #ccc;"><span style="color: cyan;">usort</span><span style="color: grey;">&#40;</span><span style="color: #ffc080;">$wp_query</span><span style="color: grey;">-&gt;</span><span style="color: magenta;">posts</span><span style="color: grey;">,</span> <span style="color: #0000ff;">'review_tie_breaker'</span><span style="color: grey;">&#41;</span><span style="color: grey;">;</span></pre></div></div>

<p>The first argument in the function is the array of posts created by the default query in WordPress.  The second argument is the name of our custom sort function, which is shown below:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td><td class="code"><pre class="php" style="color: #ccc;"><span style="color: #ffff00;">function</span> review_tie_breaker<span style="color: grey;">&#40;</span><span style="color: #ffc080;">$a</span><span style="color: grey;">,</span> <span style="color: #ffc080;">$b</span><span style="color: grey;">&#41;</span> <span style="color: grey;">&#123;</span>
   <span style="color: #80ff80">// get the star value for each </span>
   <span style="color: #ffc080;">$a_stars</span> <span style="color: grey;">=</span> get_post_meta<span style="color: grey;">&#40;</span><span style="color: #ffc080;">$a</span><span style="color: grey;">-&gt;</span><span style="color: magenta;">ID</span><span style="color: grey;">,</span> <span style="color: #0000ff;">'stars-overall-rating'</span><span style="color: grey;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: grey;">&#41;</span><span style="color: grey;">;</span>
   <span style="color: #ffc080;">$b_stars</span> <span style="color: grey;">=</span> get_post_meta<span style="color: grey;">&#40;</span><span style="color: #ffc080;">$b</span><span style="color: grey;">-&gt;</span><span style="color: magenta;">ID</span><span style="color: grey;">,</span> <span style="color: #0000ff;">'stars-overall-rating'</span><span style="color: grey;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: grey;">&#41;</span><span style="color: grey;">;</span>
   <span style="color: #80ff80">// if it's not a tie, return which has more stars</span>
   <span style="color: #4080ff;">if</span> <span style="color: grey;">&#40;</span><span style="color: #ffc080;">$a_stars</span> <span style="color: grey;">!=</span> <span style="color: #ffc080;">$b_stars</span><span style="color: grey;">&#41;</span> <span style="color: grey;">&#123;</span>
      <span style="color: #4080ff;">return</span> <span style="color: grey;">&#40;</span><span style="color: grey;">&#40;</span>float<span style="color: grey;">&#41;</span><span style="color: #ffc080;">$a_stars</span> <span style="color: grey;">&gt;</span> <span style="color: grey;">&#40;</span>float<span style="color: grey;">&#41;</span><span style="color: #ffc080;">$b_stars</span><span style="color: grey;">&#41;</span> ? <span style="color: grey;">-</span><span style="color: #cc66cc;">1</span> <span style="color: grey;">:</span> <span style="color: #cc66cc;">1</span><span style="color: grey;">;</span>
   <span style="color: grey;">&#125;</span>
   <span style="color: #80ff80">// else, if they are tied, go to the priority tiebreaker...</span>
&nbsp;
   <span style="color: #80ff80">// get the priority value for each</span>
   <span style="color: #ffc080;">$a_priority</span> <span style="color: grey;">=</span> get_post_meta<span style="color: grey;">&#40;</span><span style="color: #ffc080;">$a</span><span style="color: grey;">-&gt;</span><span style="color: magenta;">ID</span><span style="color: grey;">,</span> <span style="color: #0000ff;">'rating-priority'</span><span style="color: grey;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: grey;">&#41;</span><span style="color: grey;">;</span>
   <span style="color: #ffc080;">$b_priority</span> <span style="color: grey;">=</span> get_post_meta<span style="color: grey;">&#40;</span><span style="color: #ffc080;">$b</span><span style="color: grey;">-&gt;</span><span style="color: magenta;">ID</span><span style="color: grey;">,</span> <span style="color: #0000ff;">'rating-priority'</span><span style="color: grey;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: grey;">&#41;</span><span style="color: grey;">;</span>
&nbsp;
   <span style="color: #80ff80">// if a priority value has not been entered, default to 0</span>
   <span style="color: #ffc080;">$a_priority</span> <span style="color: grey;">=</span> <span style="color: grey;">&#40;</span><span style="color: #ffc080;">$a_priority</span> <span style="color: grey;">==</span> <span style="color: #0000ff;">''</span><span style="color: grey;">&#41;</span> ? <span style="color: #cc66cc;">0</span> <span style="color: grey;">:</span> <span style="color: grey;">&#40;</span>int<span style="color: grey;">&#41;</span><span style="color: #ffc080;">$a_priority</span><span style="color: grey;">;</span>
   <span style="color: #ffc080;">$b_priority</span> <span style="color: grey;">=</span> <span style="color: grey;">&#40;</span><span style="color: #ffc080;">$b_priority</span> <span style="color: grey;">==</span> <span style="color: #0000ff;">''</span><span style="color: grey;">&#41;</span> ? <span style="color: #cc66cc;">0</span> <span style="color: grey;">:</span> <span style="color: grey;">&#40;</span>int<span style="color: grey;">&#41;</span><span style="color: #ffc080;">$b_priority</span><span style="color: grey;">;</span>
&nbsp;
   <span style="color: #80ff80">// if the priority is also equal, just return as a tie</span>
   <span style="color: #4080ff;">if</span> <span style="color: grey;">&#40;</span><span style="color: #ffc080;">$a_priority</span> <span style="color: grey;">==</span> <span style="color: #ffc080;">$b_priority</span><span style="color: grey;">&#41;</span> <span style="color: grey;">&#123;</span>
      <span style="color: #4080ff;">return</span> <span style="color: #cc66cc;">0</span><span style="color: grey;">;</span>
   <span style="color: grey;">&#125;</span>
   <span style="color: #80ff80">// if not, we return the priority comparison</span>
   <span style="color: #4080ff;">return</span> <span style="color: grey;">&#40;</span><span style="color: #ffc080;">$a_priority</span> <span style="color: grey;">&lt;</span> <span style="color: #ffc080;">$b_priority</span><span style="color: grey;">&#41;</span> ? <span style="color: grey;">-</span><span style="color: #cc66cc;">1</span> <span style="color: grey;">:</span> <span style="color: #cc66cc;">1</span><span style="color: grey;">;</span>
<span style="color: grey;">&#125;</span></pre></td></tr></table></div>

<h3>How the Tie-Breaker Function Works</h3>
<p>The way the custom sort function works is by comparing two elements of the array ($a and $b, above), and deciding which one is &#8220;greater than&#8221; the other.  If $a is greater than $b, we should return a value of 1.  If the opposite is true, we return -1.  If they are tied, we return 0.  The above function uses ternary operators to compare first the star ratings and then the priority values.  If the stars are not tied, it just returns which has the higher star rating, and never gets to the tie-breaker phase.  But if they are equal, we then compare the second criteria.</p>
<p>There is also a check to make sure the &#8220;priority&#8221; field has a value.  This is so that the user is not forced to input a value for every single review, just the ones that need to be tweaked.  Using this system, all that is required to bump a review up above another review with an equal star-rating is to insert a &#8220;-1&#8243; in the priority box.</p>
<p>I used this for a star rating system, but it could be used for any number of applications.  For example, if you wanted to order your posts by author, but for each author make sure they are in chronological order.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffgran.com/218/blog/wordpress-sort-posts-by-multiple-fields/feed</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>WordPress: Tabbed Sidebar Widgets with jQuery</title>
		<link>http://jeffgran.com/180/blog/wordpress-tabbed-sidebar-widgets-with-jquery</link>
		<comments>http://jeffgran.com/180/blog/wordpress-tabbed-sidebar-widgets-with-jquery#comments</comments>
		<pubDate>Wed, 01 Jul 2009 22:33:13 +0000</pubDate>
		<dc:creator>Jeff Gran</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://jeffgran.com/?p=180</guid>
		<description><![CDATA[Tabs are a great way to show more information in less space, assuming the initially-hidden tabs are non-essential information.  Recently a client asked me to put a few Wordpress widgets into a single tabbed container in the sidebar.  Here's how I did it.]]></description>
			<content:encoded><![CDATA[<p>Tabs are a great way to show more information in less space, assuming the initially-hidden tabs are non-essential information.  Recently a client asked me to put a few WordPress widgets into a single tabbed container in the sidebar.  Here&#8217;s how I did it.</p>
<h3>The Problem</h3>
<p>There&#8217;s no reason to re-invent the wheel, and there are already several tabs implementations written as jQuery plugins, including the <a title="jQuery UI Tabs" href="http://jqueryui.com/demos/tabs/">jQuery UI tabs widget</a>. The problem with these is that most (if not all) of them require the markup to be set up in a different way than we have available with our WordPress-outputted sidebar markup.</p>
<p>To illustrate, WordPress by default outputs the sidebar with markup that is structured something like this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="html4strict" style="color: #ccc;"><span style="color: #009900;">&lt;<span style="color: #ffff00;">div</span> <span style="color: cyan;">id</span><span style="color: grey;">=</span><span style="color: #ff8080;">&quot;sidebar-1&quot;</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #ffff00;">ul</span> <span style="color: cyan;">class</span><span style="color: grey;">=</span><span style="color: #ff8080;">&quot;sidebar-list&quot;</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #ffff00;">li</span> <span style="color: cyan;">id</span><span style="color: grey;">=</span><span style="color: #ff8080;">&quot;widget-1&quot;</span> <span style="color: cyan;">class</span><span style="color: grey;">=</span><span style="color: #ff8080;">&quot;widget widget-class-1&quot;</span>&gt;</span>
      <span style="color: #009900;">&lt;<span style="color: #ffff00;">h2</span>&gt;</span>Widget 1 Title<span style="color: #009900;">&lt;<span style="color: grey;">/</span><span style="color: #ffff00;">h2</span>&gt;</span>
      <span style="color: #009900;">&lt;<span style="color: #ffff00;">p</span>&gt;</span>...content...<span style="color: #009900;">&lt;<span style="color: grey;">/</span><span style="color: #ffff00;">p</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: grey;">/</span><span style="color: #ffff00;">li</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #ffff00;">li</span> <span style="color: cyan;">id</span><span style="color: grey;">=</span><span style="color: #ff8080;">&quot;widget-2&quot;</span> <span style="color: cyan;">class</span><span style="color: grey;">=</span><span style="color: #ff8080;">&quot;widget widget-class-2&quot;</span>&gt;</span>
      <span style="color: #009900;">&lt;<span style="color: #ffff00;">h2</span>&gt;</span>Widget 2 Title<span style="color: #009900;">&lt;<span style="color: grey;">/</span><span style="color: #ffff00;">h2</span>&gt;</span>
      <span style="color: #009900;">&lt;<span style="color: #ffff00;">p</span>&gt;</span>...content2...<span style="color: #009900;">&lt;<span style="color: grey;">/</span><span style="color: #ffff00;">p</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: grey;">/</span><span style="color: #ffff00;">li</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: grey;">/</span><span style="color: #ffff00;">ul</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: grey;">/</span><span style="color: #ffff00;">div</span>&gt;</span></pre></td></tr></table></div>

<p>The various jQuery tabs plugins all require the markup to be strutured like this (notice the titles moved to the additional list at the top, with anchor tags corresponding to the ids of the respective widgets:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="html4strict" style="color: #ccc;"><span style="color: #009900;">&lt;<span style="color: #ffff00;">div</span> <span style="color: cyan;">id</span><span style="color: grey;">=</span><span style="color: #ff8080;">&quot;sidebar-1&quot;</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #ffff00;">ul</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #ffff00;">li</span>&gt;&lt;<span style="color: #ffff00;">a</span> <span style="color: cyan;">href</span><span style="color: grey;">=</span><span style="color: #ff8080;">&quot;#widget-1&quot;</span>&gt;</span>Widget 1 Title<span style="color: #009900;">&lt;<span style="color: grey;">/</span><span style="color: #ffff00;">a</span>&gt;&lt;<span style="color: grey;">/</span><span style="color: #ffff00;">li</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #ffff00;">li</span>&gt;&lt;<span style="color: #ffff00;">a</span> <span style="color: cyan;">href</span><span style="color: grey;">=</span><span style="color: #ff8080;">&quot;#widget-2&quot;</span>&gt;</span>Widget 2 Title<span style="color: #009900;">&lt;<span style="color: grey;">/</span><span style="color: #ffff00;">a</span>&gt;&lt;<span style="color: grey;">/</span><span style="color: #ffff00;">li</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: grey;">/</span><span style="color: #ffff00;">ul</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #ffff00;">ul</span> <span style="color: cyan;">class</span><span style="color: grey;">=</span><span style="color: #ff8080;">&quot;sidebar-list&quot;</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #ffff00;">li</span> <span style="color: cyan;">id</span><span style="color: grey;">=</span><span style="color: #ff8080;">&quot;widget-1&quot;</span> <span style="color: cyan;">class</span><span style="color: grey;">=</span><span style="color: #ff8080;">&quot;widget widget-class-1&quot;</span>&gt;</span>
      <span style="color: #009900;">&lt;<span style="color: #ffff00;">p</span>&gt;</span>...content...<span style="color: #009900;">&lt;<span style="color: grey;">/</span><span style="color: #ffff00;">p</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: grey;">/</span><span style="color: #ffff00;">li</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #ffff00;">li</span> <span style="color: cyan;">id</span><span style="color: grey;">=</span><span style="color: #ff8080;">&quot;widget-2&quot;</span> <span style="color: cyan;">class</span><span style="color: grey;">=</span><span style="color: #ff8080;">&quot;widget widget-class-2&quot;</span>&gt;</span>
      <span style="color: #009900;">&lt;<span style="color: #ffff00;">p</span>&gt;</span>...content2...<span style="color: #009900;">&lt;<span style="color: grey;">/</span><span style="color: #ffff00;">p</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: grey;">/</span><span style="color: #ffff00;">li</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: grey;">/</span><span style="color: #ffff00;">ul</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: grey;">/</span><span style="color: #ffff00;">div</span>&gt;</span></pre></td></tr></table></div>

<h3>The Solution</h3>
<p>While it would be possible to alter the PHP code to output the list above the widgets (although, I looked into this solution and was not able to find a hook that would allow it without altering the core), we can just use some custom jQuery to dynamically add the list before invoking the tabs plugin.  This method also has the advantage that it makes our tabs more unobtrusive.  If javascript is disabled, the page will look exactly as it would with the standard sidebar widgets, but if javascript is available, we&#8217;ll fix the markup and add the tabs all at once with our jQuery code.</p>
<h3>The Code</h3>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
</pre></td><td class="code"><pre class="javascript" style="color: #ccc;">$<span style="color: grey;">&#40;</span>document<span style="color: grey;">&#41;</span>.<span style="color: magenta;">ready</span><span style="color: grey;">&#40;</span><span style="color: #ffff00;">function</span><span style="color: grey;">&#40;</span><span style="color: grey;">&#41;</span> <span style="color: grey;">&#123;</span>
   <span style="color: #80ff80">// first, we select the sidebar</span>
   $<span style="color: grey;">&#40;</span><span style="color: #ff8080;">'#sidebar-1 .sidebar-list'</span><span style="color: grey;">&#41;</span>.<span style="color: magenta;">each</span><span style="color: grey;">&#40;</span><span style="color: #ffff00;">function</span><span style="color: grey;">&#40;</span><span style="color: grey;">&#41;</span> <span style="color: grey;">&#123;</span>
      <span style="color: #80ff80">// each child of the sidebar element will be a widget, and will become a tab</span>
      <span style="color: #ffff00;">var</span> widgets <span style="color: grey;">=</span> $<span style="color: grey;">&#40;</span><span style="color: #4080ff;">this</span><span style="color: grey;">&#41;</span>.<span style="color: magenta;">children</span><span style="color: grey;">&#40;</span><span style="color: grey;">&#41;</span><span style="color: grey;">;</span>
&nbsp;
      <span style="color: #80ff80">// we'll build the list of titles, starting with the opening tag</span>
      <span style="color: #ffff00;">var</span> titleList <span style="color: grey;">=</span> <span style="color: #ff8080;">'&lt;ul&gt;'</span><span style="color: grey;">;</span>
&nbsp;
      <span style="color: #80ff80">//for each widget in the sidebar:</span>
      widgets.<span style="color: magenta;">each</span><span style="color: grey;">&#40;</span><span style="color: #ffff00;">function</span><span style="color: grey;">&#40;</span><span style="color: grey;">&#41;</span> <span style="color: grey;">&#123;</span>
&nbsp;
         <span style="color: #80ff80">// save the title of the widget</span>
         <span style="color: #ffff00;">var</span> widgetTitle <span style="color: grey;">=</span> $<span style="color: grey;">&#40;</span><span style="color: #4080ff;">this</span><span style="color: grey;">&#41;</span>.<span style="color: magenta;">children</span><span style="color: grey;">&#40;</span><span style="color: #ff8080;">'h2'</span><span style="color: grey;">&#41;</span>.<span style="color: magenta;">text</span><span style="color: grey;">&#40;</span><span style="color: grey;">&#41;</span><span style="color: grey;">;</span>
         <span style="color: #80ff80">// then hide it since it will be displayed in the tab</span>
         $<span style="color: grey;">&#40;</span><span style="color: #4080ff;">this</span><span style="color: grey;">&#41;</span>.<span style="color: magenta;">children</span><span style="color: grey;">&#40;</span><span style="color: #ff8080;">'h2'</span><span style="color: grey;">&#41;</span>.<span style="color: magenta;">hide</span><span style="color: grey;">&#40;</span><span style="color: grey;">&#41;</span><span style="color: grey;">;</span>
&nbsp;
         <span style="color: #80ff80">// create a new list item for the tab, linking to this widget's id</span>
         <span style="color: #ffff00;">var</span> listItem <span style="color: grey;">=</span> <span style="color: #ff8080;">'&lt;li&gt;&lt;a href=&quot;#'</span><span style="color: grey;">+</span>$<span style="color: grey;">&#40;</span><span style="color: #4080ff;">this</span><span style="color: grey;">&#41;</span>.<span style="color: magenta;">attr</span><span style="color: grey;">&#40;</span><span style="color: #ff8080;">'id'</span><span style="color: grey;">&#41;</span><span style="color: grey;">+</span><span style="color: #ff8080;">'&quot;&gt;'</span><span style="color: grey;">+</span>widgetTitle<span style="color: grey;">+</span><span style="color: #ff8080;">'&lt;/a&gt;&lt;/li&gt;'</span><span style="color: grey;">;</span>
         <span style="color: #80ff80">// add the list item to the list we're building</span>
         titleList <span style="color: grey;">+=</span> listItem<span style="color: grey;">;</span>
      <span style="color: grey;">&#125;</span><span style="color: grey;">&#41;</span><span style="color: grey;">;</span>
      <span style="color: #80ff80">// close the list now that we're done going through each widget</span>
      titleList <span style="color: grey;">+=</span> <span style="color: #ff8080;">'&lt;/ul&gt;'</span><span style="color: grey;">;</span>
&nbsp;
      <span style="color: #80ff80">// add the title list to the beginning of the sidebar</span>
      $<span style="color: grey;">&#40;</span><span style="color: #4080ff;">this</span><span style="color: grey;">&#41;</span>.<span style="color: magenta;">before</span><span style="color: grey;">&#40;</span>titleList<span style="color: grey;">&#41;</span><span style="color: grey;">;</span>
   <span style="color: grey;">&#125;</span><span style="color: grey;">&#41;</span><span style="color: grey;">;</span>
&nbsp;
   <span style="color: #80ff80">// apply the tabs plugin</span>
   $<span style="color: grey;">&#40;</span><span style="color: #ff8080;">'#sidebar-1'</span><span style="color: grey;">&#41;</span>.<span style="color: magenta;">tabs</span><span style="color: grey;">&#40;</span><span style="color: grey;">&#41;</span><span style="color: grey;">;</span>
<span style="color: grey;">&#125;</span><span style="color: grey;">&#41;</span><span style="color: grey;">;</span></pre></td></tr></table></div>

<h3>Explanation</h3>
<p>The comments in the code should make the solution pretty self-explanatory.  This will take all the widgets in the selected sidebar and create tabs for them.</p>
<p>There are some things you&#8217;ll have to be careful about if you use this code.  First, you&#8217;ll have to change the selection for the sidebar div (line 3 above, as well as in the second-to-last line) to match yours.  This assumes you <em>have</em> your sidebar list wrapped in a div (required by the tabs plugin), so if you don&#8217;t, you will need to add that, either in the theme itself or with jQuery( using .wrap() ). Also, in the two places you see &#8216;h2&#8242;, this is assuming that the titles of the widgets are in &lt;h2&gt; tags.  You may need to select a different tag if your theme displays the widget titles differently.</p>
<p>Also note that this will create tabs for <em>all</em> the widgets in the sidebar.  Making it only apply to specific widgets is possible, but a bit more complicated.  Luckily, with WordPress 2.8, the sidebars/widgets interface is much improved.  One solution would be to create multiple &#8216;sidebars&#8217; that stacked on top of each other in the sidebar area of your theme, and apply the above tab-ifying code to one or more of them individually.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffgran.com/180/blog/wordpress-tabbed-sidebar-widgets-with-jquery/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Book Review: Javascript: The Missing Manual</title>
		<link>http://jeffgran.com/161/blog/book-review-javascript-the-missing-manual</link>
		<comments>http://jeffgran.com/161/blog/book-review-javascript-the-missing-manual#comments</comments>
		<pubDate>Sat, 13 Jun 2009 01:30:57 +0000</pubDate>
		<dc:creator>Jeff Gran</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[book review]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://jeffgran.com/?p=161</guid>
		<description><![CDATA[In my ongoing efforts to realize my dreams of becoming a true web ninja, I recently read Javascript: The Missing Manual by David Sawyer MacFarland.  I had read his previous book in the Missing Manuals series on CSS, and had both enjoyed it and learned a lot from it. I did find this book interesting [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-166" title="js_mm_cover" src="http://jeffgran.com/img/js_mm_cover.png" alt="js_mm_cover" width="145" height="190" />In my ongoing efforts to realize my dreams of becoming a true web ninja, I recently read <a title="Javascript: The Missing Manual" href="http://www.amazon.com/gp/product/0596515898"><em>Javascript: The Missing Manual</em></a> by <a title="David Sawyer MacFarland" href="http://www.sawmac.com">David Sawyer MacFarland</a>.  I had read his previous book in the Missing Manuals series on CSS, and had both enjoyed it and learned a lot from it.</p>
<p>I did find this book interesting and informative as well, but I say that with caveats, which I&#8217;ll explain.</p>
<p>First, I&#8217;m not sure that I was exactly the intended audience for the book.  I am pretty well-versed in programming concepts in general, and what I was looking for was an introduction to the language of javascript and when and how to use it effectively in my web sites.  In contrast, this book seemed to be geared a little more towards pure designers who are scared of programming. A few times during my reading I had to roll my eyes at another &#8220;If this is making your head hurt, just type it in and know that it works.&#8221;  Personally, I want to know how everything works and I&#8217;m not interested in blindly typing in code to &#8220;make it work.&#8221;  I can do that by searching google and cutting and pasting.  I bought a book because I wanted to get deep, to learn the ins and outs of how it all works behind the scenes.  I wanted a book because I&#8217;m on my way to becoming a full-on pro, and this book at times seemed more geared towards hobbyists, or designers who just wanted to dip their toes into javascript.</p>
<p>Second, this is really a book on jQuery.  I don&#8217;t have a problem with that, but it needs to be said.  The first section of the book goes over the syntax of plain old javascript, including function declarations, string manipulation with built-in functions and regular expressions, math functions and operators, variable typing, etc.  Then the author quickly moves on to the use of libraries to speed development, and specifically to jQuery.  I&#8217;ll say here that I have very ambiguous feelings regarding the need to learn the &#8220;hard way&#8221; of doing things when using a library to do it for you will normally suffice.  That&#8217;s a debate in itself, and I don&#8217;t want to get into all the pros and cons, but again, it should be said that you won&#8217;t be learning the traditional way of working with the DOM here, you&#8217;ll be learning to use jQuery selectors.</p>
<p>Now for the good parts.  Like the CSS book in the series, I found the information to be explained in a very readable and understandable tone.  The book is well-paced &#8212; several times I would have an &#8220;aha &#8211; that&#8217;s cool how that works!&#8221; moment, followed by a &#8220;but wait, what if you wanted to do it this way?&#8221;, and without fail the next paragraph would address my question.  Sometimes it would answer right there, and sometimes it would say &#8220;we&#8217;ll show you how to do this with more flexibility in the next section&#8230;&#8221; so I&#8217;d know it was coming.  This ability to anticipate the reader&#8217;s thinking is probably the best part of these books.</p>
<p>Also, the tutorials were again very helpful and well laid-out.  Another thing I&#8217;d like to point out is that the tutorials are not just re-hashes of the information in the preceding chapter.  There is additional learning value in the tutorials that build on what you learn by reading the chapter.  So you get the explanations of how things are designed to work, and then you get to play with a real-world example and the book shows you how to solve the additional problems that inevitably come up.  Code examples are thoroughly explained (sometimes too thoroughly &#8212; I found myself skipping sections saying to myself, &#8220;yeah, I get it already&#8221; &#8212; but that&#8217;s definitely better than the opposite).</p>
<p>After going through all the basic functionality of jQuery itself, the book unfortunately devolves into several chapters showing how to use specific jQuery plugins for specific purposes: image gallery, slideshow, tabs, etc.  While these are certainly useful, no additional concepts or ideas were presented, just lists of the specific variables and possible values for customizing the plugins.  This part of the book seemed like fluff to me and could have been condensed into a few short pages of charts.  It&#8217;s not that the information wasn&#8217;t useful, just that after learning so many interesting and, to me, revolutionary concepts, reading paragraphs about using &#8220;slow&#8221; if you want it to move slow, and &#8220;fast&#8221; if you want it to move fast seemed like a step backwards.</p>
<p>The last section of the book is dedicated to AJAX.  Here the quality of information improves again, but again with caveats.  You won&#8217;t learn the details of setting up the XMLHTTPRequest object, but you&#8217;ll learn what is and then how jQuery saves you the trouble of knowing.</p>
<p>In one way this final section about AJAX serves as a microcosm to the whole book.  It&#8217;s a great introduction, it gets you familiar with the general concepts and shows you how to get started right away, but it left me hungry for more, deeper knowledge.  And perhaps that&#8217;s the way it should be.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffgran.com/161/blog/book-review-javascript-the-missing-manual/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Site Upgrades: WordPress 2.8!</title>
		<link>http://jeffgran.com/163/blog/site-upgrades-wordpress-28</link>
		<comments>http://jeffgran.com/163/blog/site-upgrades-wordpress-28#comments</comments>
		<pubDate>Sat, 13 Jun 2009 00:17:34 +0000</pubDate>
		<dc:creator>Jeff Gran</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[announcement]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://jeffgran.com/?p=163</guid>
		<description><![CDATA[WordPress 2.8 was released on Wednesday, and I've upgraded my site.]]></description>
			<content:encoded><![CDATA[<p>WordPress 2.8 <a title="WordPress 2.8 Jazzes Themes and Widgets" href="http://wordpress.org/development/2009/06/wordpress-28/">was released</a> on Wednesday, and I&#8217;ve upgraded my site.  I&#8217;m looking forward to playing with the new widgets API.  Hmm&#8230; what kind of widgets will I make?</p>
<p>I also upgraded to the latest <a title="Pods: WordPress CMS Plugin" href="http://pods.uproot.us/">Pods</a> release (1.6.5), which will allow some nifty behind-the-scenes magic to happen.</p>
<p>That&#8217;s all.  Carry on.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeffgran.com/163/blog/site-upgrades-wordpress-28/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

