<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Dr Nic &#187; JSON</title>
	<atom:link href="http://drnicwilliams.com/category/javascript/json/feed/" rel="self" type="application/rss+xml" />
	<link>http://drnicwilliams.com</link>
	<description>Ruby makes Rails, Javascript makes Ajax, Dr Nic makes Magic</description>
	<lastBuildDate>Mon, 15 Mar 2010 20:51:48 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Showing off data on a timeline</title>
		<link>http://drnicwilliams.com/2007/10/28/showing-off-data-on-a-timeline/</link>
		<comments>http://drnicwilliams.com/2007/10/28/showing-off-data-on-a-timeline/#comments</comments>
		<pubDate>Sun, 28 Oct 2007 03:41:21 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[JSON]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[MagicCGI]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Trick]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/2007/10/28/showing-off-data-on-a-timeline/</guid>
		<description><![CDATA[I&#8217;m still trying to justify my effort writing the MagicCGI code. It let you get an XML or JSON feed for any database, with some basic conditionals, limits etc. The existing demo is for my blog database. 
I think this one is kinda cool &#8211; showing off all your blog posts/articles on a timeline:

Can&#8217;t see [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2007/08/12/magiccgi/' rel='bookmark' title='Permanent Link: MagicCGI shows OpenID user count'>MagicCGI shows OpenID user count</a> <small> In the last 20 days, 43 people have used...</small></li><li><a href='http://drnicwilliams.com/2007/04/16/aliases-to-the-latest-branch-folder-youre-working-on/' rel='bookmark' title='Permanent Link: Aliases to the latest branch folder you&#8217;re working on'>Aliases to the latest branch folder you&#8217;re working on</a> <small>For my Rails and RubyGem projects I&#8217;ll run multiple branches...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m still trying to justify my effort writing the <a href="http://drnicwilliams.com/2007/08/12/magiccgi/">MagicCGI code</a>. It let you get an XML or JSON feed for any database, with some basic conditionals, limits etc. The existing demo is for my blog database. </p>
<p>I think this one is kinda cool &#8211; showing off all your blog posts/articles on a <a href="http://simile.mit.edu/">timeline</a>:</p>
<p><iframe src="http://drnicwilliams.com/wp-content/blog_timeline/current/" width=550 height=750 border=0></iframe></p>
<caption id="cant_see_timeline"><a href="http://drnicwilliams.com/wp-content/blog_timeline/current/">Can&#8217;t see the snazzy timeline above?</a></caption>
<p>To get the timeline working with the schema output from the Magic CGI, I needed to write my own Timeline EventSource. Currently I don&#8217;t do anything fancy with the generated bubbles &#8211; I just use the defaults.</p>
<p>The MagicCGI query gets all wp_posts (Wordpress schema) rows, where &#8220;post_status=publish&#8221; and only returns fields that are relevant (notably ignores the large post_content field holding the blog content):</p>
<p><a href="http://drnicwilliams.com/cgi-bin/wp_drnicwilliams.cgi?format=json&#038;table=wp_posts&#038;post_status=publish&#038;field=ID&#038;field=post_title&#038;field=post_date_gmt&#038;field=post_modified_gmt&#038;field=guid&#038;field=comment_count">http://drnicwilliams.com/cgi-bin/wp_drnicwilliams.cgi?<br/>format=json&#038;table=wp_posts&#038;post_status=publish&#038;<br/>field=ID&#038;field=post_title&#038;field=post_date_gmt&#038;<br/>field=post_modified_gmt&#038;field=guid&#038;field=comment_count</a></p>
<p>The other cool thing I did here was to deploy it all with Capistrano (an html page + javascript libs). It even deploys/manages a copy of the Timeline trunk onto the server. This is the first time I&#8217;ve deployed a non-Ruby/Rails app using Capistrano, and once I got it set up it becomes much easier to manage than using an FTP app, etc.</p>
<p>How easy? <code>cap1 update</code> (note the dubious use of capistrano 1&#8230; I still&#8230; haven&#8217;t&#8230; converted&#8230; to 2.0&#8230;)</p>
<p>I&#8217;m not confident enough that my solution is sexy enough to outline in detail, so if you&#8217;re interested in deploying Javascript apps etc with Capistrano, just checkout the code (below) and look at the config/deploy.rb script. (note that I&#8217;ve disabled the <a href="http://www.deprec.org/">deprec</a> require statement as it assumes I&#8217;m wanted to run some mongrels etc, but deprec is very handy for setting up ssh and other fun stuff at the start).</p>
<p>So, no details here, just a fun example. </p>
<p>If the Timeline tickles your fancy, their website has lots of tutorials, and/or check out my html/javascript code.</p>
<pre>
svn co http://drnicwilliams.com/svn/blog_timeline/trunk blog_timeline
</pre>
<p>If the MagicCGI tickles your fancy, its also only on svn at the moment, though its docco should be pretty good. I think. </p>
<pre>
svn co http://rubyforge.org/var/svn/magicmodels/magic_cgi/trunk magic_cgi
</pre>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2007/08/12/magiccgi/' rel='bookmark' title='Permanent Link: MagicCGI shows OpenID user count'>MagicCGI shows OpenID user count</a> <small> In the last 20 days, 43 people have used...</small></li><li><a href='http://drnicwilliams.com/2007/04/16/aliases-to-the-latest-branch-folder-youre-working-on/' rel='bookmark' title='Permanent Link: Aliases to the latest branch folder you&#8217;re working on'>Aliases to the latest branch folder you&#8217;re working on</a> <small>For my Rails and RubyGem projects I&#8217;ll run multiple branches...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2007/10/28/showing-off-data-on-a-timeline/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MagicCGI shows OpenID user count</title>
		<link>http://drnicwilliams.com/2007/08/12/magiccgi/</link>
		<comments>http://drnicwilliams.com/2007/08/12/magiccgi/#comments</comments>
		<pubDate>Sun, 12 Aug 2007 10:51:04 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[JSON]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[OpenID]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Trick]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/2007/08/12/magiccgi/</guid>
		<description><![CDATA[



In the last 20 days, 43 people have used OpenID to leave comments. That&#8217;s very cool.
Corollary: add OpenID login to your blog.
Even cooler &#8211; Dynamic counter
The screen shot comes from the Comments form.
If you look at the comments form in a week, month, year, the counter above have be changed from its original value 43.
No [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2007/10/28/showing-off-data-on-a-timeline/' rel='bookmark' title='Permanent Link: Showing off data on a timeline'>Showing off data on a timeline</a> <small>I&#8217;m still trying to justify my effort writing the MagicCGI...</small></li><li><a href='http://drnicwilliams.com/2007/09/11/myopenid-goes-down-multiple-openids-useful/' rel='bookmark' title='Permanent Link: Why supporting multiple OpenIDs per User is useful for users&#8230;'>Why supporting multiple OpenIDs per User is useful for users&#8230;</a> <small>Web apps/services go down for maintenance (expected or erroneously) all...</small></li><li><a href='http://drnicwilliams.com/2007/09/11/railsrumble-hates-openid/' rel='bookmark' title='Permanent Link: RailsRumble hates OpenID'>RailsRumble hates OpenID</a> <small>There are 146 RailsRumble entrants. %w[rubygems hpricot open-uri].each { |l|...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<div>
<div style="float:right">
<a class="imagelink" href="http://drnicwilliams.com/wp-content/uploads/2007/08/openid_user_count.png" title="OpenID count"><img id="image220" src="http://drnicwilliams.com/wp-content/uploads/2007/08/openid_user_count.png" alt="OpenID count" /></a>
</div>
<p>In the last 20 days, <span id="openid_counter">43</span> people have used OpenID to leave comments. That&#8217;s very cool.</p>
<p><strong>Corollary</strong>: add OpenID login to your blog.</p>
<h2 id="even_cooler_dynamic_counter">Even cooler &#8211; Dynamic counter</h2>
<p>The screen shot comes from the Comments form.</p>
<p>If you look at the comments form in a week, month, year, the counter above have be changed from its original value 43.</p>
<p>No fancy Wordpress plugins (I don&#8217;t <em>do</em> PHP)</p>
<p>No Apache tricks. (I don&#8217;t know any Apache tricks)</p>
</div>
<p>Instead with Javascript/HTML <em>attached</em> to JSON <em>attached</em> to a RubyCGI script <em>attached</em> to my Wordpress database via ActiveRecords and some magic.</p>
<p>I call it <strong>MagicCGI</strong>. I also call it <strong>Frigging Scary</strong>.</p>
<p>Try the following:</p>
<pre>$ curl -v "http://drnicwilliams.com/cgi-bin/wp_drnicwilliams.cgi?table=wp_openid_identities&amp;action=count&amp;format=json"
&lt; Content-Type: txt/json
&lt;
43
</pre>
<p>Or some XML?</p>
<pre>$ curl -v "http://drnicwilliams.com/cgi-bin/wp_drnicwilliams.cgi?table=wp_openid_identities&amp;action=count&amp;format=xml"
&lt; Content-Type: txt/xml
&lt;
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;result&gt;
  &lt;count type="integer"&gt;43&lt;/count&gt;
&lt;/result&gt;
</pre>
<h2 id="raw_data">Raw data?</h2>
<pre>$ curl "http://drnicwilliams.com/cgi-bin/wp_drnicwilliams.cgi?table=wp_posts&amp;field=post_title&amp;limit=5&amp;order=post_title"
[{"attributes": {"post_title": "OpenID count"}},
 {"attributes": {"post_title": "MagicCGI shows OpenID user count"}},
 {"attributes": {"post_title": "map_by_method now works with ActiveRecord associations"}},
 {"attributes": {"post_title": "Feedburner"}},
 {"attributes": {"post_title": "One year on the InterTubes"}}
]
</pre>
<p>Getting kinda scary now, I think.</p>
<h2 id="ooh_just_how_much_magic">Ooh, just how much magic?</h2>
<p>Want a list of available tables to play with?</p>
<pre>$ curl "http://drnicwilliams.com/cgi-bin/wp_drnicwilliams.cgi?meta=tables"
[{table_name: 'wp_users'},...]
</pre>
<ul>
<li>add <code>&amp;format=xml</code> to XML output; JSON is default</li>
<li>add <code>&amp;meta=columns</code> to include the column schema definitions</li>
<li>add <code>&amp;table_name=wp_posts</code> for each table you want (instead of all the tables)</li>
</ul>
<p>E.g. to see the columns for <code>wp_posts</code> and no other table, in XML:</p>
<pre>$ curl "http://drnicwilliams.com/cgi-bin/wp_drnicwilliams.cgi?meta=tables&amp;meta=columns&amp;table_name=wp_posts&amp;format=xml"
</pre>
<p>A list of all urls and internal user_ids for users/OpenID users/registered commenters?</p>
<pre>$ curl "http://drnicwilliams.com/cgi-bin/wp_drnicwilliams.cgi?table=wp_users&amp;field=user_url&amp;field=id"
[{"attributes": {"id": "1", "user_url": "http://drnicwilliams.com"}}, ...
</pre>
<p>So, now we know Dr Nic = user id 1.</p>
<p>Oh oh oh, how about a list of comments for a specific user?</p>
<pre>$ curl "http://drnicwilliams.com/cgi-bin/wp_drnicwilliams.cgi?table=wp_comments&amp;user_id=1"
...comments by Dr Nic...
or
$ curl "http://drnicwilliams.com/cgi-bin/wp_drnicwilliams.cgi?table=wp_comments&amp;user_id=1&amp;action=count"
232
</pre>
<p>Dr Nic&#8217;s commented in his own blog 232 times? Out of how many comments?</p>
<pre>$ curl "http://drnicwilliams.com/cgi-bin/wp_drnicwilliams.cgi?table=wp_comments&amp;action=count"
963
</pre>
<p>Where are the user emails? Where are their passwords?</p>
<p><strong>Hidden!</strong> See below.</p>
<h2 id="callbacks">Callbacks?</h2>
<p>JSON URLs support <code>callback=someCallbackMethod</code> and/or <code>variable=someLocalVariable</code>.</p>
<pre>$ curl "http://drnicwilliams.com/cgi-bin/wp_drnicwilliams.cgi?table=wp_comments&amp;action=count&amp;callback=someMethod"
someMethod(963);
</pre>
<h2 id="what_does_wp_drnicwilliamscgi_look_like">What does <code>wp_drnicwilliams.cgi</code> look like?</h2>
<p>Something a little like this&#8230; </p>
<pre>#!/usr/local/bin/ruby
require 'magic_cgi'         # loads the render magic, model magic, and meta-model magic
include Render

require 'magic_cgi/config/wordpress'  # connect to DB using Wordpress installation (wp-config.php)
MagicCGI::Config::Wordpress.establish_connection "/path/to/drnicwilliams/web/public"

# The following is defaulted for Wordpress connections:
MagicCGI::Config.hidden_tables |= %w[wp_openid_nonces wp_openid_associations wp_usermeta wp_tla_rss_map wp_tla_data]
MagicCGI::Config.hidden_columns['wp_users'] = %w[user_email user_pass user_activation_key]
MagicCGI::Config.hidden_columns['wp_openid_identities'] = %w[hash]
MagicCGI::Config.hidden_columns['wp_comments'] = %w[comment_author_email comment_author_IP]
MagicCGI::Config.hidden_columns['wp_posts'] = %w[post_password]

render do |params|
  data = DbTable.from_params(params)
  data ||= begin
    table_name = params['table'].first || 'wp_users'
    model_name = ActiveRecord::Base.class_name(table_name)
    klass = MagicCGI::MagicModel.create_class(model_name, ActiveRecord::Base)
    klass.find_or_count_by_params(params)
  end
  data
end
</pre>
<h2 id="can_i_write_my_own_cgi_scripts_for_my_own_dbs">Can I write my own CGI scripts for my own DBs?</h2>
<p>Sure. Its a library called MagicCGI.</p>
<h2 id="what_is_magic_cgi">What is MagicCGI?</h2>
<p>Coming soon.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2007/10/28/showing-off-data-on-a-timeline/' rel='bookmark' title='Permanent Link: Showing off data on a timeline'>Showing off data on a timeline</a> <small>I&#8217;m still trying to justify my effort writing the MagicCGI...</small></li><li><a href='http://drnicwilliams.com/2007/09/11/myopenid-goes-down-multiple-openids-useful/' rel='bookmark' title='Permanent Link: Why supporting multiple OpenIDs per User is useful for users&#8230;'>Why supporting multiple OpenIDs per User is useful for users&#8230;</a> <small>Web apps/services go down for maintenance (expected or erroneously) all...</small></li><li><a href='http://drnicwilliams.com/2007/09/11/railsrumble-hates-openid/' rel='bookmark' title='Permanent Link: RailsRumble hates OpenID'>RailsRumble hates OpenID</a> <small>There are 146 RailsRumble entrants. %w[rubygems hpricot open-uri].each { |l|...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2007/08/12/magiccgi/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>My railsconf sessions in my sidebar</title>
		<link>http://drnicwilliams.com/2007/05/02/myconfplan-sidebar-widget/</link>
		<comments>http://drnicwilliams.com/2007/05/02/myconfplan-sidebar-widget/#comments</comments>
		<pubDate>Wed, 02 May 2007 07:39:26 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[JSON]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[MyConfPlan]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/2007/05/02/myconfplan-sidebar-widget/</guid>
		<description><![CDATA[Jesse Newland got the JSON API a day ago and already built a reusable Javascript widget to show conference session selections on his blog sidebar.
So I added it to my blog too!

Feel free to use his code, and write your own CSS to make it look sexy on your site.
Remember, its dynamic JSON (or XML) [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2007/05/03/12-new-railsconf-sessions/' rel='bookmark' title='Permanent Link: 12 new Railsconf sessions'>12 new Railsconf sessions</a> <small>The expansion of the Railsconf schedule has added a dozen...</small></li><li><a href='http://drnicwilliams.com/2007/04/27/javaone-on-myconfplan/' rel='bookmark' title='Permanent Link: Railsconf => 4 tracks; JavaOne => simultaneous 14 tracks!!'>Railsconf => 4 tracks; JavaOne => simultaneous 14 tracks!!</a> <small>MyConfPlan now includes all the sessions for next month&#8217;s JavaOne...</small></li><li><a href='http://drnicwilliams.com/2006/11/23/supporting-json-in-rails-or-anywhere/' rel='bookmark' title='Permanent Link: Supporting JSON callbacks in Rails'>Supporting JSON callbacks in Rails</a> <small>Now you know how to write JavaScript widgets, now you...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://soylentfoo.jnewland.com/">Jesse Newland</a> got the JSON API a day ago and already built a reusable <a href="http://soylentfoo.jnewland.com/articles/2007/05/01/myconfplan-javascript-widget">Javascript widget</a> to show conference session selections on his blog sidebar.</p>
<p><strong><a href="http://drnicwilliams.com">So I added it to my blog too!</a></strong></p>
<p><a id="p179" rel="attachment" class="imagelink" href="http://drnicwilliams.com/2007/05/02/myconfplan-sidebar-widget/dr-nic-myconfplan-sidebar/" title="Dr Nic MyConfPlan sidebar"><img border=1 id="image179" src="http://drnicwilliams.com/wp-content/uploads/2007/05/dr-nic-selections-sidebar.png" alt="Dr Nic MyConfPlan sidebar" /></a><br />
Feel free to use his code, and write your own CSS to make it look sexy on your site.</p>
<p>Remember, its dynamic JSON (or XML) &#8211; so any changes you make to your conf plan will automatically show up next time the widget is displayed.</p>
<p>Doubly remember &#8211; use <strong>your</strong> JSON url not Jesse&#8217;s&#8230; its the link &#8220;json&#8221; at the top of each conference page, when you&#8217;re logged in. Alternately, just change jnewland to your username. Yeah, that&#8217;s simpler.</p>
<p>[Most of this text copied from <a href="http://blog.myconfplan.com/2007/05/01/show-your-sessions-as-a-widget/">original announcement</a>]</p>
<p>Thanks Jesse!</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2007/05/03/12-new-railsconf-sessions/' rel='bookmark' title='Permanent Link: 12 new Railsconf sessions'>12 new Railsconf sessions</a> <small>The expansion of the Railsconf schedule has added a dozen...</small></li><li><a href='http://drnicwilliams.com/2007/04/27/javaone-on-myconfplan/' rel='bookmark' title='Permanent Link: Railsconf => 4 tracks; JavaOne => simultaneous 14 tracks!!'>Railsconf => 4 tracks; JavaOne => simultaneous 14 tracks!!</a> <small>MyConfPlan now includes all the sessions for next month&#8217;s JavaOne...</small></li><li><a href='http://drnicwilliams.com/2006/11/23/supporting-json-in-rails-or-anywhere/' rel='bookmark' title='Permanent Link: Supporting JSON callbacks in Rails'>Supporting JSON callbacks in Rails</a> <small>Now you know how to write JavaScript widgets, now you...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2007/05/02/myconfplan-sidebar-widget/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Supporting JSON callbacks in Rails</title>
		<link>http://drnicwilliams.com/2006/11/23/supporting-json-in-rails-or-anywhere/</link>
		<comments>http://drnicwilliams.com/2006/11/23/supporting-json-in-rails-or-anywhere/#comments</comments>
		<pubDate>Thu, 23 Nov 2006 11:52:03 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[JSON]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/2006/11/23/supporting-json-in-rails-or-anywhere/</guid>
		<description><![CDATA[Now you know how to write JavaScript widgets, now you need to know how to help others write widgets for your data.
Here&#8217;s a short-one act play to describe the issue at hand.
Actors in this play
You: You run a website that you built with Rails. Its got data in it. You&#8217;re a hero of the working [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2010/03/15/using-coffeescript-in-rails-and-even-on-heroku/' rel='bookmark' title='Permanent Link: Using CoffeeScript in Rails and even on Heroku'>Using CoffeeScript in Rails and even on Heroku</a> <small>I&#8217;m pretty excited about CoffeeScript as a clean-syntax replacement for...</small></li><li><a href='http://drnicwilliams.com/2009/11/03/first-look-at-rails-3-0-pre/' rel='bookmark' title='Permanent Link: First look at rails 3.0.pre'>First look at rails 3.0.pre</a> <small> This article is out of date in some aspects....</small></li><li><a href='http://drnicwilliams.com/2009/03/30/closing-in-on-the-dream-one-click-to-deploy-rails-apps/' rel='bookmark' title='Permanent Link: Closing in on The Dream: &#8220;one-click-to-deploy Rails apps&#8221;'>Closing in on The Dream: &#8220;one-click-to-deploy Rails apps&#8221;</a> <small> Got a simple app you want to build? Allocate...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Now you know how to <a href="http://drnicwilliams.com/2006/11/21/diy-widgets/">write JavaScript widgets</a>, now you need to know how to help others write widgets for your data.</p>
<p>Here&#8217;s a short-one act play to describe the issue at hand.</p>
<h3>Actors in this play</h3>
<p><strong>You</strong>: You run a website that you built with Rails. Its got data in it. You&#8217;re a hero of the working class, a family man, and own a hybrid car, but you ride a bike to work. You vote, you contribute to the local neighbourhood newspaper, and you love Autumn because the leaves turn pretty colours. You&#8217;re not a fool.<br />
<strong>Ulrich</strong>: Ulrich is a user of your site. Ulrich is a needy, web2.0 super-consumer. Ulrich started using your site when it was first profiled on TechCrunch, Ajaxian, and the Times magazine, but since then he&#8217;s found Theo&#8217;s website.<br />
<strong>Theo</strong>: Theo runs a third-party website. Theo&#8217;s website has its own data too. It doesn&#8217;t have Ulrich&#8217;s data. Theo&#8217;s site <em>wasn&#8217;t</em> written about in TechCrunch, nor Ajaxian, nor even the local church foldover. </p>
<p><strong>[Prelude]</strong> Theo just received his third email from Ulrich. Ulrich wants to port his data from Your website to Theo&#8217;s. Theo in turn, now has you on Skype&#8230;<br />
<strong>You:</strong> I&#8217;m not very happy with the idea of giving up my data.<br />
<strong>Theo:</strong> What happened to Open APIs? Making the user&#8217;s data transferrable with the user?<br />
<strong>You:</strong> You read too many 37signals blog articles. Even Flickr &#8211; web two of all web two sites &#8211; doesn&#8217;t give up its data.<br />
<strong>Theo:</strong> But some of my users&#8230;<br />
<strong>You:</strong> You mean Ulrich. He&#8217;s emailed me too<br />
Theo: Yeah, Ulrich. Ulrich wants to embed his data from your site into my site.<br />
<strong>You:</strong> We already have a JSON API..<br />
<strong>Theo:</strong> Its no good.<br />
<strong>You:</strong> Works just fine. Returns lovely JavaScript data. Our users use it within our site to write their own widgets. Its one of our big draw cards.<br />
<strong>Theo:</strong> Its no good. It doesn&#8217;t support callbacks.<br />
<strong>You:</strong> What the?<br />
<strong>Theo:</strong> Without a callback function there is no way my <code>&lt;script></code> tags can trigger any functionality when they retrieve the data. Ulrich could include his JavaScript widget into his page on mysite with <em>your data</em> if it was possible to specify a callback function in your API.<br />
<strong>You:</strong> Instead of just raw JSON data?<br />
<strong>Theo:</strong> Yeah. Lots of other sites offer it: <a href="http://www.cocomment.com/json">CoComment</a>, <a href="http://del.icio.us/help/json/posts">Delicious</a>, <a href="http://googledataapis.blogspot.com/2006/11/calling-all-web-hackers-json-support.html">Google Data</a>, etc. They all allow <code>callback=myFunction</code> in the URL parameters.<br />
<strong>You:</strong> <em>[thinking to yourself]</em> Rails don&#8217;t support callbacks out of the box. Bugger.<br />
<strong>You:</strong> Sure, I&#8217;ll work on something.<br />
<strong>Theo:</strong> Thanks, hopefully this gets Ulrich off my back. Should drive us both more traffic too.<br />
<strong>You:</strong> The wikipedia page for <a href="http://en.wikipedia.org/wiki/JSON">JSON</a> doesn&#8217;t mention callbacks.<br />
<strong>Theo:</strong> Its a wiki. Add it yourself.<br />
<strong>You:</strong> Smart arse.</p>
<p>The end.</p>
<h3>Supporting JSON callbacks in Rails</h3>
<p>Piece of cake. </p>
<p>But first, to support pure JSON API data objects from Rails, you have a handy <code>to_json</code> method on the <code>Object</code> class. So, in the partial/view you are rendering, e.g. <code>person_json.rhtml</code> (or <code>person.rjs</code> if you using <a href="http://www.danwebb.net/2006/11/17/rjs-minus-r">MinusR</a> plugin), you include:</p>
<pre>
&lt;%= @object.to_json %>
</pre>
<p>Yeah, that was tough.</p>
<p>Now, for callback support. Change the above to:</p>
<pre>
<span class="string">&lt;%= "#{params[:callback]}(" if params[:callback] -%&gt;</span>
&lt;%= @object.to_json -%>
<span class="string">&lt;%= ")" if params[:callback] -%&gt;</span>
</pre>
<p>Done.</p>
<h3>Update: render_json method</h3>
<p><a href="http://toolmantim.com/">Tim Lucas</a> wrote a <a href="http://www.sitepoint.com/blogs/2006/10/05/json-p-output-with-rails">great article</a> introducing a <code>render_json</code> method to add to your base ApplicationController. It will automatically return JSON data that you pass it, wrapped automatically in a callback or assigned to a variable (or both) if the parameters include a <code>callback</code> or <code>variable</code> value.</p>
<p>Read it, its good.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2010/03/15/using-coffeescript-in-rails-and-even-on-heroku/' rel='bookmark' title='Permanent Link: Using CoffeeScript in Rails and even on Heroku'>Using CoffeeScript in Rails and even on Heroku</a> <small>I&#8217;m pretty excited about CoffeeScript as a clean-syntax replacement for...</small></li><li><a href='http://drnicwilliams.com/2009/11/03/first-look-at-rails-3-0-pre/' rel='bookmark' title='Permanent Link: First look at rails 3.0.pre'>First look at rails 3.0.pre</a> <small> This article is out of date in some aspects....</small></li><li><a href='http://drnicwilliams.com/2009/03/30/closing-in-on-the-dream-one-click-to-deploy-rails-apps/' rel='bookmark' title='Permanent Link: Closing in on The Dream: &#8220;one-click-to-deploy Rails apps&#8221;'>Closing in on The Dream: &#8220;one-click-to-deploy Rails apps&#8221;</a> <small> Got a simple app you want to build? Allocate...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2006/11/23/supporting-json-in-rails-or-anywhere/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>
