<?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>thyncology &#187; Mac</title>
	<atom:link href="http://www.thynctank.com/category/mac/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.thynctank.com</link>
	<description>The Science of Thynctank.</description>
	<lastBuildDate>Fri, 03 Apr 2009 03:51:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Gracefully Degrading Widgets, Part 2: Navbars &amp; jQuery Plugins</title>
		<link>http://www.thynctank.com/javascript/2009/03/gracefully-degrading-widgets-part-2-navbars-jquery-plugins/</link>
		<comments>http://www.thynctank.com/javascript/2009/03/gracefully-degrading-widgets-part-2-navbars-jquery-plugins/#comments</comments>
		<pubDate>Thu, 05 Mar 2009 10:42:14 +0000</pubDate>
		<dc:creator>thynctank</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[graceful degradation]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[progressive enhancement]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[widgets]]></category>

		<guid isPermaLink="false">http://www.thynctank.com/?p=145</guid>
		<description><![CDATA[I recently met up with a friend and former coworker to help him ramp up his jQuery skills quickly. In the process I got to play with a few things I hadn&#8217;t bothered to pick up previously myself! First of these was Google&#8217;s Ajax Libraries API. While worthless for when you need to be offline [...]]]></description>
			<content:encoded><![CDATA[<p>I recently met up with a friend and former coworker to help him ramp up his jQuery skills quickly. In the process I got to play with a few things I hadn&#8217;t bothered to pick up previously myself!</p>

<p>First of these was <a href="http://code.google.com/apis/ajaxlibs/">Google&#8217;s Ajax Libraries API</a>. While worthless for when you need to be offline (as I ended up being, since the Borders where we met has no free wifi, and <strong>I am cheap/skint</strong>), it&#8217;s nice and easy to include scripts on your pages without needing to maintain the files yourself. Luckily I thought to download local copies and installed Google Docs offline shortly before leaving to meet with the dude.</p>

<p>The second interesting thing I picked up, I actually picked up <em>after</em> the meeting, as I both wanted to learn it and wanted to share with my friend. That something is <em>How to Author a jQuery Plugin</em>, which is what we&#8217;re going to look at today. We&#8217;ll be building a flexible drop-down navigation menu which will work <em>with or without</em> JavaScript thanks to CSS.</p>

<p>Here&#8217;s the working example: <a href="http://www.thynctank.com/nav.html">MultiNav</a></p>

<p><a href="http://www.thynctank.com/javascript/2008/02/gracefully-degrading-widgets-part-1-tabs/">Previously</a>, I discussed some of the fundamental ideas behind <strong>Gracefully Degrading Widgets</strong>, but let&#8217;s quickly delineate them again here:</p>

<ul>
<li>Focus on content above interactivity &#8211; if that means sacrificing the latter for the former, so be it</li>
<li>Present most important content first &#8211; sometimes it is necessary to hide some content to maintain page layout, the most important still shows</li>
<li>Write minimalist markup &#8211; this leads to fewer chances of screwing up and makes it easier on any consumers of your code</li>
<li>Write stylesheets to hide interactive content by default, and override in your JavaScript</li>
</ul>

<p>We&#8217;ll also be focusing on <strong>reusability</strong> and <strong>flexibility</strong>, and we&#8217;ll discover that part of this is covered by virtue of the fact we&#8217;re creating our widget as a jQuery plugin. jQuery plugins are automatically applicable to any selector style available in jQuery, and so our widget will immediately be available to instantiate among common classes of a page, or to elements with individually unique IDs. You can even apply multiple instances on the page at simultaneously. In addition to these flexible instantiation capabilities, we&#8217;ll be building the widget to take a number of options to use different effects, use different classes if the default class names are not appropriate or would conflict with existing names on the page, and so on.</p>

<p>On with the show already! First off let&#8217;s create some simple markup for our drop down menu and style it w/ CSS:</p>


<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;">  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">ul</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;nav&quot;</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>Top Level<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;</span>
      <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">ul</span>&gt;</span>
        <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>Submenus<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span>
        <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>Are Much<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span>
        <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>Less Prominent<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span>
      <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">ul</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>Menus Are<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>Most Noticeable<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;</span>
      <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">ul</span>&gt;</span>
        <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>But Still<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span>
        <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">li</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>Quite Useful<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span>
      <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">ul</span>&gt;</span>
    <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">li</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">ul</span>&gt;</span></pre></div></div>


<p>Nice and simple!</p>


<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">  <span style="color: #00AA00;">*</span> <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">margin</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span><span style="color: #00AA00;">&#125;</span>
  <span style="color: #6666ff;">.nav</span> <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">margin</span><span style="color: #00AA00;">:</span> <span style="color: #933;">50px</span><span style="color: #00AA00;">;</span><span style="color: #00AA00;">&#125;</span>
  <span style="color: #6666ff;">.nav</span> li <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">display</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">block</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">float</span><span style="color: #00AA00;">:</span> <span style="color: #000000; font-weight: bold;">left</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">background-color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#ccccee</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">height</span><span style="color: #00AA00;">:</span> <span style="color: #933;">50px</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">line-height</span><span style="color: #00AA00;">:</span> <span style="color: #933;">2em</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">position</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">relative</span><span style="color: #00AA00;">;</span><span style="color: #00AA00;">&#125;</span>
  <span style="color: #6666ff;">.nav</span> li ul <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">display</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">position</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">absolute</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">top</span><span style="color: #00AA00;">:</span> <span style="color: #933;">50px</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">left</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span><span style="color: #00AA00;">&#125;</span>
  <span style="color: #6666ff;">.nav</span> li a <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">display</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">block</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">text-decoration</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span> <span style="color: #933;">10px</span><span style="color: #00AA00;">;</span><span style="color: #00AA00;">&#125;</span>
  <span style="color: #6666ff;">.nav</span> li a<span style="color: #3333ff;">:hover </span><span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">text-decoration</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">underline</span><span style="color: #00AA00;">;</span><span style="color: #00AA00;">&#125;</span>
  <span style="color: #6666ff;">.nav</span> li<span style="color: #3333ff;">:hover </span>ul <span style="color: #00AA00;">&#123;</span><span style="color: #000000; font-weight: bold;">display</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">block</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span>
  <span style="color: #6666ff;">.nav</span> li ul li <span style="color: #00AA00;">&#123;</span><span style="color: #000000; font-weight: bold;">display</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">block</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">float</span><span style="color: #00AA00;">:</span> <span style="color: #000000; font-weight: bold;">left</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">width</span><span style="color: #00AA00;">:</span> <span style="color: #933;">130px</span><span style="color: #00AA00;">;</span><span style="color: #00AA00;">&#125;</span></pre></div></div>


<p><em>Still</em> simple!</p>

<p>Even with this alone, the example code will show simple hover-over submenus via CSS, in browsers that support it (all but IE6, I believe). This is where degradation comes into play. We want things to fail gracefully, so each of those top-level menus should be a link in and of itself, rather than slamming all the links into the submenus. This is a good failover.</p>

<p>So now that we&#8217;ve got simple menus, let&#8217;s add some action!</p>

<p>To animate a single submenu&#8217;s intro into the page, we might use code similar to the following:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;.nav:first &gt; ul &gt; li:first &gt; ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fadeIn</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>


<p>Which uses an advanced CSS3 selector to grab the very first submenu (a <em>ul</em> element) of the first top-level menu item of the first nav. <code>fadeIn()</code> is a call to a nice pre-defined function of any element(s) returned by jQuery.</p>

<p>That&#8217;s all well and good, but what we really need to do is setup a hover effect to fade this menu in and out given the user&#8217;s interaction with it.</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;.nav:first &gt; li:first&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hover</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">children</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fadeIn</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">children</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fadeOut</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>


<p>This sets up two anonymous functions to be triggered on <em>mouseOver</em> and on <em>mouseOut</em>. jQuery takes care of all of this. What&#8217;s important is understanding the selectors and the event assignment. We won&#8217;t go into detail about the selectors here, but definitely read the <a href="http://docs.jquery.com/Selectors">documentation</a> and play with it. The <em>hover</em> function takes two parameters, each a function. The first will be run on mouseOver, and the second will be run on mouseOut.</p>

<p>So that&#8217;s a start. Our submenu is fading in and out. But what if you accidentally mouse off the submenu? The damned thing fades away instantly! To get around this limitation, we&#8217;ll use a handy built-in feature of JavaScript, <code>setTimeout</code>. This function takes as its parameters a function literal to be called after a specified number of milliseconds, followed by a timeout value in milliseconds. On mouseOver, we&#8217;ll set a class on the element, let&#8217;s call it &#8220;over&#8221;. On mouseOut, we&#8217;ll remove the class, and call <code>setTimeout</code>. After a specified amount of time, let&#8217;s say 500ms, we&#8217;ll check whether the class &#8220;over&#8221; is present on the top-level nav, and if it isn&#8217;t, we&#8217;ll fade it out. If it is (indicating the nav item has been hovered over again), we do nothing.</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;.nav:first &gt; li:first&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hover</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">addClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;over&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">children</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fadeIn</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      <span style="color: #003366; font-weight: bold;">var</span> li <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      setTimeout<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>li.<span style="color: #660066;">hasClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;over&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
          li.<span style="color: #660066;">fadeOut</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">500</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>


<p>This new code sets it up exactly as we&#8217;d like it for the first submenu content alone.</p>

<p>What we want to do is make this reusable, as much as possible, and also make it versatile. That&#8217;s where jQuery&#8217;s plugin system comes in.</p>

<p>jQuery plugins are like any other widget initializer code, only they automatically get to take advantage of jQuery&#8217;s fancy schmancy selector system. They should also be written using the function name <em>jQuery</em> rather than <em>$</em>, because jQuery optionally allows itself to be alternately aliased so that it can sit along side other libraries, which might also define a global function <em>$</em>. Both <a href="http://www.prototypejs.org">Prototype</a> and <a href="http://www.mootools.net/">MooTools</a> do this, and still jQuery can run in combination with these libraries. If you were to use the $ function, you could likely be unintentionally calling the Prototype or MooTools selector function rather than jQuery&#8217;s.</p>

<p>Instructions on authoring jQuery plugins can be found <a href="http://docs.jquery.com/Plugins/Authoring">on jQuery&#8217;s Web site</a>. It all boils down to:</p>

<ol>
<li>Respecting the &#8220;jQuery&#8221; function name over &#8220;$&#8221;</li>
<li>Defining your function as a property of <code>jQuery.fn</code>, and</li>
<li>Returning the jQuery object that it is called on. (this allows chaining calls, something near and dear to jQuery developers&#8217; hearts)</li>
<li>To be incorporated as an official plugin, the plugin should be defined in a standalone file, named &#8220;jquery.[plugin name].js&#8221; where &#8220;[plugin name]&#8221; is your plugin&#8217;s name.</li>
</ol>

<p>Let&#8217;s take a look at the next version of our code, the first as a plugin:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  jQuery.<span style="color: #660066;">fn</span>.<span style="color: #660066;">nav</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #003366; font-weight: bold;">var</span> nav <span style="color: #339933;">=</span> jQuery<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      nav.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot; &gt; li&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hover</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        jQuery<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">children</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fadeIn</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> li <span style="color: #339933;">=</span> jQuery<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        setTimeout<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
          <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>li.<span style="color: #660066;">hasClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;over&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            li.<span style="color: #660066;">fadeOut</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">500</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>


<p>This is a very suitable, fine piece of code, and it&#8217;s even a plugin now. It&#8217;s even reusable, because it&#8217;s no longer tied to the &#8220;.nav&#8221; class. You can actually call it multiple times on a page, and using multiple selectors, and all will work just fine, independently:</p>

<ul>
<li><code>$(".nav").nav()</code> works just like our old code, only now it&#8217;s a <em>lot</em> shorter.</li>
<li><code>$("#topNav").nav()</code> also works, only this is for a single unique element</li>
</ul>

<p>However, it&#8217;s not very versatile beyond the selector bit. For that, we&#8217;ll need to introduce the concept of <em>default options</em> and overrides. jQuery provides a simple means of setting up default settings for a plugin that can be overridden in any call to it by passing in an options object. The options object concept is an echo of similar functionality in other programming languages: Ruby (via Hashes), Python (via named arguments) and other languages via similar constructs such as associative arrays. The idea behind it is that no one wants to have to memorize the order of parameters for a function, so don&#8217;t make them! Object literals allow you to specify their component properties in any order.</p>

<p>To obtain this functionality in jQuery, simply call <code>jQuery.extend()</code>, passing in an object literal for the default values, and the options object parameter from the plugin&#8217;s function. Through this, we can specify faster or slower fade effects, as well as change the actual effects called. This is the final version of our plugin, and the code is quite a bit longer.</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  jQuery.<span style="color: #660066;">fn</span>.<span style="color: #660066;">multinav</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>options<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> settings <span style="color: #339933;">=</span> jQuery.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
      effect<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;fade&quot;</span><span style="color: #339933;">,</span>
      duration<span style="color: #339933;">:</span> <span style="color: #CC0000;">250</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> options<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> fade <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
      over<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        jQuery<span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fadeIn</span><span style="color: #009900;">&#40;</span>settings.<span style="color: #660066;">duration</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      out<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        jQuery<span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fadeOut</span><span style="color: #009900;">&#40;</span>settings.<span style="color: #660066;">duration</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> slide <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
      over<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        jQuery<span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">slideDown</span><span style="color: #009900;">&#40;</span>settings.<span style="color: #660066;">duration</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      out<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        jQuery<span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">slideUp</span><span style="color: #009900;">&#40;</span>settings.<span style="color: #660066;">duration</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> size <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
      over<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        jQuery<span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">show</span><span style="color: #009900;">&#40;</span>settings.<span style="color: #660066;">duration</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      out<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        jQuery<span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hide</span><span style="color: #009900;">&#40;</span>settings.<span style="color: #660066;">duration</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> effect <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">switch</span><span style="color: #009900;">&#40;</span>settings.<span style="color: #660066;">effect</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">&quot;slide&quot;</span><span style="color: #339933;">:</span>
        effect <span style="color: #339933;">=</span> slide<span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">&quot;size&quot;</span><span style="color: #339933;">:</span>
        effect <span style="color: #339933;">=</span> size<span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">&quot;fade&quot;</span><span style="color: #339933;">:</span>
      <span style="color: #003366; font-weight: bold;">default</span><span style="color: #339933;">:</span>
        effect <span style="color: #339933;">=</span> fade<span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// iterate over the elements obtained from the selector</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #003366; font-weight: bold;">var</span> nav <span style="color: #339933;">=</span> jQuery<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      nav.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot; &gt; li &gt; ul&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hide</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      nav.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot; &gt; li&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">hover</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        jQuery<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">addClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;over&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        effect.<span style="color: #660066;">over</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> li <span style="color: #339933;">=</span> jQuery<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">removeClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;over&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        setTimeout<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
          <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>li.<span style="color: #660066;">hasClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;over&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            effect.<span style="color: #660066;">out</span><span style="color: #009900;">&#40;</span>li<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">500</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>


<p>Though this code is longer, it&#8217;s still quite legible. We&#8217;ve changed the plugin&#8217;s name to <em>multinav</em> to reflect it&#8217;s new, multi-functional nature The new benefit is that we are able to call on the plugin with alternate effects and timing, simply by passing in an object literal with alternate values from the defaults. Here are a few examples:</p>

<ul>
<li><code>$(".nav:first").multinav();</code> &#8211; this is the default behavior</li>
<li><code>$(".nav:nth(1)").multinav({effect: "slide", duration: 100});</code> &#8211; this selects the second nav-classed element and performs a fast slideIn on hover</li>
<li><code>$(".nav:last").multinav({effect: "size", duration: 1000});</code> &#8211; this selects the last nav-classed element and performs a slow size-in on hover</li>
</ul>

<p>Using these ideas, you can build any number of plugins which, when handled correctly, can <em>work alongside other libraries</em>, can <em>work under a variety of conditions</em> and <em>present different functionality based on the needs of the job at hand</em>. Calling on a plugin is <strong>typically only one line of code</strong>. That&#8217;s a lot of power in one line. Not only that, but when using the practices of graceful degradation, your page will look and behave appropriately when interactivity is not possible in the browser.</p>

<p>Remember that any widget with interactive elements (form controls, ajax links, tabs, content which moves around or hides/reveals&#8230;) should either hide those interactive elements in the CSS and reveal in the JavaScript, or find a way to make use of the elements using the backend. This ensures the page does not contain any confusing, ineffectual controls which look as though they&#8217;ll bring about change on the page. In the case of ajax tabs, for instance, you have two choices: Hide the tabs altogether (certainly the easier route), or organize your content and backend technology so that the tabs work as static links to reload the page showing the appropriate (newly-clicked) tab content and hiding the other tabs. This is a bit more trouble, and if you can get away with showing only the most-important content in the first tab, I suggest taking that route.</p>

<p>Have fun writing gracefully-degrading jQuery plugins!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thynctank.com/javascript/2009/03/gracefully-degrading-widgets-part-2-navbars-jquery-plugins/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Awesome Macness</title>
		<link>http://www.thynctank.com/mac/2007/04/awesome-macness/</link>
		<comments>http://www.thynctank.com/mac/2007/04/awesome-macness/#comments</comments>
		<pubDate>Sun, 22 Apr 2007 09:24:02 +0000</pubDate>
		<dc:creator>thynctank</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[browscap]]></category>
		<category><![CDATA[humor]]></category>
		<category><![CDATA[mobilator]]></category>
		<category><![CDATA[quicksilver]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://www.thynctank.com/wordpress/awesome-macness</guid>
		<description><![CDATA[So John put me onto RCDefaultApp, and it seems to be a great, simple solution to a vexing problem with Mac OS: File type associations don&#8217;t stick. Whereas in Windows, all filetypes are regulated by the evil ruler, the Registry, in Mac files seem almost to be free-floating entities with no compass telling them how [...]]]></description>
			<content:encoded><![CDATA[<p>So <a href="http://boboroshi.com" title="Boboroshi.">John</a> put me onto <a href="http://www.rubicode.com/Software/RCDefaultApp/" title="RCDefaultApp">RCDefaultApp</a>, and it seems to be a great, simple solution to a vexing problem with Mac OS: File type associations don&#8217;t stick. Whereas in Windows, all filetypes are regulated by the evil ruler, the <a href="http://en.wikipedia.org/wiki/Windows_registry" title="Registry">Registry</a>, in Mac files seem almost to be free-floating entities with no compass telling them how to open with what program. In Finder, you can get Info (Cmd-I) where you can assign what app a given file will open with. But then, what of the next file of that type you happen upon? Well, the solution should be as simple as setting the app for the current file and hitting the button marked &#8220;Change All&#8230;&#8221; but no, that would be too simple and straightforward. The <a href="http://video.stumbleupon.com/?p=3t2mk2n8ct" title="iWorld - Great Stuff.">gods of Apple</a> in Their Infinite Wisdom, decided to bestow upon us a non-functioning button. (or at least <em>extremely</em> poorly-functioning one) Anyhow, only time will tell whether this new app will prove to be a pearl or just another grain of sand.</p>

<p>I also started messing with a few other Mac apps lately, namely <a href="http://bargiel.home.pl/iGTD/" title="iGTD">iGTD</a> and <a href="http://quicksilver.blacktree.com/" title="Quicksilver">Quicksilver</a>.<span id="more-28"></span></p>

<p>iGTD is a fast, keyboard-oriented todo list manager with priority and context switching. You can associate tasks with given projects, and it will also sync to external software/devices via iSync. I&#8217;ve now got my Treo syncing to iCal and iGTD via iSync. That iWorld video (if you didn&#8217;t follow the link on the Apple gods you owe it to yourself) had it right with the out-of-hand i-ness of Apple and Mac-tastic software. Developers need to drop the i and cross their Ts and move on with life. But I understand trends. <em>sigh</em> Anyhow, iGTD is freeware and works very fast once you get used to it. Let&#8217;s see how well it fairs in my daily usage routine. (I haven&#8217;t gotten used to seeing iCal pop reminders at me from stuff I put in my Palm yet. May have to disable the iCal bit. One alarm is enough, already!)</p>

<p>I have to say Quicksilver is immediately becoming my go-to app for anything in the world. (like TextMate is for quick coding as well as some power moves) I may have to look into writing some plugins for it, though, as immediately sending links from browser to buddies via Adium  would be a great feature, and I was thinking of another one earlier that I just can&#8217;t recall now. (it <em>is</em> 4:35 AM) But Quicksilver is like Spotlight on meth: immensely faster, and smarter. It learns your nuances so that over time it retrieves the information you&#8217;re looking for faster. An example: I bring up the Quicksilver interface (Ctrl-Space) and begin my query by typing &#8220;text&#8221;. This brings up 6 results. Among these are a link to the <a href="http://textsnippets.com/" title="Text Snippets">Text Snippets</a> site, TextEdit, and TextMate. As I&#8217;ve said, TextMate is quick becoming my weapon of choice for editing, so I see that as being my top choice after entering &#8220;text&#8221;. However, the Text Snippets link is top, for some reason. Perhaps it was indexed first. Regardless, after playing the search-and-run game twice and picking TextMate both times, Quicksilver has learned that this is my top choice. From there on out (assuming I never chose from among the other results) it will be safe to hit Enter, knowing that TextMate will launch.</p>

<p>But it&#8217;s<em> </em>smarter than that even. TextMate applies this preference-learning to shorter queries as well. So now, automatically it associates textmate with &#8220;t&#8221; for instance. It&#8217;s full of these things. The whole app was built on the philosophy of <a href="http://docs.blacktree.com/quicksilver/tao" title="Tao Te Ching">&#8220;acting without doing&#8221;</a> and seems to achieve that lofty goal  very well.</p>

<p>Speaking of TextMate, I&#8217;ve been playing a bit more. I like. Ctrl-Shift-Q runs a one-liner query on your localhost SQL db. Rad. Ctrl-Shift-A brings up a context menu with SVN actions. If you don&#8217;t know the keyboard shortcuts and triggers for a given bundle, hit Ctrl-Esc to bring up the menu you&#8217;d otherwise have to click for. (which I&#8217;ve been doing) So nice to have things so simple. One thing I keep wishing Eclipse had. For all of its power, Eclipse has no means for customizing its menus or adding buttons or <em>even keyboard shortcuts</em> for any menu actions. That&#8217;s just plain crazy. So in order to commit a file to SVN, you&#8217;ve got to right-click a file in Navigator or whatever file browser your editor uses (or alternately in an open document) and chose Team and then chose Commit, and who has that much time? Especially when Eclipse has 30-odd items bulging at the seams of every menu and submenu?</p>

<p>For more keyboard shortcuts and general usage on the included bundles, check <a href="http://macromates.com/textmate/manual/bundles" title="Bundles - TextMate Manual">this page</a> of the online manual.</p>

<p>On an off topic, I&#8217;ve started writing my first WordPress plugin, Mobilator, which will generate a mobile version of your site and is fully configurable with custom stylesheet, number of posts visible on main index, number of comments visible on post pages, and custom header and sidebar options (these will have defaults and everything will be resettable) The plugin architecture is pretty cool, though I wish a few more functions were allowed to be overridden, or at least that their outputs could be filtered as well. Namely, I&#8217;d like to filter the entire contents of the header before it spits out a bunch of script tags which are wasting bandwidth on the precious (and not-so-spacious) CDMA connection from my Treo. I can already switch stylesheets by hijacking filtering on &#8220;stylesheet&#8221;, why can&#8217;t I filter the entire head? Anyway so to detect mobile devices I&#8217;ll be using the <a href="http://garetjax.info/projects/browscap/" title="Browscap PHP Project">PHP Browscap</a> class which I&#8217;ve played with before, but as of right now, it&#8217;s not identifying my Treo correctly. I&#8217;ve had brief communications with the author, and he has emailed me back already. Hopefully today (Sunday) I&#8217;ll have time to get in touch with him again and remedy the situation.</p>

<p>Also on an unrelated note, but simply to continue the tally (I swear I&#8217;m going to start scraping it directly pretty soon and build the Dowloads page for this site) my Cricket is at 3267 downloads. Awesome. And someone finally rated it! Yeehaw. Now to make the addition that&#8217;s been suggested.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thynctank.com/mac/2007/04/awesome-macness/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Do The Intel Shuffle</title>
		<link>http://www.thynctank.com/mac/2007/04/do-the-intel-shuffle/</link>
		<comments>http://www.thynctank.com/mac/2007/04/do-the-intel-shuffle/#comments</comments>
		<pubDate>Mon, 09 Apr 2007 08:46:10 +0000</pubDate>
		<dc:creator>thynctank</dc:creator>
				<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://www.thynctank.com/mac/do-the-intel-shuffle</guid>
		<description><![CDATA[Well, since Karen left the office on Friday, I&#8217;ve been given her old Intel MacBook Pro to convert into my new box. I&#8217;m coming from a PowerBook G4 and I didn&#8217;t figure it would be much hassle. It really wasn&#8217;t, but there are some caveats I&#8217;d like to point out to any other souls taking [...]]]></description>
			<content:encoded><![CDATA[<p>Well, since <a href="http://kkitch.com" title="kkitch.com">Karen</a> left the office on Friday, I&#8217;ve been given her old Intel MacBook Pro to convert into my new box. I&#8217;m coming from a PowerBook G4 and I didn&#8217;t figure it would be much hassle. It really wasn&#8217;t, but there are some caveats I&#8217;d like to point out to any other souls taking the plunge into the warm Intel waters.</p>

<p>A number of folks at the office have suggested booting the old laptop in <a href="http://docs.info.apple.com/article.html?artnum=58583">Firewire target disk mode</a> to enable drag and drop of all necessary files, but I&#8217;ve found that permissions bog you down in this setup. A number of important directories will be disabled to you unless you have the same user name and whatever other credentials it needs. In my case, I was moving over from a different login. So I found another way&#8230;</p>

<p>[EDIT: Certain things are missing... Follow the link for more info]</p>

<p><span id="more-14"></span></p>

<p>Rather than boot to target disk mode, I simply enabled Firewire networking (System Preferences-&gt;Network-&gt;Built-in Firewire, set both machines to use DHCP and click the Renew DHCP Lease button) and turned on Personal File Sharing on the old machine. (System Preferences-&gt;Sharing and check Personal File Sharing) The old computer then showed up under Network in Finder and I was able to connect to it as any resource, logging in like I do on the X Serve at work, only using my old login info for the old machine. By authenticating this way, I was given full access to the folders that would otherwise be unavailable to me through target disk mode.</p>

<p>Moving apps over from Applications to Applications was a breeze. There may be a few license numbers I&#8217;ll have to reenter somewhere down the road, but so far I think I&#8217;ve managed to slip past that issue altogether. The key to this (as well as retaining all of your personal data like Firefox (or Safari) bookmarks, Transmit Favorites, et al, is copying over the following two directories as well:
<ul>
    <li>/Users/yourname/Library/Application Support</li>
    <li>/Users/yourname/Library/Preferences</li>
</ul>
Copy both of these directories in full and I believe you&#8217;ll have transferred all your personal data too. (not including any Documents type data, which I don&#8217;t really use much anyway) Obviously transfer over your Documents, Desktop, and whatever other personal folders you use.</p>

<p>I&#8217;ve only used it briefly, but having seen Parallels flying on other workers&#8217; MacBooks and envying them for months, I&#8217;m happy to have made the change. Eclipse boots in no time at all. It&#8217;s like butter.</p>

<p>Will definitely follow up on this in the days/weeks to come.</p>

<p>As a side note, my <a href="http://ubuntu.com" title="Ubuntu Linux">Ubuntu</a> machine at home required a reinstall tonight as I&#8217;d stupidly neglected to document my password and hadn&#8217;t used it in weeks.</p>

<p>[EDIT: The following added Tues, April 10, 2007]
<ul>
    <li>Transmit passwords are lost. If you want to retain Transmit passwords, be sure to export your Favorites from Favorites-&gt;Export (go figure) and then reimport from the similarly-named Import option.</li>
    <li>StumbleUpon &#8220;Send to&#8221; addresses missing as well</li>
    <li>Yahoo Widgets settings were lost, but at least I have the widgets themselves. <a href="http://www.thynctank.com/javascript/2007/04/my-first-widget-cricketchirp">My Cricket</a> is now sitting proud on top of other windows again!</li>
</ul></p>
]]></content:encoded>
			<wfw:commentRss>http://www.thynctank.com/mac/2007/04/do-the-intel-shuffle/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 1.422 seconds -->
