<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CUcFRno5fyp7ImA9WhRaFEw.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263</id><updated>2012-02-16T11:23:37.427-06:00</updated><category term="Code" /><category term="CoffeeScript" /><category term="General" /><category term="Comatose" /><category term="Theme Support" /><category term="Backbone" /><category term="Rails" /><category term="Software" /><category term="Cocoa" /><category term="Comics" /><category term="Misc" /><category term="Nu" /><category term="Movies" /><category term="JavaScript" /><category term="Sports" /><category term="Cartoons" /><category term="default" /><category term="TaskTHIS" /><title>Matt McCray</title><subtitle type="html">Head in the Cloud(s)</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://mattmccray.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>112</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/mattmccray" /><feedburner:info uri="mattmccray" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CEYNRXw4eSp7ImA9WhRQEU4.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-3966145088529001403</id><published>2011-12-05T18:43:00.000-06:00</published><updated>2011-12-05T18:43:14.231-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-05T18:43:14.231-06:00</app:edited><title>Inkwellian Theatre: Minicomic Anthology: Jumblaya! #1</title><content type="html">&lt;a href="http://blog.inkwellian.com/2011/12/minicomic-anthology-jumblaya-1.html?spref=bl"&gt;Inkwellian Theatre: Minicomic Anthology: Jumblaya! #1&lt;/a&gt;: Jumblaya! #1 , a collection of some of my minicomics all bound up in a handy, iPad-ready*, ebook!   52 pages of weirdness and fun! Avail...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-3966145088529001403?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/lsbJs4OqIhq3QyJhVExy0l0OlnI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/lsbJs4OqIhq3QyJhVExy0l0OlnI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/lsbJs4OqIhq3QyJhVExy0l0OlnI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/lsbJs4OqIhq3QyJhVExy0l0OlnI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/3966145088529001403/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2011/12/inkwellian-theatre-minicomic-anthology.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/3966145088529001403?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/3966145088529001403?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/Uso8WhJhT_w/inkwellian-theatre-minicomic-anthology.html" title="Inkwellian Theatre: Minicomic Anthology: Jumblaya! #1" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2011/12/inkwellian-theatre-minicomic-anthology.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUCRXo4fSp7ImA9Wx5UEUo.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-2599389553722899340</id><published>2010-10-15T15:58:00.001-05:00</published><updated>2010-10-15T16:14:24.435-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-15T16:14:24.435-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="Backbone" /><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><title>Simple Todo App using Backbone</title><content type="html">&lt;!-- Generated by Markdown to HTML in MarsEdit --&gt;&lt;p&gt;Here's a quick example I threw together of a simple Todo app using &lt;a href="http://documentcloud.github.com/backbone/"&gt;Backbone.js&lt;/a&gt;. It overrides the &lt;code&gt;Backbone.sync&lt;/code&gt; function to persist the tasks to &lt;code&gt;localStorage&lt;/code&gt;. I tried to keep it simple. &lt;/p&gt;&lt;p&gt;I'd really like any Backbone gurus to have a look and make suggestions (or make their own fork) for better collection/view handling. Or to just rework it to show "best practices."&lt;/p&gt;&lt;p&gt;Some questions I have are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;What's the best way to handle views when the associated model has been destroyed?&lt;/li&gt;&lt;li&gt;Is there a better way to handle collections? (A collection controller perhaps?)&lt;/li&gt;&lt;li&gt;When a collection is refreshed, is it better to blitz the DOM (as this example does) or loop through the models to see if they already have Views and attach/create as needed?&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;It seems most of my questions are related to Views, huh?&lt;/p&gt;&lt;p&gt;Well, I'll continue to experiment and if I come to any conclusions I'll be sure and post them. But if you are, or know, anyone well versed in Backbone (can't be too many people, at this point) I'd really like some feedback.&lt;/p&gt;&lt;p&gt;You can see it below, or &lt;a href="http://jsfiddle.net/darthapo/AFjVP/result/"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Enjoy!&lt;/p&gt;&lt;iframe style="width: 100%; height: 350px" src="http://jsfiddle.net/darthapo/AFjVP/embedded/result,js,html,css"&gt;&lt;/iframe&gt;&lt;!-- Technorati Tags Start --&gt;&lt;p style="display:none;"&gt;Technorati Tags:
&lt;a href="http://technorati.com/tag/javascript" rel="tag"&gt;javascript&lt;/a&gt;, &lt;a href="http://technorati.com/tag/backbone.js" rel="tag"&gt;backbone.js&lt;/a&gt;, &lt;a href="http://technorati.com/tag/jquery" rel="tag"&gt;jquery&lt;/a&gt;&lt;/p&gt;&lt;!-- Technorati Tags End --&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-2599389553722899340?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ljUF4mpnTI1OP1dJQscTf-E_eVo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ljUF4mpnTI1OP1dJQscTf-E_eVo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ljUF4mpnTI1OP1dJQscTf-E_eVo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ljUF4mpnTI1OP1dJQscTf-E_eVo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/2599389553722899340/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2010/10/simple-todo-app-using-backbone.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/2599389553722899340?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/2599389553722899340?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/KICKMrmTUU8/simple-todo-app-using-backbone.html" title="Simple Todo App using Backbone" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2010/10/simple-todo-app-using-backbone.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUUAQX86eip7ImA9Wx5UEUg.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-2649461763012282515</id><published>2010-10-15T09:34:00.000-05:00</published><updated>2010-10-15T09:34:00.112-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-15T09:34:00.112-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="Backbone" /><category scheme="http://www.blogger.com/atom/ns#" term="CoffeeScript" /><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><category scheme="http://www.blogger.com/atom/ns#" term="Code" /><title>Using Backbone.js in CoffeeScript</title><content type="html">&lt;p&gt;If you don't know about &lt;a href="http://jashkenas.github.com/coffee-script/"&gt;CoffeeScript&lt;/a&gt; yet, you need to check it out. Now. -- I love it. It feels as fun and clean as writing in &lt;a href="http://www.ruby-lang.org/en/"&gt;Ruby&lt;/a&gt;, only it compiles to &lt;a href="https://developer.mozilla.org/en/JavaScript"&gt;JavaScript&lt;/a&gt;. That's what you would call "all good." If you were one to use such expressions.&lt;/p&gt;&lt;p&gt;Here's some coffee I created so I could use Backbone classes as native CoffeeScript classes:&lt;/p&gt;&lt;script src="http://gist.github.com/625893.js"&gt;&lt;/script&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-2649461763012282515?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/K0_7wA-abGwahV5AA8_wOhbYZ1A/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/K0_7wA-abGwahV5AA8_wOhbYZ1A/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/K0_7wA-abGwahV5AA8_wOhbYZ1A/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/K0_7wA-abGwahV5AA8_wOhbYZ1A/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/2649461763012282515/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2010/10/using-backbonejs-in-coffeescript.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/2649461763012282515?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/2649461763012282515?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/mN-V5CXKRmE/using-backbonejs-in-coffeescript.html" title="Using Backbone.js in CoffeeScript" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2010/10/using-backbonejs-in-coffeescript.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEYAQH8yeCp7ImA9Wx5UEU0.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-5299640983358766583</id><published>2010-10-14T19:15:00.001-05:00</published><updated>2010-10-14T19:22:21.190-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-14T19:22:21.190-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="Backbone" /><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><title>Apps With Backbone</title><content type="html">&lt;p&gt;I've been working with a lot of &lt;a href="https://developer.mozilla.org/en/JavaScript"&gt;JavaScript&lt;/a&gt; (single page) apps lately. I've found that the primary challenge of JS apps is keeping your data and UI sync'ed up.&lt;/p&gt;&lt;p&gt;There are those who say that attaching the data directly to the DOM is fine... But I'm leery of that. Some browsers (notably IE, of course) tend to leak memory when attaching extraneous data to the DOM. Plus, it just feels wrong. There's a reason "Separation of Concerns" (SoC) is a bit of a mantra.&lt;/p&gt;&lt;p&gt;Ideally you'd want to use something like Cocoa's KVC bindings for your UI. But the two main projects that have that as a goal, &lt;a href="http://www.sproutcore.com/"&gt;SproutCore&lt;/a&gt; and &lt;a href="http://cappuccino.org/"&gt;Cappuccino&lt;/a&gt;, are actually trying to implement the entire Cocoa stack on the web. Cappuccino even goes so far as to create a &lt;a href="http://en.wikipedia.org/wiki/Objective-J"&gt;new language&lt;/a&gt; (sort of) to do so. Which is great, I guess, if you want to invest the time to learn their huge frameworks. (Don't get me started on their lack of decent docs.)&lt;/p&gt;&lt;p&gt;A new option appeared yesterday. &lt;a href="http://www.documentcloud.org/"&gt;DocumentCloud&lt;/a&gt; released an interesting so-called MVC framework named &lt;a href="http://documentcloud.github.com/backbone/"&gt;Backbone.js&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href="http://documentcloud.github.com/backbone/"&gt;&lt;/a&gt;I should mention that it's not actually an MVC framework in the truest sense. It provides Models, Views, and Collections... MVC actually stands for Models, Views, and Controllers. For Controllers, I think &lt;a href="http://code.quirkey.com/sammy/"&gt;Sammy.js&lt;/a&gt; is probably the best Controller framework you'll use.&lt;/p&gt;&lt;p&gt;Why is Backbone interesting? Because it's basically a small framework ﻿(~2Kb) that provides the core pieces of KVO bindings.&lt;/p&gt;&lt;p&gt;It's also built on top of &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; and &lt;a href="http://documentcloud.github.com/underscore/"&gt;underscore.js&lt;/a&gt;. Bonus!&lt;/p&gt;&lt;p&gt;I'm definitely gonna be digging into Backbone and I'll write up my findings and some examples as I go along.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-5299640983358766583?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/t7-BPBGwGORLSUwV04dfwl7qlzM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/t7-BPBGwGORLSUwV04dfwl7qlzM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/t7-BPBGwGORLSUwV04dfwl7qlzM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/t7-BPBGwGORLSUwV04dfwl7qlzM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/5299640983358766583/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2010/10/apps-with-backbone.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/5299640983358766583?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/5299640983358766583?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/rDgdBXf8Szk/apps-with-backbone.html" title="Apps With Backbone" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2010/10/apps-with-backbone.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cMR3k6fSp7ImA9Wx5UEEQ.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-2531338186858374151</id><published>2010-10-14T17:24:00.001-05:00</published><updated>2010-10-14T17:24:46.715-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-14T17:24:46.715-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="General" /><title>Hark! He Posts.</title><content type="html">&lt;p&gt;What's this? Has hell frozen over?&lt;/p&gt;&lt;p&gt;Not exactly. But I am resurrecting my blog. I've included all the old content here to keep some kind of continuity.&lt;/p&gt;&lt;p&gt;I'll be posting my more technical oriented material here. For illustrations, sketchs and other fun stuff, I'll be posting that to &lt;a href="http://www.zoodotcom.com"&gt;zoodotcom.com&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Lately I've been moving more to the JavaScript world, an already familiar place for me. So expect to see some posts about Node.js, Backbone.js, CoffeeScript and other things that catch my fancy.&lt;/p&gt;&lt;p&gt;Cheers!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-2531338186858374151?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gHAXw9XZqlY_8mURXcUgd_TRPuw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gHAXw9XZqlY_8mURXcUgd_TRPuw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gHAXw9XZqlY_8mURXcUgd_TRPuw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gHAXw9XZqlY_8mURXcUgd_TRPuw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/2531338186858374151/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2010/10/hark-he-posts.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/2531338186858374151?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/2531338186858374151?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/50McOb7Ta-E/hark-he-posts.html" title="Hark! He Posts." /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2010/10/hark-he-posts.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4EQXgzfCp7ImA9WxNSGU4.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-4960227630298048045</id><published>2009-09-02T18:43:00.000-05:00</published><updated>2009-09-02T19:48:20.684-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-02T19:48:20.684-05:00</app:edited><title>Coming Soon: TaskTHIS² (A Titanium Application)</title><content type="html">&lt;img align="right" alt="taskthis-icon.png" border="0" height="64" src="http://www.mattmccray.com/images/taskthis-icon.png" width="64" /&gt;

&lt;p&gt;In the next week or so, I'll be releasing the first beta of TaskTHIS&lt;sup&gt;2&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Unlike the original, this version is a cross-platform desktop application. It's being distributed on the &lt;a href="http://www.appcelerator.com/products/titanium-desktop"&gt;Titanium&lt;/a&gt; platform.&lt;/p&gt;

&lt;p&gt;Over the next few weeks I'll discuss the technology behind it (all WebKit based: HTML/JS/CSS). And some of the libraries I built to make development easier (including my &lt;a href="http://gist.github.com/159480"&gt;build script&lt;/a&gt; and a JavaScript class library called &lt;a href="http://github.com/darthapo/klass.js/tree/master"&gt;Klass.js&lt;/a&gt;). So be on the lookout for that!&lt;/p&gt;

&lt;div style="text-align: center;"&gt;&lt;img alt="taskthis2-alpha.png" border="0" height="168" src="http://www.mattmccray.com/images/taskthis2-alpha.png" width="200" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-4960227630298048045?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Rxf6unk0eVUj2CRVsy0Mzmc2tHs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Rxf6unk0eVUj2CRVsy0Mzmc2tHs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Rxf6unk0eVUj2CRVsy0Mzmc2tHs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Rxf6unk0eVUj2CRVsy0Mzmc2tHs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/4960227630298048045/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2009/09/coming-soon-taskthis-titanium.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/4960227630298048045?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/4960227630298048045?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/n_0k2EAbLHE/coming-soon-taskthis-titanium.html" title="Coming Soon: TaskTHIS² (A Titanium Application)" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2009/09/coming-soon-taskthis-titanium.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8AQX07eip7ImA9WxNSGU4.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-9034770966986093867</id><published>2009-05-12T09:12:00.000-05:00</published><updated>2009-09-02T19:47:20.302-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-02T19:47:20.302-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Sports" /><category scheme="http://www.blogger.com/atom/ns#" term="Comics" /><title>Plausible Deniability</title><content type="html">&lt;a href="http://www.flickr.com/photos/darthapo/3520176453/" title="Plausible Deniability by DarthAPO, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3636/3520176453_bef7444cc2_s.jpg" width="75" height="75" alt="Plausible Deniability" align="right" style="margin-left:10px;margin-bottom:10px;"&gt;&lt;/a&gt;

&lt;p&gt;
I’m a fan of the &lt;span class="caps"&gt;NBA&lt;/span&gt;… Most of the time. But I swear, the officiating has been horrible this year. Not just for my team, but all over. It’s enough to make you wonder.&lt;/p&gt;

&lt;p&gt;
Check out my speculation of &lt;a href="http://www.flickr.com/photos/darthapo/3520176453/" title="Be sure and click Flickr's 'All Sizes' to see the bigger version."&gt;what goes on in the &lt;span class="caps"&gt;NBA&lt;/span&gt; league offices&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-9034770966986093867?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ax8xfECXsTj5YD3JnBMy-MVnJ1Y/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ax8xfECXsTj5YD3JnBMy-MVnJ1Y/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ax8xfECXsTj5YD3JnBMy-MVnJ1Y/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ax8xfECXsTj5YD3JnBMy-MVnJ1Y/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/9034770966986093867/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2009/05/plausible-deniability.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/9034770966986093867?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/9034770966986093867?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/Q3UAF4l8w-s/plausible-deniability.html" title="Plausible Deniability" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm4.static.flickr.com/3636/3520176453_bef7444cc2_t.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2009/05/plausible-deniability.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0QDRnc4fip7ImA9WxNSGU4.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-5889477069986868221</id><published>2008-12-11T07:52:00.000-06:00</published><updated>2009-09-02T19:56:17.936-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-02T19:56:17.936-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><title>Liquid.js, A Non-Evaling Template Engine in JavaScript</title><content type="html">&lt;p&gt;Of late, I&amp;#8217;ve needed a robust JavaScript template engine that doesn&amp;#8217;t use &lt;code&gt;eval&lt;/code&gt; (and preferably not &lt;code&gt;with&lt;/code&gt;). Also, I&amp;#8217;ve always liked &lt;a href="http://www.liquidmarkup.org/"&gt;Liquid&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, two plus two equals&amp;#8230; JavaScript! Hah, you thought it was four, didn&amp;#8217;t you? Well, that&amp;#8217;s what you get for thinking.&lt;/p&gt;

&lt;p&gt;Yeah, long story short, I ported Liquid to JavaScript. You can grab it from github (where else?) here: &lt;a href="http://github.com/darthapo/liquid.js"&gt;http://github.com/darthapo/liquid.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m calling this version 0.1. It&amp;#8217;s not battle tested yet, but I know it&amp;#8217;ll work using Firefox 3+, Safari 3+, and Adobe Air 1.1.&lt;/p&gt;

&lt;p&gt;So what are the differences between running the Ruby version and the JavaScript version? Well, as far as the templates themselves, nothing. It&amp;#8217;s a full port, so all of Liquid&amp;#8217;s default tags  and filters are supported in Liquid.js. I even added a placeholder function that you can implement yourself (based on your own needs) to support the &amp;#8216;include&amp;#8217; tag.&lt;/p&gt;

&lt;pre class="textmate-source"&gt;&lt;span class="source source_js"&gt;&lt;span class="meta meta_function meta_function_js"&gt;&lt;span class="support support_class support_class_js"&gt;Liquid&lt;/span&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_js"&gt;readTemplateFile&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_js"&gt;=&lt;/span&gt; &lt;span class="storage storage_type storage_type_function storage_type_function_js"&gt;function&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js"&gt;(&lt;/span&gt;&lt;span class="variable variable_parameter variable_parameter_function variable_parameter_function_js"&gt;path&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js"&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;{&lt;/span&gt;
  &lt;span class="storage storage_type storage_type_js"&gt;var&lt;/span&gt; elem &lt;span class="keyword keyword_operator keyword_operator_js"&gt;=&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_js"&gt;$&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;path&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;
  &lt;span class="keyword keyword_control keyword_control_js"&gt;if&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;elem&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt; &lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;{&lt;/span&gt;
    &lt;span class="keyword keyword_control keyword_control_js"&gt;return&lt;/span&gt; elem&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;innerHTML&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;
  &lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;}&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_js"&gt;else&lt;/span&gt; &lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;{&lt;/span&gt;
    &lt;span class="keyword keyword_control keyword_control_js"&gt;return&lt;/span&gt; path &lt;span class="keyword keyword_operator keyword_operator_js"&gt;+&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js"&gt;"&lt;/span&gt; can't be found.&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt; 
    &lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js"&gt;//&lt;/span&gt; Or throw and error, or whatever you want...
&lt;/span&gt;  &lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;}&lt;/span&gt;
&lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;}&lt;/span&gt;

&lt;span class="storage storage_type storage_type_js"&gt;var&lt;/span&gt; src &lt;span class="keyword keyword_operator keyword_operator_js"&gt;=&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js"&gt;"&lt;/span&gt;{% include 'myOtherTemplate' with current_user %}&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;

&lt;span class="storage storage_type storage_type_js"&gt;var&lt;/span&gt; tmpl &lt;span class="keyword keyword_operator keyword_operator_js"&gt;=&lt;/span&gt; Liquid&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_function support_function_js"&gt;parse&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt; src &lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;

&lt;span class="support support_function support_function_js"&gt;alert&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt; tmpl&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;render&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;{&lt;/span&gt; current_user:&lt;span class="string string_quoted string_quoted_single string_quoted_single_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js"&gt;'&lt;/span&gt;M@&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;}&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;))&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;An easy way to include template in a page is to use &lt;code&gt;script&lt;/code&gt; elements, like this:&lt;/p&gt;

&lt;pre class="textmate-source"&gt;&lt;span class="text text_html text_html_basic"&gt;&lt;span class="comment comment_block comment_block_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_html"&gt;&amp;lt;!--&lt;/span&gt; Browsers ignore script blocks with an unrecognized type.  &lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_html"&gt;--&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="comment comment_block comment_block_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_html"&gt;&amp;lt;!--&lt;/span&gt; Makes for pretty good inline template storage.  &lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_html"&gt;--&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="source source_js source_js_embedded source_js_embedded_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_script entity_name_tag_script_html"&gt;script&lt;/span&gt; &lt;span class="entity entity_other entity_other_attribute-name entity_other_attribute-name_html"&gt;type&lt;/span&gt;=&lt;span class="string string_quoted string_quoted_double string_quoted_double_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_html"&gt;"&lt;/span&gt;text/liquid&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_html"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="meta meta_attribute-with-value meta_attribute-with-value_id meta_attribute-with-value_id_html"&gt;&lt;span class="entity entity_other entity_other_attribute-name entity_other_attribute-name_id entity_other_attribute-name_id_html"&gt;id&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_key-value punctuation_separator_key-value_html"&gt;=&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_html"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_html"&gt;"&lt;/span&gt;&lt;span class="meta meta_toc-list meta_toc-list_id meta_toc-list_id_html"&gt;myOtherTemplate&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_html"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;
  Hello&lt;span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js"&gt;, &lt;/span&gt;&lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;{{&lt;/span&gt; current_user &lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;}}&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_js"&gt;!&lt;/span&gt;
&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="entity entity_name entity_name_tag entity_name_tag_script entity_name_tag_script_html"&gt;script&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_tag punctuation_definition_tag_html"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Currently, Liquid.js requires &lt;a href="http://mootools.net/"&gt;MooTools&lt;/a&gt;. Some of the things I&amp;#8217;d like to polish up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remove MooTools requirement, run entirely independent of any other js library&lt;/li&gt;
&lt;li&gt;Add Rhino for console-based testing&lt;/li&gt;
&lt;li&gt;Test, test, test on Internet &lt;strike&gt;Exploder&lt;/strike&gt; Explorer&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-5889477069986868221?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/U-qKelVp3Esv3QLtODujkzh7P5k/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/U-qKelVp3Esv3QLtODujkzh7P5k/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/U-qKelVp3Esv3QLtODujkzh7P5k/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/U-qKelVp3Esv3QLtODujkzh7P5k/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/5889477069986868221/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2008/12/liquidjs-non-evaling-template-engine-in.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/5889477069986868221?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/5889477069986868221?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/UzD7G8LK69g/liquidjs-non-evaling-template-engine-in.html" title="Liquid.js, A Non-Evaling Template Engine in JavaScript" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2008/12/liquidjs-non-evaling-template-engine-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0QHSX05eyp7ImA9WxNSGU4.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-5194358647514269915</id><published>2008-11-30T15:53:00.000-06:00</published><updated>2009-09-02T19:55:38.323-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-02T19:55:38.323-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><category scheme="http://www.blogger.com/atom/ns#" term="TaskTHIS" /><category scheme="http://www.blogger.com/atom/ns#" term="Rails" /><title>TaskTHIS is Back!</title><content type="html">&lt;img src="http://taskthis.elucidata-apps.com/images/taskthis-logo.jpg" alt="TaskTHIS" align="left" style="margin-right:10px; margin-bottom:5px"/&gt;

&lt;p&gt;&lt;a href="http://taskthis.elucidata-apps.com"&gt;TaskTHIS&lt;/a&gt; is up and running again. Sorry for the downtime, but since I host it for you guys for free, I don't think you can complain too much. :-)&lt;/p&gt;

&lt;p&gt;In the process, it's moved URLs as well. You can now find it at:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://taskthis.elucidata-apps.com"&gt;http://taskthis.elucidata-apps.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="info"&gt;The old URL (taskthis.darthapo.com) should redirect you there automatically.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;I had to convert TaskTHIS from Rails 1.1 to Rails 2.1, which was not too fun. Especially since it had already been converted from pre-1.0 to 1.1. &lt;/p&gt;

&lt;p&gt;Anyway, it's probably still a little rough around the edges, so if you find any bugs please add a post in the &lt;a href="http://support.elucidata-apps.com/"&gt;support forum&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-5194358647514269915?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/z_n8pcOCfm2LdYoLElG5VISpC40/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/z_n8pcOCfm2LdYoLElG5VISpC40/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/z_n8pcOCfm2LdYoLElG5VISpC40/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/z_n8pcOCfm2LdYoLElG5VISpC40/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/5194358647514269915/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2008/11/taskthis-is-back.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/5194358647514269915?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/5194358647514269915?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/AkOoC9a8tyE/taskthis-is-back.html" title="TaskTHIS is Back!" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2008/11/taskthis-is-back.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cMRn8_eSp7ImA9WxNSGU4.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-8449093233931355531</id><published>2008-11-19T11:41:00.000-06:00</published><updated>2009-09-02T19:51:27.141-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-02T19:51:27.141-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><category scheme="http://www.blogger.com/atom/ns#" term="TaskTHIS" /><title>Shuffling Servers</title><content type="html">&lt;p&gt;I'm in the process of shuffling servers around, so a lot of the apps/sites I've created will be down whilst I make the move.&lt;/p&gt;

&lt;p&gt;Some things are already back up: &lt;a href="http://zoodotcom.com"&gt;ZooDotCom&lt;/a&gt; and &lt;a href="http://lilmonstas.com"&gt;Lil Monstas&lt;/a&gt;. Others, like &lt;a href="http://maelstromapp.com"&gt;Maelstrom&lt;/a&gt; and &lt;a href="http://taskthis.darthapo.com"&gt;TaskTHIS&lt;/a&gt; are not.&lt;/p&gt;

&lt;p&gt;In fact, TaskTHIS may take a little while longer to bring back up. I'm going to update it to Rails 2. That having been said, I did make a backup of the database before bringing it down. So when it returns all of your data will still be there.&lt;/p&gt;

&lt;p&gt;Also, I've noticed that I post a lot fewer blog posts these days since I generally vent on my &lt;a href="http://www.twitter.com/darthapo"&gt;Twitter account&lt;/a&gt;, I wind up having not too much left to say. Funny that.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-8449093233931355531?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/AGVY87Lu2Rl58bdKh9avPyk53oc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AGVY87Lu2Rl58bdKh9avPyk53oc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/AGVY87Lu2Rl58bdKh9avPyk53oc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AGVY87Lu2Rl58bdKh9avPyk53oc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/8449093233931355531/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2008/11/shuffling-servers.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/8449093233931355531?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/8449093233931355531?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/L3kntpGP3Nw/shuffling-servers.html" title="Shuffling Servers" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2008/11/shuffling-servers.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0MMRnszfip7ImA9WxNSGU4.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-4471893129330259629</id><published>2008-01-23T11:17:00.001-06:00</published><updated>2009-09-02T19:58:07.586-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-02T19:58:07.586-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><title>Sterling-code.com For Your HTML Slicing Needs!</title><content type="html">&lt;p&gt;&lt;a href="http://www.sterling-code.com"&gt;Sterling Code&lt;/a&gt; can help you get from design to finished HTML quickly.&lt;/p&gt;&lt;p&gt;We specialize in creating semantic, SEO optimized XHTML and HTML for rich emails. Offering competitive rates and quick turn-around, &lt;a href="http://www.sterling-code.com"&gt;check us out&lt;/a&gt;!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-4471893129330259629?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/-Qi6OX5Nue1iNtf3r-HiBZvz9Uk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-Qi6OX5Nue1iNtf3r-HiBZvz9Uk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/-Qi6OX5Nue1iNtf3r-HiBZvz9Uk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-Qi6OX5Nue1iNtf3r-HiBZvz9Uk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/4471893129330259629/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2008/01/sterling-codecom-for-your-html-slicing.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/4471893129330259629?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/4471893129330259629?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/Wyqt-6AOD0Q/sterling-codecom-for-your-html-slicing.html" title="Sterling-code.com For Your HTML Slicing Needs!" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2008/01/sterling-codecom-for-your-html-slicing.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UBQnc6fyp7ImA9WxNSGU4.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-6252205138166979317</id><published>2008-01-18T07:52:00.000-06:00</published><updated>2009-09-02T19:54:13.917-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-02T19:54:13.917-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><category scheme="http://www.blogger.com/atom/ns#" term="Cocoa" /><title>Animating NSViews In RubyCocoa</title><content type="html">&lt;p&gt;Yesterday we talked about how to make nifty &lt;a href="http://mattmccray.com/archive/2008/01/16/Selectable_Toolbar_Icons_in_Ru"&gt;selectable toolbars&lt;/a&gt; like this:&lt;/p&gt;

&lt;p style="text-align:center;"&gt;&lt;img src="http://www.mattmccray.com/images/selectable-toolbar.png" alt="selectable-toolbar.png" border="0" width="366" height="80" /&gt;&lt;/p&gt;

&lt;p&gt;Now let's look at the finishing touch for our Preferences window; Animating the panel changes. We'll be flying through this at a pretty good clip, but don't worry. I'll provide the full source for your inspection.&lt;/p&gt;

&lt;p&gt;First off, let's add some new outlets to our window controller:&lt;/p&gt;

&lt;p&gt;&lt;pre class="textmate-source"&gt;&lt;span class="source source_ruby"&gt;  ib_outlets &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;generalPrefsView&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt;
             &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;advancedPrefsView&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/p&gt;


&lt;img src="http://www.mattmccray.com/images/CustomView.png" alt="CustomView.png" border="0" width="135" height="54" align="right" /&gt;

&lt;p&gt;Now in Interface Builder, we'll create the views for each preference pane by dragging Custom Views from the Library onto our Preferences.nib.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: Be sure to drop the Custom Views on the main nib window in IB, not on the Preferences &lt;code&gt;NSWindow&lt;/code&gt;. Your project (in IB) should look something like this:&lt;/p&gt;

&lt;div style="text-align:center;"&gt;&lt;img src="http://www.mattmccray.com/images/Prefs-IB.png" alt="Prefs-IB.png" border="0" width="385" height="337" /&gt;&lt;/div&gt;

&lt;p&gt;Hook up the outlets to the new views, and edit your preference panels to your heart's desire. From here, we go back to the code.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Tip&lt;/em&gt;: Be sure to set the auto-sizing on your preference panels (the &lt;code&gt;NSView&lt;/code&gt;s) so that it matches the &lt;code&gt;NSWindow&lt;/code&gt;'s &lt;code&gt;contentView&lt;/code&gt;.&lt;/p&gt;

&lt;p style="text-align:center;"&gt;&lt;img src="http://www.mattmccray.com/images/Picture 5.png" alt="Picture 5.png" border="0" width="232" height="120"/&gt;&lt;/p&gt;

&lt;p&gt;Next up are some helper methods for our window controller. I won't spend too much time explaining these, but they're pretty straight forward.&lt;/p&gt;

&lt;p&gt;&lt;pre class="textmate-source"&gt;&lt;span class="source source_ruby"&gt;  &lt;span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;viewForTag&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby"&gt;(&lt;/span&gt;&lt;span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby"&gt;tag&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby"&gt;)&lt;/span&gt;&lt;/span&gt;
    &lt;span class="keyword keyword_control keyword_control_ruby"&gt;case&lt;/span&gt; tag
      &lt;span class="keyword keyword_control keyword_control_ruby"&gt;when&lt;/span&gt; &lt;span class="constant constant_numeric constant_numeric_ruby"&gt;0&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;:&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;[&lt;/span&gt;&lt;span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby"&gt;@&lt;/span&gt;generalPrefsView&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt;  &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;General&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;]&lt;/span&gt;
      &lt;span class="keyword keyword_control keyword_control_ruby"&gt;when&lt;/span&gt; &lt;span class="constant constant_numeric constant_numeric_ruby"&gt;1&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;:&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;[&lt;/span&gt;&lt;span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby"&gt;@&lt;/span&gt;advancedPrefsView&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;Advanced&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;]&lt;/span&gt;
    &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
  &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/p&gt;


&lt;p&gt;&lt;code&gt;#viewForTag&lt;/code&gt; actually returns our &lt;code&gt;NSView&lt;/code&gt; and a title string.&lt;/p&gt;


&lt;p&gt;&lt;pre class="textmate-source"&gt;&lt;span class="source source_ruby"&gt;  &lt;span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;newFrameForNewContentView&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby"&gt;(&lt;/span&gt;&lt;span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby"&gt;view&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby"&gt;)&lt;/span&gt;&lt;/span&gt;
    newFrameRect &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; window&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;frameRectForContentRect&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;view&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;frame&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;
    oldFrameRect &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; window&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;frame
    newSize &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; newFrameRect&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;size
    oldSize &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; oldFrameRect&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;size
    frame &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; window&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;frame
    frame&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;size &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; newSize
    frame&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;origin&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;y &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; frame&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;origin&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;y &lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby"&gt;-&lt;/span&gt; &lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;newSize&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;height &lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby"&gt;-&lt;/span&gt; oldSize&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;height&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;
    frame
  &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;#newFrameForNewContentView&lt;/code&gt; calculates the new frame rectangle for the window based on the new view (preference pane).&lt;/p&gt;

&lt;p&gt;Now we're ready to fill out our &lt;code&gt;selectPrefPanel&lt;/code&gt; action:&lt;/p&gt;

&lt;p&gt;&lt;pre class="textmate-source"&gt;&lt;span class="source source_ruby"&gt;  ib_action &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby entity_name_function"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;selectPrefPanel&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do &lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;sender&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;
    tag &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt;  sender&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;tag
    view&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; title &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="variable variable_language variable_language_ruby"&gt;self&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;viewForTag&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;tag&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;
    previousView&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; prevTitle &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="variable variable_language variable_language_ruby"&gt;self&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;viewForTag&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby"&gt;@&lt;/span&gt;currentViewTag&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;
    &lt;span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby"&gt;@&lt;/span&gt;currentViewTag&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; tag
    newFrame &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="variable variable_language variable_language_ruby"&gt;self&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;newFrameForNewContentView&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;view&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;
    window&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;title &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;&lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;#{&lt;/span&gt;title&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;}&lt;/span&gt;&lt;/span&gt; Preferences&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;
&lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;    &lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt; Using an animation grouping because we may be changing the duration
&lt;/span&gt;    &lt;span class="support support_class support_class_ruby"&gt;NSAnimationContext&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;beginGrouping
&lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;      &lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt; Call the animator instead of the view / window directly
&lt;/span&gt;      window&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;contentView&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;animator&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;replaceSubview_with&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;previousView&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; view&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;
      window&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;animator&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;setFrame_display newFrame&lt;span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby"&gt;,&lt;/span&gt; &lt;span class="constant constant_language constant_language_ruby"&gt;true&lt;/span&gt;
    &lt;span class="support support_class support_class_ruby"&gt;NSAnimationContext&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;endGrouping
  &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;Right on! Now we setup the initial pane when the window loads:&lt;/p&gt;

&lt;p&gt;&lt;pre class="textmate-source"&gt;&lt;span class="source source_ruby"&gt;  &lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;awakeFromNib&lt;/span&gt;&lt;/span&gt;
    window&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;setContentSize &lt;span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby"&gt;@&lt;/span&gt;generalPrefsView&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;frame&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;size 
    window&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;contentView&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;addSubview &lt;span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby"&gt;@&lt;/span&gt;generalPrefsView&lt;/span&gt;
    window&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;title &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;General Preferences&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;
    &lt;span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby"&gt;@&lt;/span&gt;currentViewTag&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="constant constant_numeric constant_numeric_ruby"&gt;0&lt;/span&gt;
&lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;    &lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt; Will use CoreAnimation for the panel changes:
&lt;/span&gt;    window&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;contentView&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;wantsLayer &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="constant constant_language constant_language_ruby"&gt;true&lt;/span&gt;
  &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;That pretty much does it. Now you have a professional looking preferences window. So enough of those dang blasted &lt;code&gt;NSTabView&lt;/code&gt;s!&lt;/p&gt;

&lt;p&gt;Here's the completed &lt;a href="http://pastie.textmate.org/140681"&gt;PreferencesController.rb&lt;/a&gt;. Or, you can download the &lt;a href="http://www.mattmccray.com/downloads/PreferencesExample.zip"&gt;full Xcode project&lt;/a&gt;. (Requires Leopard, Xcode 3, and Interface Builder 3)&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-6252205138166979317?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/JLBJFmS9ppnCOk5QIAhGXNhRFP0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JLBJFmS9ppnCOk5QIAhGXNhRFP0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/JLBJFmS9ppnCOk5QIAhGXNhRFP0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JLBJFmS9ppnCOk5QIAhGXNhRFP0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/6252205138166979317/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2008/01/animating-nsviews-in-rubycocoa.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/6252205138166979317?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/6252205138166979317?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/a0raqIKys8U/animating-nsviews-in-rubycocoa.html" title="Animating NSViews In RubyCocoa" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2008/01/animating-nsviews-in-rubycocoa.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMCR3Y4fCp7ImA9Wx5UEU0.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-3857696334303185907</id><published>2008-01-16T06:10:00.000-06:00</published><updated>2010-10-14T20:51:06.834-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-14T20:51:06.834-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><category scheme="http://www.blogger.com/atom/ns#" term="Cocoa" /><title>Selectable Toolbar Icons in RubyCocoa</title><content type="html">&lt;p&gt;So you'd like to have some nifty selectable toolbar items to make your preferences window really polished? Or maybe you'd like to use the toolbar as a tab-set like &lt;a href="http://www.panic.com/coda/"&gt;Coda&lt;/a&gt; does. No problem, here's how to do it.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: I'm using Leopard &amp; Interface Builder 3. You can create selectable toolbars in Tiger, but the process is different and not within the scope of this article.&lt;/p&gt;&lt;p&gt;To start, in the window controller, add an &lt;code&gt;ib_action:&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;pre class="textmate-source"&gt;&lt;span class="source source_ruby"&gt;ib_action &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;selectPrefPaneldo&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;sender&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;&lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt; We'll do stuff here later...
&lt;/span&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;Then in Interface Builder, create the toolbar and the toolbar items. For each toolbar item:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Turn off the 'autovalidates' option&lt;/li&gt;&lt;li&gt;Set the action to target the &lt;code&gt;selectPrefPanel:&lt;/code&gt; action on your window controller (probably the File's Owner)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Before you save the Nib, be sure and set the toolbar's &lt;code&gt;delegate&lt;/code&gt; to the window controller.&lt;/p&gt;&lt;p&gt;Now back in the window controller code, implement a &lt;code&gt;toolbarSelectableItemIdentifiers&lt;/code&gt; method in your controller:&lt;/p&gt;&lt;p&gt;&lt;pre class="textmate-source"&gt;&lt;span class="source source_ruby"&gt;&lt;span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt;&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;toolbarSelectableItemIdentifiers&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby"&gt;(&lt;/span&gt;&lt;span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby"&gt;toolbar&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby"&gt;@&lt;/span&gt;toolbaridents&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby"&gt;||=&lt;/span&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;begin&lt;/span&gt;
    window&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;toolbar&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;toolbaritems&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;collect &lt;span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby"&gt;{&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;i&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt; i&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;itemIdentifier &lt;span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby"&gt;}&lt;/span&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;Lastly, when the window loads, select the first toolbar item:&lt;/p&gt;&lt;p&gt;&lt;pre class="textmate-source"&gt;&lt;span class="source source_ruby"&gt;&lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt;&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;awakeFromNib&lt;/span&gt;&lt;/span&gt;
  window&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;toolbar&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;selectedItemIdentifier &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; window&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;toolbar&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;toolbarItems&lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;[&lt;/span&gt;&lt;span class="constant constant_numeric constant_numeric_ruby"&gt;0&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;]&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;itemIdentifier
&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;Viola! Now you have selectable toolbar items.&lt;/p&gt;&lt;p&gt;Here's the &lt;a href="http://pastie.textmate.org/140682"&gt;&lt;strong&gt;full source&lt;/strong&gt; for the window controller&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;It's worth mentioning that this isn't specific to RubyCocoa. You can do the same thing in Objective-C, Python, or Nu (&lt;a href="http://pastie.textmate.org/139630"&gt;example&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;Next, I'll show you how to create the views that will go within your preferences window, and how to animate them to really finish it off.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Update&lt;/em&gt;: Find the next article &lt;a href="http://mattmccray.com/archive/2008/01/18/Animating_NSViews_In_RubyCocoa"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-3857696334303185907?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/LmGsfE6aisWTzGhRPpq2FsqMpJU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LmGsfE6aisWTzGhRPpq2FsqMpJU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/LmGsfE6aisWTzGhRPpq2FsqMpJU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LmGsfE6aisWTzGhRPpq2FsqMpJU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/3857696334303185907/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2008/01/selectable-toolbar-icons-in-rubycocoa.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/3857696334303185907?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/3857696334303185907?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/eYjoO7bY4bs/selectable-toolbar-icons-in-rubycocoa.html" title="Selectable Toolbar Icons in RubyCocoa" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2008/01/selectable-toolbar-icons-in-rubycocoa.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUABQnY6fip7ImA9Wx5UEU0.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-1254381657555933769</id><published>2008-01-15T15:49:00.000-06:00</published><updated>2010-10-14T20:55:53.816-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-14T20:55:53.816-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><category scheme="http://www.blogger.com/atom/ns#" term="Nu" /><title>Nuapp</title><content type="html">&lt;p&gt;Nuapp is a simple script (written in &lt;a href="http://programming.nu"&gt;Nu&lt;/a&gt;, of course) that generates a skeleton Nu application. Check it out here: &lt;a href="http://pastie.textmate.org/138976"&gt;http://pastie.textmate.org/138976&lt;/a&gt;&lt;/p&gt;&lt;p&gt;You'll probably want to customize it. For instance, I doubt you'll want to use my "Requisite Beta Disclaimer". :-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-1254381657555933769?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/vuu4-LHosTYlbNhssDzXhT2jY6A/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/vuu4-LHosTYlbNhssDzXhT2jY6A/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/vuu4-LHosTYlbNhssDzXhT2jY6A/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/vuu4-LHosTYlbNhssDzXhT2jY6A/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/1254381657555933769/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2008/01/nuapp.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/1254381657555933769?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/1254381657555933769?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/Qt9XMVkBo7I/nuapp.html" title="Nuapp" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2008/01/nuapp.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8EQns5eSp7ImA9Wx5UEU0.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-1429922554508175439</id><published>2008-01-14T14:06:00.000-06:00</published><updated>2010-10-14T20:56:43.521-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-14T20:56:43.521-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><category scheme="http://www.blogger.com/atom/ns#" term="Cocoa" /><category scheme="http://www.blogger.com/atom/ns#" term="Nu" /><title>Snippet: Compiling XIBs into NIBs in your Nukefile</title><content type="html">&lt;p&gt;Here's a function I use in my Nukefile to compile XIBs into NIBs:&lt;/p&gt;&lt;p&gt;&lt;pre class="textmate-source"&gt;&lt;span class="source source_nu"&gt;(&lt;span class="meta meta_function meta_function_nu"&gt;&lt;span class="storage storage_type storage_type_function-type storage_type_function-type_nu"&gt;function&lt;/span&gt;&lt;span class="entity entity_name entity_name_function entity_name_function_nu"&gt;compile-xibs-from-to&lt;/span&gt;&lt;/span&gt; (xibs to_path)&lt;br/&gt;(&lt;span class="keyword keyword_control keyword_control_nu"&gt;if&lt;/span&gt; (&lt;span class="keyword keyword_operator keyword_operator_nu"&gt;and&lt;/span&gt; (!= target &lt;span class="string string_quoted string_quoted_double string_quoted_double_nu"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_nu"&gt;"&lt;/span&gt;clobber&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_nu"&gt;"&lt;/span&gt;&lt;/span&gt;) (!= target &lt;span class="string string_quoted string_quoted_double string_quoted_double_nu"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_nu"&gt;"&lt;/span&gt;clean&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_nu"&gt;"&lt;/span&gt;&lt;/span&gt;))&lt;br/&gt;(&lt;span class="keyword keyword_control keyword_control_nu"&gt;then&lt;/span&gt;&lt;br/&gt;(SH &lt;span class="string string_quoted string_quoted_double string_quoted_double_nu"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_nu"&gt;"&lt;/span&gt;mkdir -p #{to_path}&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_nu"&gt;"&lt;/span&gt;&lt;/span&gt;)&lt;br/&gt;((filelist xibs) each:(&lt;span class="keyword keyword_control keyword_control_nu"&gt;do&lt;/span&gt; (xib)&lt;br/&gt;(&lt;span class="keyword keyword_control keyword_control_nu"&gt;set&lt;/span&gt; nib (xib stringByReplacingPathExtensionWith:&lt;span class="string string_quoted string_quoted_double string_quoted_double_nu"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_nu"&gt;"&lt;/span&gt;nib&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_nu"&gt;"&lt;/span&gt;&lt;/span&gt;))&lt;br/&gt;(SH &lt;span class="string string_quoted string_quoted_double string_quoted_double_nu"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_nu"&gt;"&lt;/span&gt;ibtool #{xib} --compile #{to_path}/#{( nib fileName )}&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_nu"&gt;"&lt;/span&gt;&lt;/span&gt;)))&lt;br/&gt;(filelist &lt;span class="string string_quoted string_quoted_double string_quoted_double_nu"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_nu"&gt;"&lt;/span&gt;^#{to_path}/[^/]*&lt;span class="constant constant_character constant_character_escape constant_character_escape_nu"&gt;.&lt;/span&gt;nib$&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_nu"&gt;"&lt;/span&gt;&lt;/span&gt;))&lt;br/&gt;(&lt;span class="keyword keyword_control keyword_control_nu"&gt;else&lt;/span&gt;&lt;span class="constant constant_language constant_language_nu"&gt;nil&lt;/span&gt;)))  (&lt;span class="keyword keyword_control keyword_control_nu"&gt;set&lt;/span&gt; @nib_files (compile-xibs-from-to &lt;span class="string string_quoted string_quoted_double string_quoted_double_nu"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_nu"&gt;"&lt;/span&gt;^resources/views/[^/]*&lt;span class="constant constant_character constant_character_escape constant_character_escape_nu"&gt;.&lt;/span&gt;xib$&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_nu"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="string string_quoted string_quoted_double string_quoted_double_nu"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_nu"&gt;"&lt;/span&gt;build/nibs&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_nu"&gt;"&lt;/span&gt;&lt;/span&gt;))&lt;/span&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;It uses &lt;code&gt;ibtool&lt;/code&gt; to compile the .xib into a .nib:&lt;/p&gt;&lt;p&gt;&lt;pre class="console"&gt;ibtool source.xib --compile target.nib&lt;/pre&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-1429922554508175439?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/IswPhe2owcY6W3ARP8hwIrLA4k8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/IswPhe2owcY6W3ARP8hwIrLA4k8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/IswPhe2owcY6W3ARP8hwIrLA4k8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/IswPhe2owcY6W3ARP8hwIrLA4k8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/1429922554508175439/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2008/01/snippet-compiling-xibs-into-nibs-in.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/1429922554508175439?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/1429922554508175439?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/bPIadQVmgHI/snippet-compiling-xibs-into-nibs-in.html" title="Snippet: Compiling XIBs into NIBs in your Nukefile" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2008/01/snippet-compiling-xibs-into-nibs-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4AR3o-fyp7ImA9Wx5UEU0.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-1973371820707160422</id><published>2007-10-25T09:19:00.000-05:00</published><updated>2010-10-14T20:59:06.457-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-14T20:59:06.457-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Comatose" /><category scheme="http://www.blogger.com/atom/ns#" term="Comics" /><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><category scheme="http://www.blogger.com/atom/ns#" term="Rails" /><title>AJAX Is X-TREME!</title><content type="html">&lt;div class="update"&gt;&lt;p&gt;&lt;strong&gt;Author&amp;#8217;s Note&lt;/strong&gt;: I actually wrote this back in 2006, but it kind of fell through the cracks. So I present it now, for your amusement/pleasure/whatever&amp;#8230;&lt;/p&gt;&lt;/div&gt;
The term &lt;acronym title="No matter how hard I try, I can't write 'Web 2.0' without quotes!"&gt;&amp;#8220;Web 2.0&amp;#8221;&lt;/acronym&gt; has become synonymous with &lt;span class="caps"&gt;AJAX&lt;/span&gt;. With the hype and buzz that&amp;#8217;s surrounded &lt;acronym title="See?"&gt;&amp;#8220;Web 2.0&amp;#8221;&lt;/acronym&gt;, people seem to invent reasons for using it. Even when it makes no sense. Sometimes &lt;em&gt;especially&lt;/em&gt; when it makes no sense. Just because it&amp;#8217;s &amp;#8220;cool!&amp;#8221; 
&lt;p style="text-align:center;"&gt;&lt;img src="http://mattmccray.com/images/ajax-strip-one.jpg" style="border:0px solid" title="ZooDotCom Presents - AJAX is X-TREME!!!" alt="ZooDotCom Presents - AJAX is X-TREME!!!" class="pivot-image" /&gt;&lt;/p&gt;&lt;br/&gt;Oh yes, &lt;span class="caps"&gt;AJAX&lt;/span&gt; is cool. It can really enhance the user experience of your application. And yes, you can do some interesting &lt;a href="http://trimpath.com/project/wiki/SinglePageApplications"&gt;single page applications&lt;/a&gt; that &lt;a href="http://www.tiddlywiki.com/"&gt;don&amp;#8217;t require a server&lt;/a&gt;. But hopefully you&amp;#8217;re not quite as &lt;em&gt;gung-ho&lt;/em&gt; about it as Charlie here (from the comic above).
&lt;a href="http://www.rubyonrails.com"&gt;Rails&lt;/a&gt; makes it easy to use &lt;span class="caps"&gt;AJAX&lt;/span&gt;. Really easy. Too easy? Perhaps. And occasionally even I&amp;#8217;ve been sucked into the trap of throwing out a quick, AJAXified, solution rather than taking the time to build it right, to build it &lt;em&gt;compatible&lt;/em&gt; with the &amp;#8220;Web 1.0&amp;#8221; (or non-JavaScript enabled) folks. But I shouldn&amp;#8217;t have. And neither should you.

&lt;p style="text-align:center;"&gt;&lt;img src="http://mattmccray.com/images/ajax-strip-two.jpg" style="border:0px solid" title="ZooDotCom Presents - Fine, then how do I it?!" alt="ZooDotCom Presents - Fine, then how do I it?!" class="pivot-image" /&gt;&lt;/p&gt;&lt;p&gt;That, Charlie, is a good question.
In my next post I&amp;#8217;ll talk a bit about &lt;a href="http://comatose.rubyforge.org"&gt;Comatose&lt;/a&gt;, and how I went about ensuring that it&amp;#8217;s backward compatible with non-JavaScript enabled browsers.&lt;/p&gt;&lt;div class="update"&gt;&lt;p&gt;&lt;strong&gt;Author&amp;#8217;s Other Note&lt;/strong&gt;: I will post the second part to this soon&amp;#8230; Probably next week. Cheers.&lt;/p&gt;&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-1973371820707160422?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/FGjiFdVIb3Lnf1Eyrkssi7SWsTw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FGjiFdVIb3Lnf1Eyrkssi7SWsTw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/FGjiFdVIb3Lnf1Eyrkssi7SWsTw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FGjiFdVIb3Lnf1Eyrkssi7SWsTw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/1973371820707160422/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2007/10/ajax-is-x-treme.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/1973371820707160422?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/1973371820707160422?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/SW6u4wuJXJQ/ajax-is-x-treme.html" title="AJAX Is X-TREME!" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2007/10/ajax-is-x-treme.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcFSHs-eSp7ImA9Wx5UEU0.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-6778886007083288972</id><published>2007-08-17T20:21:00.000-05:00</published><updated>2010-10-14T21:00:19.551-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-14T21:00:19.551-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Comics" /><title>R.I.P. Mr. Wieringo</title><content type="html">&lt;p&gt;&lt;a href="http://www.mikewieringo.com"&gt;&lt;p style="text-align:center;"&gt;&lt;img src="http://mattmccray.com/images/rip-wieringo.jpg" style="border:0px solid" title="R.I.P. Mr. Wieringo" alt="R.I.P. Mr. Wieringo" class="pivot-image" /&gt;&lt;/a&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-6778886007083288972?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/4gY6zvVuuljhmCSwq3pYGmIAItY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4gY6zvVuuljhmCSwq3pYGmIAItY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/4gY6zvVuuljhmCSwq3pYGmIAItY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4gY6zvVuuljhmCSwq3pYGmIAItY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/6778886007083288972/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2007/08/rip-mr-wieringo.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/6778886007083288972?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/6778886007083288972?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/0NJ7hr6O2W8/rip-mr-wieringo.html" title="R.I.P. Mr. Wieringo" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2007/08/rip-mr-wieringo.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYCRnk5eyp7ImA9Wx5UEU0.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-1439693553758674931</id><published>2007-06-29T08:04:00.000-05:00</published><updated>2010-10-14T21:02:47.723-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-14T21:02:47.723-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Comatose" /><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><category scheme="http://www.blogger.com/atom/ns#" term="Rails" /><title>Comatose 0.8.1</title><content type="html">&lt;p&gt;It&amp;#8217;s been a long time coming, but it&amp;#8217;s finally here: &lt;a href="http://mattmccray.com/svn/rails/plugins/comatose"&gt;Comatose 0.8.1&lt;/a&gt;!&lt;/p&gt;&lt;p&gt;Over the next few days, I&amp;#8217;ll be transitioning the project to &lt;a href="http://code.google.com/p/comatose-plugin"&gt;Google Code&lt;/a&gt; and &lt;a href="http://groups.google.com/group/comatose-plugin"&gt;Google Groups&lt;/a&gt; please start using them for reporting bugs and such. Here are the important URLs:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/comatose-plugin"&gt;http://code.google.com/p/comatose-plugin&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://groups.google.com/group/comatose-plugin"&gt;http://groups.google.com/group/comatose-plugin&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I&amp;#8217;ve also updated the &lt;a href="http://comatose.rubyforge.org/getting-started-01.html"&gt;docs&lt;/a&gt; to reflect the new 0.8+ way of doing things. They&amp;#8217;ll wind up on the &lt;a href="http://code.google.com/p/comatose-plugin/w/list"&gt;wiki&lt;/a&gt; so that they&amp;#8217;ll be easily maintained by all.&lt;/p&gt;&lt;p&gt;From the changelog:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;All includes and helpers are loaded at the end of the &lt;code&gt;ComatoseController&lt;/code&gt; and &lt;code&gt;ComatoseAdminController&lt;/code&gt; classes&lt;/li&gt;&lt;li&gt;Fixed the &lt;code&gt;ComatoseController#show&lt;/code&gt; action to correctly send an HTTP status of 404 even if it finds, and renders, a page at &amp;#8216;/404&amp;#8217;&lt;/li&gt;&lt;li&gt;Fixed the migration to default a page&amp;#8217;s &lt;code&gt;full_path&lt;/code&gt; to &amp;#8221; instead of null&lt;/li&gt;&lt;li&gt;Formalized &lt;code&gt;ComatoseDrops&lt;/code&gt;. Use &lt;code&gt;Comatose.define_drop "drop_name", do ... end&lt;/code&gt;. Every method within that block should return a value for use with a Liquid and/or ERB template. Usage in a comatose page: &lt;code&gt;{{ drop_name.def_name }}&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Added support for a &lt;code&gt;config.after_setup&lt;/code&gt; block that gets called after Comatose is setup (in the &lt;code&gt;Dispatcher#to_prepare&lt;/code&gt; event)&lt;/li&gt;&lt;li&gt;Added HTML comment output for calls that result in a &lt;code&gt;method_missing&lt;/code&gt; on the &lt;code&gt;ProcessingContext&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Updated page tree to remember collapsed/expanded nodes between page visits&lt;/li&gt;&lt;li&gt;Fixed some errors that were caused by null revisions (usually happened after initial installation)&lt;/li&gt;&lt;li&gt;Added my javascript test_runner lib for testing slugs generated by JavaScript. More JS tests to come.&lt;/li&gt;&lt;li&gt;Bugfix #8640 (rubyforge bug)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;For more see the &lt;a href="http://comatose.rubyforge.org"&gt;devblog&lt;/a&gt;&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-1439693553758674931?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/HFLqDgyrUowzX-fqSJdKKbEhgF4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HFLqDgyrUowzX-fqSJdKKbEhgF4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/HFLqDgyrUowzX-fqSJdKKbEhgF4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HFLqDgyrUowzX-fqSJdKKbEhgF4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/1439693553758674931/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2007/06/comatose-081.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/1439693553758674931?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/1439693553758674931?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/l09D-ewJw6Q/comatose-081.html" title="Comatose 0.8.1" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2007/06/comatose-081.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUGSH4-cCp7ImA9Wx5UEU0.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-608625250715713706</id><published>2007-02-19T11:42:00.000-06:00</published><updated>2010-10-14T21:03:49.058-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-14T21:03:49.058-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><category scheme="http://www.blogger.com/atom/ns#" term="Rails" /><title>Sorta Nested Layouts</title><content type="html">&lt;p&gt;I was playing around with layouts in Rails the other day&amp;#8230; I know, clearly I have too much time on my hands. But anyway, I found that you can fake a nested layout scheme in Rails by delegating view rendering to partials. As an added bonus, you don&amp;#8217;t need to hack around with any of Rails&amp;#8217; internals to make it work.&lt;/p&gt;&lt;p&gt;For example, let&amp;#8217;s say I&amp;#8217;m working on an application that has both a public layout and an admin layout. The &lt;em&gt;public&lt;/em&gt; layout consists of tabs and a sidebar. The &lt;em&gt;admin&lt;/em&gt; layout has different tabs and no sidebar at all. Both layouts share a site header graphic.&lt;/p&gt;&lt;p&gt;With that in mind, here&amp;#8217;s how we could structure our layouts and partials:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;app/views/layouts/application.rhtml&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;Layout Example&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div id="header"&amp;gt;&amp;lt;!-- shared header code --&amp;gt;&amp;lt;/div&amp;gt;

&lt;b&gt;&amp;lt;%= render :partial=&amp;gt;"layouts/#{controller.sub_layout}" %&amp;gt;&lt;/b&gt;

&amp;lt;div id="footer&amp;gt;&amp;lt;!-- shared footer code --&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: I&amp;#8217;m getting the partial name from a controller method named &lt;code&gt;sub_layout&lt;/code&gt;. I&amp;#8217;ll explain that bit in just minute&amp;#8212;In the meantime, knowing that it&amp;#8217;ll return either &amp;#8216;public&amp;#8217; or &amp;#8216;admin&amp;#8217; is enough.&lt;/p&gt;&lt;p&gt;You&amp;#8217;ll notice I don&amp;#8217;t have a call to &lt;code&gt;&amp;lt;%= yield %&amp;gt;&lt;/code&gt; in the layout itself&amp;#8230;&lt;/p&gt;&lt;p&gt;So then, your partials (or sub layouts) will look something like this:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;app/views/layouts/_public.rhtml&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;
&amp;lt;div id="tabs"&amp;gt;&amp;lt;!-- public tabset --&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;div id="public-content"&amp;gt;
&amp;lt;div id="sidebar"&amp;gt;
&amp;lt;!-- sidebar content here --&amp;gt;
&amp;lt;/div&amp;gt;
&lt;b&gt;&amp;lt;%= yield %&amp;gt;&lt;/b&gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;app/views/layouts/_admin.rhtml&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;
&amp;lt;div id="tabs"&amp;gt;&amp;lt;!-- admin tabset --&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;div id="admin-content"&amp;gt;
&lt;b&gt;&amp;lt;%= yield %&amp;gt;&lt;/b&gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;&lt;p&gt;Ah, there&amp;#8217;s the &lt;code&gt;&amp;lt;%= yield %&amp;gt;&lt;/code&gt;! That&amp;#8217;s how you can delegate the view rendering. Basically, you&amp;#8217;re using a partial to wrap &lt;span class="caps"&gt;HTML&lt;/span&gt; around the call to &lt;code&gt;&amp;lt;%= yield %&amp;gt;&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;OK, in the &lt;code&gt;application.rhtml&lt;/code&gt; listing above, I get the partial that works as a sub layout from the controller. To hook that up, in your &lt;code&gt;ApplicationController&lt;/code&gt;, you can specify a default sub layout like this:&lt;/p&gt;&lt;pre&gt;
class ApplicationController &amp;lt; BaseController

# .. your actions

def &lt;b&gt;sub_layout&lt;/b&gt;
"public"
end

end
&lt;/pre&gt;&lt;p&gt;Then in any administrative controllers, you can override it:&lt;/p&gt;&lt;pre&gt;
class UsersController &amp;lt; ApplicationController

# .. your admin-like actions

def sub_layout
&lt;b&gt;"admin" &lt;/b&gt;
end

end
&lt;/pre&gt;&lt;p&gt;I went ahead a threw together a little example application to better illustrate:&lt;/p&gt;&lt;div style="padding-left:10px"&gt;&lt;p&gt;&lt;a href="http://www.mattmccray.com/downloads/sublayout_example.zip"&gt;&lt;b&gt;sublayout_example.zip&lt;/b&gt;&lt;/a&gt; (68 Kb)&lt;/p&gt;&lt;/div&gt;&lt;p&gt;Perhaps the example of different tabs and sidebars isn&amp;#8217;t most compelling reason to use sub layouts&amp;#8212;Which is fine. The &lt;strong&gt;key point&lt;/strong&gt; to all of this is that you can delegate the rendering of your view from a layout to a partial. Which I&amp;#8217;m sure you can leverage in all kinds of cool ways&amp;#8230;&lt;/p&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-608625250715713706?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/0cMAWpH7JHSfKo4UJgsBg4SFy9c/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0cMAWpH7JHSfKo4UJgsBg4SFy9c/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/0cMAWpH7JHSfKo4UJgsBg4SFy9c/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0cMAWpH7JHSfKo4UJgsBg4SFy9c/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/608625250715713706/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2007/02/sorta-nested-layouts.html#comment-form" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/608625250715713706?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/608625250715713706?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/PUG4MEP-x60/sorta-nested-layouts.html" title="Sorta Nested Layouts" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>6</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2007/02/sorta-nested-layouts.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQEQ3wzcSp7ImA9Wx5UEU0.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-936533941480940691</id><published>2007-01-30T12:31:00.000-06:00</published><updated>2010-10-14T21:05:02.289-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-14T21:05:02.289-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Comatose" /><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><category scheme="http://www.blogger.com/atom/ns#" term="Rails" /><title>Comatose 0.8 Released</title><content type="html">&lt;p&gt;Tada! Comatose &lt;em&gt;finally&lt;/em&gt; supports Rails 1.2!&lt;/p&gt;&lt;p&gt;In fact, it &lt;em&gt;only&lt;/em&gt; supports Rails 1.2 now. If you are still on Rails 1.1, &lt;strong&gt;don&amp;#8217;t&lt;/strong&gt; upgrade Comatose &amp;#8212; It won&amp;#8217;t work. Consider yourself warned. (&lt;a href="http://mattmccray.com/svn/rails/plugins/tags/comatose_0-7-1/"&gt;version 0.7.1&lt;/a&gt; is tagged, so all you Rails 1.1ers can still get to it)&lt;/p&gt;&lt;p&gt;OK, so I made quite a few changes whilst upgrading Comatose. No functionality was removed, yet, but enough has changed that we should hit the high points here&amp;#8230; I&amp;#8217;ll post a more in-depth article on the &lt;a href="http://comatose.rubyforge.org/dev-blog.html"&gt;dev blog&lt;/a&gt; later.&lt;/p&gt;&lt;p&gt;First up, there&amp;#8217;s a &lt;strong&gt;new configuration system&lt;/strong&gt;. It&amp;#8217;s quite dandy, really. It single-handedly made the &lt;code&gt;DEFER_COMATOSE_LOAD&lt;/code&gt; and controller class hacking &lt;em&gt;obsolete&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;You can still use all the same old settings, only you set them in a configuration block in your &lt;code&gt;environment.rb&lt;/code&gt; now. Here&amp;#8217;s an example from an app I&amp;#8217;m currently working on:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Comatose.configure do |comatose|
  comatose.includes &amp;lt;&amp;lt; :authenticated_system
  comatose.helpers &amp;lt;&amp;lt;  :application_helper
  # admin
  comatose.admin_title = "My App's CMS"
  comatose.admin_sub_title = "... its' fun for the whole family!"
  comatose.admin_includes &amp;lt;&amp;lt; :authenticated_system
  comatose.admin_helpers &amp;lt;&amp;lt; :application_helper
  comatose.admin_authorization = :admin_required
  comatose.default_tree_level = 1
  comatose.admin_get_author do
    current_user.login
  end
  comatose.admin_get_root_page do
    roots = %w(public-root content-fragments)
    roots.collect {|path| Comatose::Page.find_by_path(path)}
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Look over that example closely, there&amp;#8217;s a lot hidden in there.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;comatose.includes&lt;/code&gt; is an array of module names (as symbols) that will be included in the &lt;code&gt;ComatoseController&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code&gt;comatose.helpers&lt;/code&gt; is also an array of module names, only these are loaded as &lt;a href="http://api.rubyonrails.com/classes/ActionController/Helpers/ClassMethods.html#M000164"&gt;helpers&lt;/a&gt; so you can use them in a view, most likely in your layout.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Remember, you &lt;strong&gt;no longer extend &lt;code&gt;ComatoseController&lt;/code&gt;&lt;/strong&gt; to add functionality.
* All that holds true for &lt;code&gt;ComatoseAdminController&lt;/code&gt; and the &lt;code&gt;comatose.admin_includes&lt;/code&gt; and &lt;code&gt;comatose.admin_helpers&lt;/code&gt; as well.
* &lt;code&gt;comatose.admin_get_author&lt;/code&gt; and &lt;code&gt;comatose.admin_get_root_page&lt;/code&gt; both accept a block of code that should return the author and root_page respectively.&lt;/p&gt;&lt;p&gt;You can use any default controller method, as well as methods from included modules
* &lt;code&gt;comatose.admin_authorization&lt;/code&gt; is using a method from an included module directly, the &lt;code&gt;:admin_required&lt;/code&gt; method from the &lt;code&gt;AuthenticatedSystem&lt;/code&gt; module.&lt;/p&gt;&lt;p&gt;The options that accept blocks will also accept symbols representing module methods.
* Have a look at the &lt;a href="http://mattmccray.com/svn/rails/plugins/comatose/lib/comatose/configuration.rb"&gt;config class&lt;/a&gt; for all the options&lt;/p&gt;&lt;p&gt;Also, there are &lt;strong&gt;unit tests&lt;/strong&gt;  now. Yay!&lt;/p&gt;&lt;p&gt;You can get an overview of the &lt;a href="http://mattmccray.com/svn/rails/plugins/comatose/SPECS"&gt;coverage&lt;/a&gt;, if you like. Oh, using &lt;code&gt;rake test:plugins&lt;/code&gt; doesn&amp;#8217;t work, to run them you will need to change into the &lt;code&gt;vendor/plugins/comatose&lt;/code&gt; directory and run &lt;code&gt;rake&lt;/code&gt;, &lt;em&gt;after&lt;/em&gt; you&amp;#8217;ve run the Comatose migrations.&lt;/p&gt;&lt;p&gt;From the &lt;a href="http://mattmccray.com/svn/rails/plugins/comatose/CHANGELOG"&gt;CHANGELOG&lt;/a&gt;:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Now ONLY supports Rails 1.2 (not even tested in Rails 1.1)&lt;/li&gt;&lt;li&gt;New configuration system&lt;/li&gt;&lt;li&gt;DEFER&lt;em&gt;COMATOSE&lt;/em&gt;LOAD is gone &amp;#8212; Using Dispatcher.to_prepare replaces it&lt;/li&gt;&lt;li&gt;You no longer extend the base classes to add functionality. You configure Comatose to include modules and send it symbols for providing said functionality. e.g. Comatose.config.includes &amp;lt;&amp;lt; :authentiation&lt;em&gt;system; Comatose.config.authorization = :require&lt;/em&gt;login&lt;/li&gt;&lt;li&gt;The automatic loading of RAILS_ROOT/lib/comatose/*.rb files is NO longer supported.&lt;/li&gt;&lt;li&gt;In addition to mapping comatose&lt;em&gt;root in your routes.rb, you&amp;#8217;ll want to map.comatose&lt;/em&gt;admin as well&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Obviously, if you have any issues with this version, please let me know.&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-936533941480940691?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/vH2mMgMh7U019J2j5ZO3IkmvapA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/vH2mMgMh7U019J2j5ZO3IkmvapA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/vH2mMgMh7U019J2j5ZO3IkmvapA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/vH2mMgMh7U019J2j5ZO3IkmvapA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/936533941480940691/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2007/01/comatose-08-released.html#comment-form" title="12 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/936533941480940691?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/936533941480940691?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/6o3wM4vNOyU/comatose-08-released.html" title="Comatose 0.8 Released" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>12</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2007/01/comatose-08-released.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMMRX09fSp7ImA9Wx5UEU0.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-828167961684894778</id><published>2007-01-22T23:12:00.000-06:00</published><updated>2010-10-14T21:08:04.365-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-14T21:08:04.365-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Theme Support" /><category scheme="http://www.blogger.com/atom/ns#" term="Comatose" /><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><category scheme="http://www.blogger.com/atom/ns#" term="TaskTHIS" /><category scheme="http://www.blogger.com/atom/ns#" term="Rails" /><title>Comatose, TaskTHIS, and Theme Support. Oh My!</title><content type="html">&lt;p&gt;Well, I&amp;#8217;ve been a little remiss in my open-source development of late. Many apologies, things have been a bit hectic. You know the feeling, I&amp;#8217;m sure.&lt;/p&gt;&lt;p&gt;But that&amp;#8217;s not why I&amp;#8217;m posting. I thought I&amp;#8217;d outline my ideas for the future of these projects and get your feedback and/or ideas.&lt;/p&gt;&lt;p&gt;&lt;img src="http://comatose.rubyforge.org/images/comatoselogo.png" align="right"/&gt;&lt;/p&gt;&lt;h3 id="comatose_the_micro_cms_plugin"&gt;Comatose, The Micro CMS Plugin&lt;/h3&gt;&lt;p&gt;The things that are &lt;em&gt;definitely&lt;/em&gt; coming&amp;#8230;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Edge Rails&lt;/strong&gt; - Since Rails 1.2 is now official, it&amp;#8217;s time to finally support &amp;#8216;edge rails&amp;#8217;. :-D&lt;/p&gt;&lt;p&gt;Actually, I have a version that runs on Rails 1.2 now, but I&amp;#8217;m debating about Rails 1.1 backward compatibility. The new version changes quite a bit. The &lt;code&gt;DEFER_COMATOSE_LOAD&lt;/code&gt; stuff goes away, replaced by better configuration support and a &lt;code&gt;Dispatch::to_prepare&lt;/code&gt; block. Plus you no longer override the &lt;code&gt;ComatoseAdminController&lt;/code&gt; for authentication, instead in the configuration you specify modules to include in the class. Oh yeah, and the controllers no longer extend &lt;code&gt;ApplicationController&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Test Harness&lt;/strong&gt; - The tests in the plugin itself are very spartan, at best. I have a horribly ugly test harness I use for the actual unit testing that I&amp;#8217;m going to clean up and release.&lt;/p&gt;&lt;p&gt;Some &lt;em&gt;possibilities&lt;/em&gt;&amp;#8230;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Liquid Only&lt;/strong&gt; - I really think I&amp;#8217;m going to drop ERb support. How many of you use ERb over Liquid for page processing?&lt;/p&gt;&lt;p&gt;&lt;strong&gt;RESTful Pages&lt;/strong&gt; - Perhaps using the new RESTfully CRUDDY support would be useful. The idea of having an API for pages is interesting.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Mount Behaviors&lt;/strong&gt; - I haven&amp;#8217;t thought this through yet, it just popped into my head: &lt;code&gt;map.comatose_root 'devblog', :index=&amp;gt;'blog', :behavior=&amp;gt;'blog'&lt;/code&gt;&lt;/p&gt;&lt;p&gt;This example would add &amp;#8216;blog-like&amp;#8217; support such as all children being paged entries (showing last 10, next page, last page, etc.), automatic hAtom microformat support, and maybe some sort of archives&amp;#8230; I don&amp;#8217;t know. I still haven&amp;#8217;t thought about this too much.&lt;/p&gt;&lt;p&gt;The behavior support would be pluggable, much like text-filters and drops&amp;#8230; Can you think of any other behavior that would make sense?&lt;/p&gt;&lt;p&gt;Maybe &lt;code&gt;:behavior=&amp;gt;'syndicated'&lt;/code&gt; to create RSS/ATOM feeds of the child pages? Perhaps they&amp;#8217;d be mixable by saying &lt;code&gt;:behavior=&amp;gt;'blog syndicated'&lt;/code&gt; or &lt;code&gt;:behavior=&amp;gt;'blog,syndicated'&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;The &lt;em&gt;probably nots&lt;/em&gt;&amp;#8230;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Media Management&lt;/strong&gt; - It just feels like too much. I have a hacked up version of Comatose that supports page attachments. But you wind up having to deal with upload directories, and file permissions and&amp;#8230; It just feels too heavy. And too heavy != micro.&lt;/p&gt;&lt;p&gt;Perhaps it could be a separate plugin?&lt;/p&gt;&lt;p&gt;&lt;img src="http://mattmccray.com/images/taskthis-logo.jpg" align="right"/&gt;&lt;/p&gt;&lt;h3 id="taskthis"&gt;TaskTHIS&lt;/h3&gt;&lt;p&gt;TaskTHIS is getting a bit long in the tooth. It was written right about the time some of my AJAX patches were being added to Rails. Which was pre 1.0. So, yeah. It needs some love.&lt;/p&gt;&lt;p&gt;It was created as a show-and-tell for the then-new-and-nifty AJAX support. Which, of course, is now old hat.&lt;/p&gt;&lt;p&gt;In keeping with the tradition of show-and-tell, I thought TaskTHIS would be an excellent application to show how to use the new CRUD/REST/Resources stuff in Rails 1.2.&lt;/p&gt;&lt;p&gt;I have a few ideas outlined &lt;a href="http://taskthis.com/public/650"&gt;here&lt;/a&gt;. The biggest ones are:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;API&lt;/strong&gt; - This is fairly straight-forward, we&amp;#8217;ll get most if it from Rails. We&amp;#8217;ll just add the appropriate authentication for the XML requests.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;OpenID&lt;/strong&gt; - I was thinking replacing the existing login system with &lt;a href="http://www.openid.net"&gt;OpenID&lt;/a&gt; authentication. I like the idea of just typing in my domain to login&amp;#8230; Who needs passwords? Seriously though, this may be a bit controversial &amp;#8212; please weigh in.&lt;/p&gt;&lt;p&gt;Oh, I forgot to mention, &lt;a href="http://www.taskthis.com"&gt;TaskTHIS.com&lt;/a&gt; is working again.&lt;/p&gt;&lt;h3 id="theme_support_plugin"&gt;Theme Support Plugin&lt;/h3&gt;&lt;p&gt;Basically, just add any outstanding patches and ensure it works on Rails 1.2. I imagine the routing stuff will need to be tweaked.&lt;/p&gt;&lt;h3 id="whadda_ya_think"&gt;Whadda Ya Think?&lt;/h3&gt;&lt;p&gt;What would/wouldn&amp;#8217;t you like to see in any of these projects?&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-828167961684894778?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/geuNjqzWD4h8mZ1Mv16kOIEdgXQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/geuNjqzWD4h8mZ1Mv16kOIEdgXQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/geuNjqzWD4h8mZ1Mv16kOIEdgXQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/geuNjqzWD4h8mZ1Mv16kOIEdgXQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/828167961684894778/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2007/01/comatose-taskthis-and-theme-support-oh.html#comment-form" title="32 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/828167961684894778?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/828167961684894778?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/NyPNM-98Umg/comatose-taskthis-and-theme-support-oh.html" title="Comatose, TaskTHIS, and Theme Support. Oh My!" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>32</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2007/01/comatose-taskthis-and-theme-support-oh.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkAGQnw4fCp7ImA9Wx5UEU0.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-4304426064865610070</id><published>2006-12-02T19:19:00.000-06:00</published><updated>2010-10-14T21:12:03.234-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-14T21:12:03.234-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><title>Default Gravatar Image; A Greasemonkey Script</title><content type="html">&lt;p&gt;So you may have noticed that &lt;a href="http://www.gravatar.com"&gt;Gravatar&lt;/a&gt; has been going through some &lt;a href="http://www.gravatar.com/blog/archives/2006/11/29/gravatar-status/"&gt;growing pains&lt;/a&gt; and isn&amp;#8217;t working right now.&lt;/p&gt;&lt;p&gt;Until it&amp;#8217;s back, pages that use gravatars aren&amp;#8217;t loading quickly, or taking forever to load with broken images&amp;#8230; Which is a little annoying. So I wrote a quick &lt;a href="http://greasemonkey.mozdev.org"&gt;Greasemonkey&lt;/a&gt; user script to replace the image&amp;#8217;s source with the site&amp;#8217;s default gravatar image.&lt;/p&gt;&lt;p&gt;&amp;nbsp; &lt;a href="http://mattmccray.com/monkeyscripts/gravatar-default-image.user.js" style="color:black; font-weight: bold;"&gt;&lt;img src="http://mattmccray.com/images/js-icon.gif" align="absmiddle"/&gt; Gravatar Default Image&lt;/a&gt; &amp;laquo; Click to install&lt;/p&gt;&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; This will only work on sites that use an &lt;code&gt;img&lt;/code&gt; tag to show avatars. If a site uses a gravatar url as a css &lt;code&gt;background-image&lt;/code&gt;, well, you&amp;#8217;re &lt;span class="caps"&gt;SOL&lt;/span&gt;. However, with a little hacking, I&amp;#8217;m sure you could tweak this script to do that too, if it was important to you. ;-)&lt;/p&gt;&lt;p&gt;I tested this with &lt;a href="http://greasemonkey.mozdev.org/"&gt;Greasemonkey&lt;/a&gt; on Firefox 2 and &lt;a href="http://8-p.info/Creammonkey/" title="Hey, I didn't name it"&gt;Creammonkey&lt;/a&gt; on Safari 2. It&amp;#8217;ll probably work on &lt;a href="http://www.reifysoft.com/turnabout.php"&gt;Turnabout&lt;/a&gt; for Internet Exploder, but I didn&amp;#8217;t test it.&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-4304426064865610070?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/a95GjzCNJss9CKtxVoYPK2X5LDU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/a95GjzCNJss9CKtxVoYPK2X5LDU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/a95GjzCNJss9CKtxVoYPK2X5LDU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/a95GjzCNJss9CKtxVoYPK2X5LDU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/4304426064865610070/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2006/12/default-gravatar-image-greasemonkey.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/4304426064865610070?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/4304426064865610070?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/v7eVeoqv_QQ/default-gravatar-image-greasemonkey.html" title="Default Gravatar Image; A Greasemonkey Script" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2006/12/default-gravatar-image-greasemonkey.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkABSH8zeyp7ImA9Wx5UEU0.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-1153716836422308844</id><published>2006-10-31T19:06:00.000-06:00</published><updated>2010-10-14T21:12:39.183-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-14T21:12:39.183-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Comics" /><title>Lil Monstas!!</title><content type="html">&lt;p&gt;&lt;a href="http://www.lilmonstas.com"&gt;&lt;img src="http://mattmccray.com/images/lilmonstas-150x68.jpg" style="float:right;margin-left:10px;margin-bottom:5px;border:0px solid" title="LilMonstas.com!" alt="LilMonstas.com!" class="pivot-image" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.lilmonstas.com"&gt;Lil Monstas&lt;/a&gt; is live! Woot! We actually made our Halloween deadline too&amp;#8212;barely. There was about five minutes left!&lt;/p&gt;&lt;p&gt;Check it out today and every Monday for new installments. I hope you enjoy it!&lt;/p&gt;&lt;p&gt;&lt;strong style="color:maroon;"&gt;Update:&lt;/strong&gt; LilMonstas.com now has an &lt;a href="http://feeds.feedburner.com/LilMonstas"&gt;&lt;span class="caps"&gt;RSS&lt;/span&gt; feed&lt;/a&gt;!&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-1153716836422308844?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/45pc3C-YafJPA-Hz3qBV9mlmxF8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/45pc3C-YafJPA-Hz3qBV9mlmxF8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/45pc3C-YafJPA-Hz3qBV9mlmxF8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/45pc3C-YafJPA-Hz3qBV9mlmxF8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/1153716836422308844/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2006/10/lil-monstas.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/1153716836422308844?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/1153716836422308844?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/ZrUwsZQMfIM/lil-monstas.html" title="Lil Monstas!!" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2006/10/lil-monstas.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8ESX44eSp7ImA9Wx5UEU0.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-3100830535036515186</id><published>2006-09-21T13:52:00.000-05:00</published><updated>2010-10-14T21:13:28.031-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-14T21:13:28.031-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><category scheme="http://www.blogger.com/atom/ns#" term="Rails" /><title>Table Tag; The HTML Pariah</title><content type="html">&lt;p&gt;Here&amp;#8217;s a piece of news: &lt;strong&gt;The &lt;code&gt;table&lt;/code&gt; tag isn&amp;#8217;t deprecated in &lt;span class="caps"&gt;XHTML&lt;/span&gt;!&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;OK, &amp;#8220;that&amp;#8217;s not news&amp;#8221; you say. True. It&amp;#8217;s not. But it seems to be for some. In fact, it&amp;#8217;s amazing the lengths people will go to avoid using tables. You know what I&amp;#8217;m talking about.&lt;/p&gt;&lt;p&gt;But, &amp;#8220;It&amp;#8217;s not semantic&amp;#8221;, &amp;#8220;It&amp;#8217;s not separating content from layout properly&amp;#8221;, &amp;#8220;It&amp;#8217;s soOOoo Web 1.0&amp;#8221; or many of the other &amp;#8220;reasons&amp;#8221; to shun tables are mostly, well, &lt;em&gt;crap&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;There&amp;#8217;s no way I&amp;#8217;ll believe that it&amp;#8217;s better to use a dozen &lt;code&gt;div&lt;/code&gt;&amp;#8217;s and a hundred lines of &lt;span class="caps"&gt;CSS&lt;/span&gt; to accomplish the same as a &lt;code&gt;table&lt;/code&gt;. Talk about re-inventing the wheel!&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Just because you &lt;em&gt;&lt;strong&gt;can&lt;/strong&gt;&lt;/em&gt; do something, doesn&amp;#8217;t mean you &lt;em&gt;&lt;strong&gt;should&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Listen, if you have &lt;em&gt;tabular&lt;/em&gt; data, or need to use some sort of grid, just &lt;em&gt;use tables&lt;/em&gt;. Be reasonable, be pragmatic. If you need a hammer, use a hammer, don&amp;#8217;t use your forehead instead. Sure, they&amp;#8217;ll both drive nails&amp;#8230; &lt;em&gt;Probably&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Let me re-emphasize the &amp;#8216;be reasonable&amp;#8217; part. Remember, it cuts both ways.  &lt;em&gt;Too many&lt;/em&gt; tables can be a bad thing, and they can be a crutch. The point of this rant is that you shouldn&amp;#8217;t &lt;em&gt;avoid&lt;/em&gt; using tables, or some other shunned-but-non-deprecated tag, just because it&amp;#8217;s popular to.&lt;/p&gt;&lt;p&gt;- end of rant -&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-3100830535036515186?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Hp-zvLazNeW5BK3wD8TwzjPm_84/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Hp-zvLazNeW5BK3wD8TwzjPm_84/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Hp-zvLazNeW5BK3wD8TwzjPm_84/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Hp-zvLazNeW5BK3wD8TwzjPm_84/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/3100830535036515186/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2006/09/table-tag-html-pariah.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/3100830535036515186?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/3100830535036515186?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/HCD0W4fOL0k/table-tag-html-pariah.html" title="Table Tag; The HTML Pariah" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2006/09/table-tag-html-pariah.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8HRnsyfip7ImA9Wx5UEU0.&quot;"><id>tag:blogger.com,1999:blog-991932877251085263.post-143804614678880614</id><published>2006-09-20T05:31:00.000-05:00</published><updated>2010-10-14T21:13:57.596-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-14T21:13:57.596-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Comatose" /><category scheme="http://www.blogger.com/atom/ns#" term="Software" /><category scheme="http://www.blogger.com/atom/ns#" term="Rails" /><title>Comatose 'Compatibility Mode'</title><content type="html">&lt;p&gt;OK, so after mentioning it in my &lt;a href="http://mattmccray.com/archive/2006/09/20/Comatose_Version_07"&gt;last post&lt;/a&gt;, I&amp;#8217;ve decided to go ahead and implement it. Comatose version 0.7.1 adds a &lt;code&gt;DEFER_COMATOSE_LOAD&lt;/code&gt; flag that you can use to, well, defer comatose&amp;#8217;s loading. You will have to manually tell it to load in your &lt;code&gt;environment.rb&lt;/code&gt; using &lt;code&gt;Comatose.load&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;See this &lt;a href="http://comatose.rubyforge.org/dev-blog/another-day-another-update"&gt;devblog post&lt;/a&gt; for more.&lt;/p&gt;&lt;p&gt;Normally, I&amp;#8217;d only post this on the &lt;a href="http://comatose.rubyforge.org/dev-blog"&gt;Comatose development blog&lt;/a&gt;, but I wanted to make sure anybody who&amp;#8217;s having problems using Comatose with other plugins/applications knows about this. If you have problems or questions, leave a comment here. Thanks!&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/991932877251085263-143804614678880614?l=mattmccray.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/wQ5k2h4S7NnpxfZX0cANOIuhaCs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wQ5k2h4S7NnpxfZX0cANOIuhaCs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/wQ5k2h4S7NnpxfZX0cANOIuhaCs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wQ5k2h4S7NnpxfZX0cANOIuhaCs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://mattmccray.blogspot.com/feeds/143804614678880614/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://mattmccray.blogspot.com/2006/09/comatose-mode.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/143804614678880614?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/991932877251085263/posts/default/143804614678880614?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mattmccray/~3/cl9Bq5nBbLg/comatose-mode.html" title="Comatose &amp;#39;Compatibility Mode&amp;#39;" /><author><name>M@</name><uri>http://www.blogger.com/profile/04260026770230997300</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_NO3qb5t--pM/TRUJz2PmTHI/AAAAAAAAANo/7_2imB7BWHE/S220/chibi-spacematt-avatar-244.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://mattmccray.blogspot.com/2006/09/comatose-mode.html</feedburner:origLink></entry></feed>

