<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Hack&#8217;d &#8211; Great Stuff for Web Hackers</title>
	<atom:link href="https://hackd.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://hackd.wordpress.com</link>
	<description>A collection of cool ideas we come across while building ThriveSmart.</description>
	<lastBuildDate>Thu, 05 Mar 2009 00:47:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<site xmlns="com-wordpress:feed-additions:1">1134473</site><cloud domain='hackd.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>https://s0.wp.com/i/webclip.png</url>
		<title>Hack&#8217;d &#8211; Great Stuff for Web Hackers</title>
		<link>https://hackd.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="https://hackd.wordpress.com/osd.xml" title="Hack&#039;d - Great Stuff for Web Hackers" />
	<atom:link rel='hub' href='https://hackd.wordpress.com/?pushpress=hub'/>
	<item>
		<title>Easy Money &#8211; Our Latest Rails Love Child</title>
		<link>https://hackd.wordpress.com/2008/02/15/easy-money-our-latest-rails-love-child/</link>
					<comments>https://hackd.wordpress.com/2008/02/15/easy-money-our-latest-rails-love-child/#respond</comments>
		
		<dc:creator><![CDATA[Dan]]></dc:creator>
		<pubDate>Sat, 16 Feb 2008 00:59:09 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">http://hackd.wordpress.com/?p=24</guid>

					<description><![CDATA[Today we released another application, this our first foray with the Facebook® platform.  The application called &#8220;Easy Money&#8221; allows players to bid and win gift cards in daily drawings. The application uses Rails 2.0.2, MySQL, backgroundrb, memcached and the facebooker plugin. We will have a series of technical posts coming soon, talking about the challenges [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><a href="https://hackd.wordpress.com/wp-content/uploads/2008/02/easymoneylogo_big.gif" title="Easy Money Logo"><img src="https://hackd.wordpress.com/wp-content/uploads/2008/02/easymoneylogo_big.gif?w=450" alt="Easy Money Logo" align="left" /></a>Today we released another application, this our first foray with the Facebook® platform.  The application called  &#8220;Easy Money&#8221; allows players to bid and win gift cards in daily drawings.  The application uses Rails 2.0.2, MySQL, backgroundrb, memcached and the facebooker plugin.</p>
<p>We will have a series of technical posts coming soon, talking about the challenges and tweaks me made to get everything working in the RESTful style we love.  If you want to see the results you can checkout the <a href="http://www.facebook.com/apps/application.php?id=20356475262">Easy Money application here</a>.</p>
<p>Facebook® is a registered trademark of Facebook Inc.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://hackd.wordpress.com/2008/02/15/easy-money-our-latest-rails-love-child/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">24</post-id>
		<media:content url="https://0.gravatar.com/avatar/673379bc8488f4a9bf2f150252cd5dd9d6e3fce48b94bd33b907f523e9c4acf1?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Dan</media:title>
		</media:content>

		<media:content url="https://hackd.wordpress.com/wp-content/uploads/2008/02/easymoneylogo_big.gif" medium="image">
			<media:title type="html">Easy Money Logo</media:title>
		</media:content>
	</item>
		<item>
		<title>Fun with Rails Constantize</title>
		<link>https://hackd.wordpress.com/2007/12/01/fun-with-rails-constantize/</link>
					<comments>https://hackd.wordpress.com/2007/12/01/fun-with-rails-constantize/#comments</comments>
		
		<dc:creator><![CDATA[Dan]]></dc:creator>
		<pubDate>Sat, 01 Dec 2007 10:33:21 +0000</pubDate>
				<category><![CDATA[DRY]]></category>
		<category><![CDATA[rails]]></category>
		<guid isPermaLink="false">http://hackd.wordpress.com/2007/12/01/fun-with-rails-constantize/</guid>

					<description><![CDATA[Have you ever found yourself working on a Rails project where you need certain behavior in a model based on type but STI[1] is not the right fit or you are already using STI and can not subtype again? I was working on a problem where a model utilized STI to create two types: Icon [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><img src="https://i0.wp.com/danieloshea.bingodisk.com/public/thrivesmart/themes_model_diag.png" alt="Visualization Diagram" align="right" height="149" width="274" />Have you ever found yourself working on a Rails project where you need certain behavior in a model based on type but STI[1] is not the right fit or you are already using STI and can not subtype again?  I was working on a problem where a model utilized STI to create two types: Icon and Color.  Within each type I had different data.  Some of the data represented defaults for Icons or defaults for Colors and the others were specific.  I&#8217;ve put together a little diagram on the right to illustrate this[2].</p>
<p>The way we had modeled the data made it very easy to pick out the specific icon or color theme (using an ActiveRecord finder for that type).  However, based on the data instance returned by find I wanted to execute a series of methods to populate other models with data relevant to the Icon or Color instance.<span id="more-22"></span></p>
<p>A couple solutions presented themselves[3]:</p>
<ol>
<li>Refactor the model so that each type was represented by a model type (the orange boxes would become brown ones).  We could then call the method we needed from that type.
<ul>
<li>Each data type in our environment would only have one record.  Changing the model this way didn&#8217;t really make any sense in our situation.</li>
</ul>
</li>
<li>Create a map from data element name to a class that could be invoked to perform the required actions.
<ul>
<li>This would work, but I was feeling lazy and maintaining a map of names to types didn&#8217;t feel as DRY as I thought it could be.</li>
</ul>
</li>
<li>Take advantage of the Rails constantize method.
<ul>
<li>We could use the name of the record and dynamically map that string to a class with a method or methods that could be invoked at runtime.</li>
</ul>
</li>
</ol>
<p>While any of theses solutions could work, the one that I found the most interesting was the one involving <a href="http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html#M000440">constantize</a> (<span class="file-title-prefix">Module</span><br />
ActiveSupport::CoreExtensions::String::Inflections).  If you have poked around the rails source you see that constantize is used for things like <a href="http://api.rubyonrails.org/classes/ActionController/Macros/InPlaceEditing/ClassMethods.html#M000081" title="in_place_edit from the Rails API">in_place_edit</a> (do a find on an object based on a parameter string).  If I haven&#8217;t lost you yet included below is a code snippet illustrating  how this works and solving my problem.  It&#8217;s important to note that you need to camelize specific_theme_type before calling constantize or it will raise a NameException.  In the example below I&#8217;ve created a rescue block because not all of my  types are mapped to a specific content class and I wanted to fall back to a default in those cases.</p>
<pre style="border:1px solid #eeeeee;"><tt><span style="font-weight:bold;"><span style="color:#0000ff;">begin</span></span>
  content_type <span style="color:#990000;">=</span> <span style="color:#ff0000;">"Content::#{specific_theme_type.camelize}Content"</span><span style="color:#990000;">.</span>constantize
<span style="font-weight:bold;"><span style="color:#0000ff;">rescue</span></span> NameError
  content_type <span style="color:#990000;">=</span> Content<span style="color:#990000;">::</span>Default
<span style="font-weight:bold;"><span style="color:#0000ff;">end</span></span><tt></tt><tt>
content_type<span style="color:#990000;">.</span><span style="color:#990000;"></span>content_method</tt></tt></pre>
<p>I&#8217;ve only touched the surface of things you can do with constantize.  If you have also used constantize or another similar trick, please share it in the comments.</p>
<p><strong>Notes:</strong></p>
<ol>
<li>Single Table Inheritance &#8211; <a href="http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html">Definition of STI</a>, <a href="http://wiki.rubyonrails.org/rails/pages/SingleTableInheritance">STI in Rails</a></li>
<li>Apologies for the small digram, full size available <a href="http://danieloshea.bingodisk.com/public/thrivesmart/themes_model_diag.png" title="Full Size Model Diagram">here</a>.</li>
<li>I am sure there are other solutions, so feel free to leave comments detailing how you would have done it <img src="https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></li>
</ol>
]]></content:encoded>
					
					<wfw:commentRss>https://hackd.wordpress.com/2007/12/01/fun-with-rails-constantize/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">22</post-id>
		<media:content url="https://0.gravatar.com/avatar/673379bc8488f4a9bf2f150252cd5dd9d6e3fce48b94bd33b907f523e9c4acf1?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Dan</media:title>
		</media:content>

		<media:content url="http://danieloshea.bingodisk.com/public/thrivesmart/themes_model_diag.png" medium="image">
			<media:title type="html">Visualization Diagram</media:title>
		</media:content>
	</item>
		<item>
		<title>Sexy Time Zones in Ruby on Rails with Timezone_Fu</title>
		<link>https://hackd.wordpress.com/2007/11/23/sexy-time-zones-in-ruby-on-rails-with-timezone_fu/</link>
					<comments>https://hackd.wordpress.com/2007/11/23/sexy-time-zones-in-ruby-on-rails-with-timezone_fu/#comments</comments>
		
		<dc:creator><![CDATA[Dan]]></dc:creator>
		<pubDate>Sat, 24 Nov 2007 03:29:42 +0000</pubDate>
				<category><![CDATA[rails]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Plugins]]></category>
		<category><![CDATA[ThriveSmart]]></category>
		<guid isPermaLink="false">http://hackd.wordpress.com/2007/11/23/sexy-time-zones-in-ruby-on-rails-with-timezone_fu/</guid>

					<description><![CDATA[As easy as has_timezone :fields =&#62; [ :start_datetime, :end_datetime]. Working with Timezones in Rails even after you have installed the TZInfo plugin is still a pain in the you know what. (You are using TZInfo, right?) I never liked having to jump through hoops converting from UTC to localtime when displaying times to Users. I [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><em><font color="#808080">As easy as </font>has_timezone :fields =&gt; [ :start_datetime, :end_datetime].</em></p>
<p>Working with Timezones in Rails even after you have installed the <a href="http://tzinfo.rubyforge.org/" title="TZInfo">TZInfo</a> plugin is still a pain in the you know what.  (You are using TZInfo, right?)   <img src="https://i0.wp.com/danieloshea.bingodisk.com/public/thrivesmart/timezone_map.jpg" alt="World Timezones" align="right" height="174" width="320" />I never liked having to jump through hoops converting from UTC to localtime when displaying times to Users.  I suppose I could have used Javascript to do the conversion but I prefer to deal with the conversion on the back end.</p>
<p>Adding support for time zones  to our apps wasn&#8217;t very fun.  While adding timezones to another model model for the third or forth time I decided there had to be a better way.   I pointed my browser to the <a href="http://agilewebdevelopment.com/plugins">agile web development plug in</a> site and did a quick search.  I found a couple plug-ins that helped with timezones or helped with date time pickers; but nothing that did quite what I wanted.<span id="more-21"></span>Ideally I wanted a plugin similar to <a href="http://agilewebdevelopment.com/plugins/attachment_fu">attachment_fu</a>.  I wanted to specify within a model a single method that handled all of the setup.  So when I accessed a datetime field the local time would be returned.  I also wanted to be able to set the field to local time and have that value converted to UTC before being saved to the database.  And the plugin had to do all of this with minimal setup and effort on the part of the developer.   Not finding anything that satisfied my requirements I decided to write something.  After an hour or two I put together something that I think is worth sharing.  Included at the bottom of this post are links to grab the plug-in.</p>
<p>While building <a href="http://www.thrivesmart.com/sprout">ThriveSmart Sprout!</a> we used plugins from various developers.  The availability of plugins was on the the great strengths of the Rails comunity.  In honor of <a href="http://techno-weenie.net/">techno weenie</a> and the <a href="http://agilewebdevelopment.com/plugins/attachment_fu">attachment_fu</a> plug-in our plug-in was christened timezone_fu.</p>
<p>Timezone_fu makes it really easy to deal with datetime fields in your models.  It adds a method to your models has_timezone that takes a hash of options.  the README for the plugin describes all of the options but below is an example:</p>
<pre style="border:1px solid #eeeeee;"><tt>  <span style="font-weight:bold;"><span style="color:#0000ff;">class</span></span> Event <span style="color:#990000;">&lt;</span> ActiveRecord<span style="color:#990000;">::</span>Base</tt><tt></tt><tt></tt>
<tt>    has_timezone <span style="color:#990000;">:</span>fields <span style="color:#990000;">=&gt;</span> <span style="color:#990000;">[</span> <span style="color:#990000;">:</span>start_datetime<span style="color:#990000;">,</span> <span style="color:#990000;">:</span>end_datetime<span style="color:#990000;">]</span></tt>
<tt><span style="color:#990000;"></span></tt><tt>  <span style="font-weight:bold;"><span style="color:#0000ff;">end</span></span></tt></pre>
<p>Our Event model has three fields a start_datetime and end_datetime and a timezone.  Adding has_timezone to the model changes the behavior of the two datetime attributes.<br />
Notice below that calling event.start_datetime shows the time in local time (&#8220;America/New York&#8221;).</p>
<pre style="border:1px solid #eeeeee;"><tt><span style="color:#990000;">&gt;&gt;</span></tt><tt> event <span style="color:#990000;">=</span> Event<span style="color:#990000;">.</span>find<span style="color:#990000;">(:</span>first</tt><tt><span style="color:#990000;">)</span></tt><tt><span style="color:#990000;"></span></tt>
<tt><span style="color:#990000;">=&gt;</span> <span style="font-style:italic;"><span style="color:#9a1900;">#&lt;Event:0x1b71b40 @attributes={
      "end_datetime"   =&gt; "2007-11-21 15:00:00",
      "start_datetime" =&gt; "2007-11-21 14:15:00",
      "timezone"       =&gt; "America/New_York"}</span></span></tt><tt>  </tt>
<tt><span style="color:#990000;">&gt;&gt;</span> event<span style="color:#990000;">.</span>start_datetime
<span style="color:#990000;">=&gt;</span> Wed Nov <span style="color:#993399;">21</span> <span style="color:#993399;">09</span><span style="color:#990000;">:</span><span style="color:#993399;">15</span><span style="color:#990000;">:</span><span style="color:#993399;">00</span> UTC <span style="color:#993399;">2007</span></tt><tt>  <span style="color:#990000;">
&gt;&gt;</span> event<span style="color:#990000;">.</span>display_start_datetime  <span style="color:#990000;">
=&gt;</span> <span style="color:#ff0000;">"Nov. 21, 2007 09:15 AM"</span></tt><tt>  <span style="color:#990000;">
&gt;&gt;</span> event<span style="color:#990000;">.</span>utc_start_datetime
<span style="color:#990000;">=&gt;</span> Wed Nov <span style="color:#993399;">21</span> <span style="color:#993399;">14</span><span style="color:#990000;">:</span><span style="color:#993399;">15</span><span style="color:#990000;">:</span><span style="color:#993399;">00</span> UTC <span style="color:#993399;">2007</span></tt></pre>
<p>You can also set the value of the field to a local date/time and it will be converted to UTC automatically:</p>
<pre style="border:1px solid #eeeeee;"><tt><span style="color:#990000;">&gt;&gt;</span> event<span style="color:#990000;">.</span>start_datetime <span style="color:#990000;">=</span> Time<span style="color:#990000;">.</span>now
<span style="color:#990000;">=&gt;</span> Sun Nov <span style="color:#993399;">25</span> <span style="color:#993399;">06</span><span style="color:#990000;">:</span><span style="color:#993399;">26</span><span style="color:#990000;">:</span><span style="color:#993399;">35</span> <span style="color:#990000;">+</span><span style="color:#993399;">0000</span> <span style="color:#993399;">2007</span>
<span style="color:#990000;">=&gt;</span> <span style="font-style:italic;"><span style="color:#9a1900;">#&lt;Biz::Event:0x1b71b40 @attributes={</span></span>
  <span style="color:#ff0000;">"end_datetime"</span>    <span style="color:#990000;">=&gt;</span>  <span style="color:#ff0000;">"2007-11-21 15:00:00"</span>
  <span style="color:#ff0000;">"start_datetime"</span>  <span style="color:#990000;">=&gt;</span>  Sun Nov <span style="color:#993399;">25</span> <span style="color:#993399;">11</span><span style="color:#990000;">:</span><span style="color:#993399;">26</span><span style="color:#990000;">:</span><span style="color:#993399;">35</span> <span style="color:#990000;">+</span><span style="color:#993399;">0000</span> <span style="color:#993399;">2007</span><span style="color:#990000;">,</span>
  <span style="color:#ff0000;">"timezone"</span>        <span style="color:#990000;">=&gt;</span>  <span style="color:#ff0000;">"America/New_York"</span> <span style="color:#ff0000;">}</span>
</tt></pre>
<p>If you want to access the fields and retrieve the database value you can use the utc_field_name method to access the UTC value of the attribute.  The plugin makes a couple of core assumptions.  One it assumes that the default rails timezone is UTC:</p>
<pre style="border:1px solid #eeeeee;"><tt>ENV<span style="color:#990000;">[</span><span style="color:#ff0000;">'TZ'</span><span style="color:#990000;">]</span> <span style="color:#990000;">=</span> <span style="color:#ff0000;">'UTC'</span></tt></pre>
<p>Second it assumes that the model has a timezone attribute named timezone:</p>
<pre style="border:1px solid #eeeeee;"><tt>t<span style="color:#990000;">.</span>column <span style="color:#990000;">:</span>timezone<span style="color:#990000;">,</span> <span style="color:#990000;">:</span>string<span style="color:#990000;">,</span> <span style="color:#990000;">:</span>default <span style="color:#990000;">=&gt;</span> <span style="color:#ff0000;">''</span></tt></pre>
<p>The plug-in depends on <a href="http://tzinfo.rubyforge.org/">TZInfo</a> and has been tested under Rails 1.2.3</p>
<p>You can grab a copy of the plug-in here: <a href="http://www.thrivesmart.com/open_source/timezone_fu">http://www.thrivesmart.com/open_source/timezone_fu</a>.<br />
Or if zipped is more your style: <a href="http://www.thrivesmart.com/open_source/timezone_fu.zip">http://www.thrivesmart.com/open_source/timezone_fu.zip</a></p>
<p>If you love and/ or hate the plug-in feel free to leave your comments below.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://hackd.wordpress.com/2007/11/23/sexy-time-zones-in-ruby-on-rails-with-timezone_fu/feed/</wfw:commentRss>
			<slash:comments>19</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">21</post-id>
		<media:content url="https://0.gravatar.com/avatar/673379bc8488f4a9bf2f150252cd5dd9d6e3fce48b94bd33b907f523e9c4acf1?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Dan</media:title>
		</media:content>

		<media:content url="http://danieloshea.bingodisk.com/public/thrivesmart/timezone_map.jpg" medium="image">
			<media:title type="html">World Timezones</media:title>
		</media:content>
	</item>
		<item>
		<title>Zero to Riding the Rails in Four Months</title>
		<link>https://hackd.wordpress.com/2007/10/14/zero-to-riding-the-rails-in-four-months/</link>
					<comments>https://hackd.wordpress.com/2007/10/14/zero-to-riding-the-rails-in-four-months/#comments</comments>
		
		<dc:creator><![CDATA[Dan]]></dc:creator>
		<pubDate>Mon, 15 Oct 2007 02:49:20 +0000</pubDate>
				<category><![CDATA[rails]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Sprout!]]></category>
		<category><![CDATA[ThriveSmart]]></category>
		<guid isPermaLink="false">http://hackd.wordpress.com/2007/10/14/zero-to-riding-the-rails-in-four-months/</guid>

					<description><![CDATA[Whew! four months of nose-to-the-keyboard development work, and we launched our new product! Because it was the first time we designed, developed, and deployed a complete web application with our new team, we wanted to chronicle our experiences over the whole process &#8211; particularly with Ruby on Rails. We thought doing so would help us [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><img src="https://hackd.wordpress.com/wp-content/uploads/2007/10/rails-podcast.png?w=112&#038;h=144" alt="rails-podcast.png" align="left" height="144" width="112" /><em>Whew! four months of nose-to-the-keyboard development work, and we launched </em><a href="http://www.thrivesmart.com/" id="v33s" title="our new product">our new product</a><em>!  Because it was the first time we designed, developed, and deployed a complete web application with our new team, we wanted to chronicle our experiences over the whole process &#8211; particularly with Ruby on Rails.  We thought doing so would help us improve on our experiences in the future.  And we hope it can help you too&#8230;</em></p>
<p>In the beginning there was Java and it was good, but something was missing. Java as a partner was not particularly pretty, it was not very fun to wake up to in the morning, but it got the job done. In late May Daniel sent an IM to Matt, He was having problems with eclipse and svn and went off on a tangent. The IM went something like this:</p>
<blockquote><p>     <strong>Daniel:</strong> &#8220;I see why the RoR people are in love. Not that SVN has     anything to do with RoR&#8221;<br />
<strong>Matt</strong>: &#8220;RoR?&#8221;<br />
<strong>Daniel</strong>: &#8220;Ruby on Rails, I was playing with it yesterday&#8221;<br />
<strong>Matt</strong>: &#8220;I see, is it good for backend? frontend? both?&#8221;<br />
<strong>Daniel</strong>: &#8220;If you are ok with going with the defaults it lets you focus     only on developing features, so you don&#8217;t have to worry about backend or     frontend. Some of the deployment tools are pretty neat too. Ok, back to     topic&#8230;&#8221;</p></blockquote>
<p>Daniel had just watched the <a href="http://rubyonrails.com/screencasts">Rails   Screencasts</a> and was in love. The concerns we were having with Java and   <a href="http://code.google.com/webtoolkit/">Google Web Toolkit</a> seemed   like they would probably go away with Rails. It took a long time to develop   new features the way we had been doing things. After debating the topic for a   while we had a founder&#8217;s meeting in the car while driving to Target, and   decided: we would devote two weeks to try our hand at porting (rewriting)   YouBook from Java to <a href="http://rubyonrails.com/">Ruby on Rails</a>. We   quickly purchased the PDF+Hard Copies of   &#8220;<a href="http://www.pragprog.com/titles/ruby" id="h7zf" title="Programming Ruby">Programming   Ruby</a>&#8221; and   &#8220;<a href="http://www.pragprog.com/titles/rails2" id="i8db" title="Agile Web Development with Rails">Agile   Web Development with Rails</a>&#8221; from Pragmatic Programmers, and the adventure   began.</p>
<p><span id="more-19"></span>   The first couple weeks were incredibly hard. When you develop with Rails, you   really have to know the Rails Way to be effective, and not feel like you&#8217;re   swimming upstream.  However, within days we were already starting to see   an application take shape. What would have taken us days to change and test in   our old environment we could do in minutes in Rails. The phrase, &#8220;Wow, I can&#8217;t   believe how easy this is&#8221; was repeated time and again for at least the first   month. As great a story as &#8220;How we learned Rails&#8221; might be, this article is   also about the lessons we learned, and what we would do differently &#8211; as well   as some really useful resources we found along the way.</p>
<p><strong>Framework</strong>: Ruby on Rails!<strong><br />
Source Code Control</strong>: Git<strong><br />
Development Methodology</strong>: Speed of development, fixes, and new features</p>
<h3><strong>Why we chose Rails over Java + Google Web Toolkit   (GWT):</strong></h3>
<p>Programming languages &amp; frameworks are just tools. Depending on the job, some tools are better than others.  We started with two tools we thought would be fantastic: Java &amp; the Google Web Toolkit.  We did so because we were experienced with Java web programming, and knew we wanted our application to have AJAX.  Given Matt&#8217;s past employment at Google, the <a href="http://code.google.com/webtoolkit/" id="r.gs" title="GWT">GWT</a> framework seemed like a great fit. We wrote our first web application YouBook for ThriveSmart (our company), which let users book appointments online with businesses that partnered with us.  Given our experience, they were definitely strong tools.  For the next version of YouBook and our new application, we wanted to choose new tools that addressed some frustrations we ran into.  GWT &amp; Java have their strengths, but there were some big concerns:</p>
<blockquote><p>   <strong> Number of <u>Serial</u> HTTP Requests to Render Any Data</strong><br />
The biggest concern we had was that GWT made the first impression of our app   feel slow &#8211; the load. We used Javascript to load and render the data of the   page (in other words, the server didn&#8217;t render any dynamic data onto the   page).  That meant that (1) browser loaded the GWT &#8220;loader&#8221; js file,   which then (2) interpreted and loaded the real GWT compiled javascript, which   then (3) interpreted and then loaded the data (as JS objects which were then   drawn by JS).  Because this all happened in serial, it just made the page   feel slow.</p>
<p><strong> Pages Not Indexable</strong><br />
Another concern was that since our data was loaded in dynamically and not   rendered on the original page, none of the content would have been indexable   by search engines.  Anything that we wanted to have searchable, we   probably would have had to have Java + Struts (or whatever framework) render   itself.  GWT would have had to have been implemented on top of it.</p>
<p><strong>UI more like Swing than HTML+CSS</strong><br />
Although it&#8217;s not perfect, designing layouts in HTML with CSS is incredibly   flexible and elegant. You get a wonderful separation of design and data.    With the UI components that come with GWT, it&#8217;s more like you&#8217;re developing   UIs in Swing, which does not share the same benefits. GWT/Swing makes it easy   to quickly mock up a moderately complex UI, but HTML+CSS gives you great   results, has better design tools, and allows for far more stylish designs &#8211;   which can all be changed with a swap of the CSS.</p>
<p><strong>At the end of the day, it&#8217;s still Java</strong><br />
Java+GWT has some nice benefits: you can understand what&#8217;s going on, because   you design the whole thing.  You can really reduce the number of complex   SQL statements because you have low level control.  With GWT, you have   the same language for both the server and the UI (cool!).  However, at   the end of the day you still have Java code, which is not particularly   elegant, and any plugins you use for uploading, or RESTful design are usually   bloated and not well tested.  Perhaps   <a href="http://paulbuchheit.blogspot.com/2007/05/amazingly-bad-apis.html" id="pn5f" title="Paul Buchheit says it best">Paul   Buchheit says it best</a>.</p></blockquote>
<p>So we were always on the lookout for better tools that came along.  Tools that truly supported our methodology of quickly responding to customer needs and rolling out new features.  Thank goodness we found Rails!  We learned it, practiced, and started writing our app.   And we never looked back.</p>
<p>Let&#8217;s continue with what we love the most about Ruby on Rails &#8211; the community and light-weight plugins, and show you what we were able to implement within our application in short order!</p>
<h3><strong> The Great Rails Community &amp; Plugins</strong></h3>
<p>One of the things that impressed about Ruby and Rails was the community. There was an abundance of information and extensions to the core Rails framework offering functionality that we needed.  Browsing the source code for the plugins was also a great way to expand our Ruby knowledge &#8211; and a great way to expand our webapp features in a lighweight manner.  We list all the tools &amp; plugins we use at the end of the post (appendix).  But here are some interesting pieces of the Rails community in no particular order:</p>
<blockquote><p><a href="http://railscasts.com/" id="kj63" title="Railscasts"><strong>Railscasts</strong></a><br />
Ryan Bates is putting together a library of video podcasts that walk you   though creating a rails application.  Currently at post # 74 I always   find a nice nugget of information in each episode.  It is also nice to   see a topic covered after you have already coded up a solution to find out   that you did it the &#8220;rails way&#8221;.</p>
<p><a href="http://peepcode.com/" id="zgvb" title="Peepcode"><strong>Peepcode</strong></a><br />
The one non-free resource in the list.  Early on we purchased the RESTful   rails episode and recently the Textmate episode.  There are many other   episodes on the site and for the price, they are a fantastic resource for   developers that want to learn a specific subject.</p>
<p><a href="http://wiki.rubyonrails.org/rails" id="x53." title="Rails Wiki"><strong>Rails   Wiki</strong></a><br />
A relatively up to date place to find out information on various recommended   techniques for building your application.</p>
<p><strong> Blogs</strong><br />
There are &#8220;google only knows&#8221; how many blogs offering up all kinds of tips and   tricks for Rails applications.  The one gripe we had with the community   is that many blogs do not insert links into the Wiki and the only way to find   the information was to (1) check the wiki, (2) search for and add it to   del.icio.us</p></blockquote>
<p>After spending days reading blogs, wikis and plugin source code, we learned a ton &#8211; and spent time designing and coding.  At the end of the four months, we ended up with a great webapp, in our eyes.  Here&#8217;s some of the key things we ended up with in short order:</p>
<h3><strong> What We ended up With</strong></h3>
<blockquote><p>   <strong> RESTful Routes</strong><br />
We wanted Sprout! to have pretty URL&#8217;s, with that in mind we looked at the two   Rails routing options and choose the REST option. Once again,   <a href="http://peepcode.com/products/restful-rails" id="fvjh" title="PeepCode came to the rescue">PeepCode   screencasts came to the rescue</a>.</p>
<p><strong>Authentication &amp; Authorization</strong><br />
We started off with the   <a href="http://agilewebdevelopment.com/plugins/restful_authentication" id="dcm3" title="restful_authentication plugin">restful_authentication   plugin</a> and extended it to include authorization per User / Business</p>
<p><a href="http://git.or.cz/" id="vhtz" title="Git"><strong>Git</strong></a><br />
We had worked with centralized repositories for years.  I had not had the   best luck with Subversion. after watching a video:   <a href="http://www.youtube.com/watch?v=4XpnKHJAok8">Linus Torvalds on   Git</a>, and realizing that some of the issues he described we were having we   switched to Git.  We started off with local repositories and pulling   changes between each other with git-deamon.  When we setup our production   server we also created a shared repository we could push and pull changes to   via SSH.  For fun we created a TextMate bundle to assist with commiting,   pushing, pulling and getting status of changes &#8211; which we will release!</p>
<p><a href="http://www.capify.org/" id="rhho" title="Capistrano"><strong>Capistrano</strong></a><strong>   based deployment</strong><br />
Capistrano rocks, we love being able to push changes to the website and the   app with one command and a password.  If you haven&#8217;t checked it out   (Rails project or not), you are doing yourself a dis-service.  It now   takes us about 15 seconds, and we can roll back to any release easily.</p>
<p><strong> Static Asset Hosting</strong><br />
As we got close to deployment we noticed that loading Javascript, images and   style sheets from on host was slowing page loads.  We had already created   Apache rules to serve our static web pages, but that was not enough.    Initially we used the builtin asset host (config.action_controller.asset_host   ) and that was an improvement.  We ran into an issue where our javascript   files (particularly tinyMCE) would make GET requests against the static host   and the inline pop ups stopped working.  We also had issues with HTTPS   pages showing security warnings in internet explorer.  Since we had to   come up with a way to serve javascript differently from images and stylesheets   we figured we would add a requirement to not serve assets from the asset host   if the request was HTTPS.  A slightly modified (for HTTPS) version of   <a href="http://agilewebdevelopment.com/plugins/multi_asset_locations" id="q3io" title="multi-asset-locations plugin">multi-asset-locations   plugin</a> fulfilled our requirements very nicely.</p>
<p><strong>Hosting</strong><br />
For our previous application we had a dedicated server.  The cost was   pretty high, but we could do whatever we wanted to the machine.  We   started looking at Virtual Private Servers as we were getting ready to   deploy.  We knew   <a href="http://www.joyent.com/" id="vak0" title="Joyent">Joyent</a> was the   official rails host, and after poking around we saw that they also hosted   twitter.  We figured with their experience, great prices, and Daniel&#8217;s   bias to Sun gear we would try them out.  It took a little while to get   our first instance (or accelerator as they call it).  Now we have two and   we love it.</p>
<p><strong> Exception Reporting</strong><br />
Having your users get an error page, no matter how pretty it is, sucks!    Going through logs looking for exceptions and stack traces is almost as   fun.  Early in the Beta we started looking at plugins that could help us   by sending emails to the development team when exceptions occurred.  We   tried the   <a href="http://agilewebdevelopment.com/plugins/exception_notifier" id="aety" title="exception_notifier plugin">exception_notifier   plugin</a> but couldn&#8217;t get it to work with Rails 1.2.3.  Instead of   trying to debug the plugin, Daniel wrote his own while Matt and Jenn were   eating dinner.</p>
<p><strong> Performance Monitoring</strong><br />
Being new to Ruby on Rails we are concerned about finding and removing   performance hot spots in an intelligent fashion.  Using the default Rails   logs to do this can be painful.  Thankfully we came across this post   about a   <a href="http://nubyonrails.com/articles/a-hodel-3000-compliant-logger-for-the-rest-of-us" id="mem6" title="Hodel 3000 complaint logger">Hodel   3000 compliant logger</a>.  Now we get a nightly email showing the   performance of the application over the previous day.  The change makes   it nearly impossible to read stack traces in the log.  Thankfully we   already had exception reporting <img src="https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p><strong> Image Uploads</strong><br />
Pictures are a big part of the Sprout! experience.  With   <a href="http://agilewebdevelopment.com/plugins/attachment_fu" id="kc8e" title="Attachment Fu">Attachment Fu</a>, a good bit of Javascript a   <a href="https://hackd.wordpress.com/2007/08/28/part-two-how-to-create-an-image-selection-plugin-for-tinymce-with-ruby-on-rails/" id="zkvz" title="new tinyMCE plugin">new   tinyMCE plugin</a> and a splash of CSS we were off to the races.    Attachment fu managed the the uploaded images, resizing, and storage.    Javascript and   <a href="http://agilewebdevelopment.com/plugins/responds_to_parent" id="z--1" title="responds_to_parent">responds_to_parent</a>   allow us to do uploads without refreshing the page. And to top it off, we used   the   <a href="http://smoothgallery.jondesign.net/" id="ezy." title="JonDesign's SmoothGallery 2.0">JonDesign&#8217;s   SmoothGallery 2.0</a> to display stunning slideshows.</p>
<p><strong>Testing<br />
</strong>When we started porting YouBook, it was very important to us to decrease   the amount of manual testing we had to do.  We started off using the   standard rails functional and unit tests and changed over to using the   test_spec_on_rails plugin after two months.  When creating a new feature   we don&#8217;t always start with tests, but before we push the change, you better   believe the tests are in there.  We both really enjoying seeing the all   green before a commit or right after a pull of the latest code.<strong><br />
</strong></p>
<p><strong>Drag and Drop Sorting, </strong><strong> Javascript callbacks</strong><br />
In our application, it was really important that our users could edit right in   the context of what they&#8217;d see.  This meant heavy javascript.    First, we heavily use the   <a href="http://wiki.script.aculo.us/scriptaculous/show/DragAndDrop" id="lt36" title="Scriptaculous Drag and Drop">Scriptaculous   Drag and Drop</a> code for easy ordering of slideshows or catalog items.    The   <a href="http://weblog.jamisbuck.org/2006/3/27/web-services-rails-style" id="mz" title="built-in javascript callbacks">built-in   javascript callbacks</a> (for different request formats, like JS, ics, etc)   were a lifesaver.  We could respond with javascript directly and have it   rendered in the browser.  It&#8217;s so easy, and really efficient &#8211; no parsing   javascript objects, just javascript code itself!</p></blockquote>
<h3><strong> What We&#8217;d Do Differently</strong></h3>
<p>We had a great introductory ride on Ruby on Rails.  We didn&#8217;t know Ruby   or Rails at all before we started, and we were able to launch a pretty   sophisticated web app in a short amount of time.  But of course, as with   all things, there were mistakes we had to make &#8212; mistakes that we would   rather avoid in the future.</p>
<blockquote><p>   <strong> Design First in HTML + JS</strong><br />
Our biggest mistake: we didn&#8217;t complete our interface design before we started   programming in rails   (<a href="http://gettingreal.37signals.com/" id="-" title="Getting Real">Getting   Real</a> did teach us to   <a href="http://gettingreal.37signals.com/ch09_Interface_First.php" id="qo95" title="Design Interface First">Design   Interface First</a>).  This was completely understandable, because we   didn&#8217;t really know what (design &amp; interface-wise) was really hard, versus   what was easy to implement in rails.  We had to play around with the   programming and implementation before we completely designed our app.  If   we hadn&#8217;t, we might have designed our way into an impossibly difficult   interface to implement in rails.</p>
<p>But now we know what rails can and can&#8217;t do.  And we really can&#8217;t stress   this enough &#8211; <span style="background-color:#ffffcc;"><strong>WE WILL DESIGN OUR   INTERFACE FIRST &#8211; COMPLETELY</strong></span>!  This means we will sit down   together and draw <em>every</em> page out on paper together (we like to do this   over meals).  Once the paper mockups are in order, we will then create   full HTML mockups <em>with javascript</em>.  Once we settle on the user   interface, we&#8217;ll go back and &#8220;fill in the blanks&#8221; with server side code.    The beauty is that in Rails, it really is fill-in-the-blanks, and it makes   design first a breeze.</p>
<p><strong> Good Javascript Libraries</strong><br />
There were a few painful points that we thought took a long time when writing   our app.  One of them was surely javascript.  Although   <a href="http://www.prototypejs.org/" id="wlc." title="prototype">prototype</a>   and   <a href="http://script.aculo.us/" id="kf" title="scriptaculous">scriptaculous</a>   are a good start (particularly because there are great helpers to interface   with them in rails), there is so far to go in this department.  Before we   try to write a lot of javascript, we&#8217;ll be sure to write additional helpers   between rails and our JS code to make it drop-dead-easy to create features.</p>
<p><strong> Use Fixtures Sparingly</strong><br />
When we started testing fixtures provided a way to quickly setup test   data.  However as our models became more complex and the relationships   between them more involved, maintaining fixture data quickly became a   headache.  Going forward we will be using Mocha to create mock objects   for our tests where there is a need to setup relationships between models.</p>
<p><strong>Caching</strong><br />
When we started coding we had discussed implementing caching, but as deadlines   approached we kept putting it off.  Sure enough when the Beta launched,   we didn&#8217;t take advantage of caching.  In the future we know that we will   need to implement caching, but it will probably require a good bit of   refactoring to be effective.</p></blockquote>
<h3><strong>Appendix &#8211; Resources We Used<br />
</strong></h3>
<p><strong>Education</strong></p>
<blockquote><p><a href="http://www.pragprog.com/titles/ruby" id="l.pk" title="Programming Ruby"><strong>Programming Ruby</strong></a><br />
Best book for learning ruby, for noobies.<br />
<a href="http://www.pragprog.com/titles/rails2" id="zjp7" title="Agile Web Development with Ruby on Rails"><strong>Agile   Web Development with Ruby on Rails</strong></a><br />
If you&#8217;ve never done any rails development, prepare to get wowed with this   great introduction.</p>
<p><a href="http://peepcode.com/" id="ix7a" title="PeepCode Screencasts"><strong>PeepCode   Screencasts</strong></a><br />
Regularly expand your Rails repritoire</p>
<p><a href="http://railscasts.com/" id="rfqg" title="Railscasts"><strong>Railscasts</strong></a><br />
Great short podcasts you can subscribe to &#8211; similar to Peepcode but covers   different subjects.</p>
<p><a href="https://hackd.wordpress.com/2007/08/28/part-two-how-to-create-an-image-selection-plugin-for-tinymce-with-ruby-on-rails/" id="flnd" title="Creating an Images plugin for TinyMCE in Rails"><strong>Creating   an Images plugin for TinyMCE in Rails</strong></a><br />
We wrote this little how to =)</p></blockquote>
<p><strong>Development Environment</strong></p>
<blockquote><p><a href="http://git.or.cz/" id="w5rh" title="Git"><strong>Git</strong></a><br />
Solid source code management &#8211; and wicked fast.  Plus you don&#8217;t get SVN   dropplets all over your source directory.<a href="http://locomotive.raaum.org/" id="j574" title="Locomotive"></a></p>
<p><a href="http://locomotive.raaum.org/" id="j574" title="Locomotive"><strong>Locomotive</strong></a>   (Duh)<br />
Get a Mac and then install this 1-stop-shop for rails development (download the ImageMagick Bundle).<br />
<a href="http://nubyonrails.com/articles/autotest-rails" id="qfw6" title="Autotest"><strong>Autotest</strong></a><strong>   &amp;   </strong><a href="http://growl.info/" title="Growl"><strong>Growl</strong></a> (a   gem, not a plugin)<br />
Part of the Zentest suite, autotest runs tests in the background as you modify   files.  It is pretty good at determining what tests need to be run if you   make changes to models, controllers or views.  With Growl notification it   was a lot of fun to see the &#8220;All tests passed&#8221; message pop up.  The &#8220;X   tests failed&#8221; message was not as fun causing many late night head scratching   sessions especially when we were new to Ruby.</p></blockquote>
<p><strong> Ruby On Rails Plugins</strong></p>
<blockquote><p><a href="http://agilewebdevelopment.com/plugins/restful_authentication" id="j3dz" title="Restful Authentication"><strong>Restful   Authentication</strong></a><br />
A well tested and helpful authentication for your webapp on top of RESTful   rails.</p>
<p><a href="http://agilewebdevelopment.com/plugins/attachment_fu" id="j67." title="Attachment Fu"><strong>Attachment   Fu</strong></a><br />
We use it to help us manage uploaded images.  This plugins stand out   quality is how easy it is to integrate.  It comes with helpers for tests,   it is robust offering File, database and Amazon S3 storage options for   uploads.  The other piece of functionality that put a big smile on my   face was the ability to quickly add different image sizes to uploads, and the   simple integration with image manipulation libraries like ImageMagik.</p>
<p><a href="http://svn.techno-weenie.net/projects/plugins/test_spec_on_rails/" id="ohjk" title="Test Spec on Rails"><strong>Test   Spec on Rails</strong></a><br />
About two months into the project we tried to switch from rails builtin   functional tests to using RSpec functional specifications.  The   functional spec tests were easier to read and with specify blocks it was   easier to seperate tests by context such as if the user was an admin,   customer, anonymous, etc.  After an all nighter trying to figure out how   to make autotest run RSpec tests and the three hundred existing tests we were   about to give up when at around five am we came across the test_spec gem and   test_spec_on_rails plugin.  Thankfully it let us use our existing tests   as is, and integrate specifications for future tests.</p>
<p><a href="http://agilewebdevelopment.com/plugins/responds_to_parent" id="x8q8" title="Responds to Parent"><strong>Responds   to Parent</strong></a><br />
This little beauty helped us again in the image upload department.  By   using an iframe for the upload we were able to spare a page refresh after an   upload completed.  We liked it so much we integrated it with the tinyMCE   editor, created our own image select and upload plugin and wrote a how-to   about it.<a href="http://agilewebdevelopment.com/plugins/exception_notifier" id="pyab" title="Exception Notifier Plugin"></a></p>
<p><a href="http://agilewebdevelopment.com/plugins/exception_notifier" id="pyab" title="Exception Notifier Plugin"><strong>Exception   Notifier Plugin</strong></a><br />
Send email notifications when errors occur in a Rails application.    <strong>NOTE</strong>: Has problems with Rails 1.2.3<a href="http://agilewebdevelopment.com/plugins/multi_asset_locations" id="u8yl" title="Multi-Assets Locations Plugin"></a></p>
<p><a href="http://agilewebdevelopment.com/plugins/multi_asset_locations" id="u8yl" title="Multi-Assets Locations Plugin"><strong>Multi-Assets   Locations Plugin</strong></a><br />
Easily map asset host URLs to different asset types (images, javascript,   stylesheets) to hosts like static1.myhost.com, static2.myhost.com to improve   page load time.<br />
<a href="http://nubyonrails.com/articles/a-hodel-3000-compliant-logger-for-the-rest-of-us" id="bf17" title="Hodel 3000 Compliant Logger"><strong>Hodel   3000 Compliant Logger</strong></a><br />
Changes the log format so you can use pl_analyze to gather performance   application for your rails application.</p></blockquote>
<p><strong>Javascript</strong></p>
<blockquote><p><a href="http://www.prototypejs.org/api" id="qxep" title="Prototype API Documentation"><strong>Prototype   API Documentation</strong></a><br />
Way too much time spent in here &#8211; but necessary if you want to code in rails.</p>
<p><a href="http://script.aculo.us/" id="s5wd" title="Scriptaculous Effects"><strong>Scriptaculous   Effects</strong></a> &#8211; Drag N Drop<br />
Javascript effects library including drag and drop, sorting, and highlighting.</p>
<p><a href="http://smoothgallery.jondesign.net/" id="p_e2" title="SmoothGallery 2.0"><strong>SmoothGallery   2.0</strong></a><br />
A fantastic javascript slideshow library by my friend Jonathan Schemoul.</p>
<p><a href="http://agilewebdevelopment.com/plugins/responds_to_parent" id="qqtr" title="Responds To Parent"><strong>Responds   To Parent</strong></a><br />
Help with having a parent of an iframe execute returned javascript code.</p>
<p><a href="http://tinymce.moxiecode.com/" id="ebvm" title="TinyMCE"><strong>TinyMCE</strong></a><br />
A good wysiwyg content editor, which wordpress also uses.</p></blockquote>
<p><strong>Deployment</strong></p>
<blockquote><p><a href="http://www.joyent.com/" id="dxe_" title="Joyent Hosting"><strong>Joyent   Hosting</strong></a><br />
A wonderful Ruby on Rails host &#8211; we love it!</p>
<p><a href="http://www.capify.org/" id="k6_c" title="Capistrano"><strong>Capistrano</strong></a><br />
Deploy your rails app with it, period!</p></blockquote>
]]></content:encoded>
					
					<wfw:commentRss>https://hackd.wordpress.com/2007/10/14/zero-to-riding-the-rails-in-four-months/feed/</wfw:commentRss>
			<slash:comments>25</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">19</post-id>
		<media:content url="https://0.gravatar.com/avatar/673379bc8488f4a9bf2f150252cd5dd9d6e3fce48b94bd33b907f523e9c4acf1?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Dan</media:title>
		</media:content>

		<media:content url="https://hackd.wordpress.com/wp-content/uploads/2007/10/rails-podcast.png" medium="image">
			<media:title type="html">rails-podcast.png</media:title>
		</media:content>
	</item>
		<item>
		<title>Extract Colors from CSS Code</title>
		<link>https://hackd.wordpress.com/2007/10/01/extract-colors-from-css-code/</link>
					<comments>https://hackd.wordpress.com/2007/10/01/extract-colors-from-css-code/#comments</comments>
		
		<dc:creator><![CDATA[Matt]]></dc:creator>
		<pubDate>Mon, 01 Oct 2007 19:57:48 +0000</pubDate>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[User Interface]]></category>
		<guid isPermaLink="false">http://hackd.wordpress.com/2007/10/01/extract-colors-from-css-code/</guid>

					<description><![CDATA[Getting the colors right in CSS can be a bit of a pain without the right tools. An interesting tool I came across extracted the colors from a published site. But I needed something (easy) to use in development. So I wrote a little tool I&#8217;d like to share with you! So I present to [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><a href="https://hackd.wordpress.com/2007/10/01/extract-colors-from-css-code/18/" rel="attachment wp-att-18"><img loading="lazy" src="https://hackd.wordpress.com/wp-content/uploads/2007/10/css-color-extractor_1191268352898.png?w=185&#038;h=119" alt="css-color-extractor_1191268352898.png" align="left" border="1" height="119" width="185" /></a>Getting the colors right in CSS can be a bit of a pain without the right tools.  An interesting tool I came across <a href="http://redalt.com/Tools/I+Like+Your+Colors">extracted the colors</a> from a published site.</p>
<p>But I needed something (easy) to use in development. So I wrote a little tool I&#8217;d like to share with you!</p>
<p><span id="more-16"></span></p>
<p>So I present to you the <strong><a href="http://www.thrivesmart.com/open_source/color-parser.html">CSS Color Extractor</a></strong>, where you can copy and paste CSS code, and it will visually display to you the results of the colors.  For this 0.1 release, it&#8217;s pretty simplistic &#8211; it simply finds #[0-9a-zA-Z] in a closure ({}), and it&#8217;s all written in Javascript.</p>
<p>I hope it&#8217;s helpful to you as you do development &#8211; where my pages wouldn&#8217;t have to be published.  I&#8217;d love feedback, too.</p>
<p>Particularly, if anybody has good ideas of a better way to sort hex values to get the colors in a more useful order, let me know!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://hackd.wordpress.com/2007/10/01/extract-colors-from-css-code/feed/</wfw:commentRss>
			<slash:comments>9</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">16</post-id>
		<media:content url="https://0.gravatar.com/avatar/09722deb67a0ab6414e1b5bc6b190a9b907662a9508c38d8f2bc86afd7b51c84?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">matt</media:title>
		</media:content>

		<media:content url="https://hackd.wordpress.com/wp-content/uploads/2007/10/css-color-extractor_1191268352898.png" medium="image">
			<media:title type="html">css-color-extractor_1191268352898.png</media:title>
		</media:content>
	</item>
		<item>
		<title>Part Two: How to Create an Image Selection &#038; Upload Plugin for tinyMCE with Ruby on Rails</title>
		<link>https://hackd.wordpress.com/2007/08/28/part-two-how-to-create-an-image-selection-plugin-for-tinymce-with-ruby-on-rails/</link>
					<comments>https://hackd.wordpress.com/2007/08/28/part-two-how-to-create-an-image-selection-plugin-for-tinymce-with-ruby-on-rails/#comments</comments>
		
		<dc:creator><![CDATA[Dan]]></dc:creator>
		<pubDate>Wed, 29 Aug 2007 07:56:43 +0000</pubDate>
				<category><![CDATA[User Interface]]></category>
		<guid isPermaLink="false">http://hackd.wordpress.com/2007/08/28/part-two-how-to-create-an-image-selection-plugin-for-tinymce-with-ruby-on-rails/</guid>

					<description><![CDATA[Update: A sample project is now available In the first part of our how-to we created a tinyMCE plugin with a dynamic image selector panel based on the advimage plugin. Now we will add functionality to upload images or select an existing image. Our plugin needed to satisfy the following requirements: Use the existing inline [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><strong>Update</strong>: A <a href="http://www.thrivesmart.com/open_source/image_select_demo_v1.0.1.zip">sample project</a> is now available</p>
<p>In the <a href="https://hackd.wordpress.com/2007/08/23/how-to-create-an-image-selction-plugin-for-tinymce-with-ruby-on-rails/" title="How to Create an Image Selection Plugin for tinyMCE with Ruby on Rails">first part of our how-to</a> we created a tinyMCE plugin with a dynamic image selector panel based on the advimage plugin. Now we will add functionality to upload images or select an existing image.</p>
<p>Our plugin needed to satisfy the following requirements:</p>
<ul>
<li>Use the existing inline popup (IFRAME) adding a form  for uploading an image. We did not want the user to be directed to another page or create a pop up window.</li>
<li>In javascript determine which controller to call in the form because we can not pass a variable from the parent  to the image selection IFRAME.</li>
<li>The image selection IFRAME should not reload when the form is submitted. Reloading the IFRAME would trigger another fetch of uploaded images and that should be avoided.</li>
<li>After an image is successfully uploaded the source and alternative text fields should be set as if the user had clicked on an existing image and the IFRAME should then disappear using the plugins existing functionality.</li>
</ul>
<p><a href="https://hackd.wordpress.com/wp-content/uploads/2007/08/picture-1.png" title="picture-1.png"></a></p>
<p style="text-align:center;"><a href="https://hackd.wordpress.com/wp-content/uploads/2007/08/picture-1.png" title="picture-1.png"><img src="https://hackd.wordpress.com/wp-content/uploads/2007/08/picture-1.png?w=450" alt="picture-1.png" /><span id="more-13"></span></a></p>
<p><a href="https://hackd.wordpress.com/wp-content/uploads/2007/08/picture-1.png" title="picture-1.png"></a>To follow along with this tutorial you will need:</p>
<ul>
<li>The updated advimage plugin from the end of <a href="https://hackd.wordpress.com/2007/08/23/how-to-create-an-image-selction-plugin-for-tinymce-with-ruby-on-rails/">How to Create an Image Selection Plugin for tinyMCE.</a></li>
<li>The  <a href="http://sean.treadway.info/svn/plugins/responds_to_parent/">responds_to_parent</a> rails plugin [1] installed, Sean Treadway has a great tutorial on <a href="http://sean.treadway.info/articles/2006/05/29/iframe-remoting-made-easy">using the plugin within a rails project.</a></li>
</ul>
<p>With what we want our updated plugin to do, let&#8217;s get started!</p>
<ol>
<li>The original image.htm (tiny_mce/plugins/ts_advimage/image.htm) has a form tag right after the body tag, we need to relocate this form in order for our image upload to function properly:
<pre style="border:1px solid #eeeeee;overflow:auto;"><tt><span style="font-weight:bold;"><span style="color:#0000ff;">&lt;body</span></span> <span style="color:#009900;">id</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"advimage"</span> <span style="color:#009900;">onload</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"tinyMCEPopup.executeOnLoad('init();');"</span> <span style="color:#009900;">style</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"display: none"</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;</span></span>

    <span style="font-weight:bold;background-color:#ffffcc;"><span style="font-weight:bold;"><span style="color:#0000ff;">&lt;form</span></span> <span style="color:#009900;">onsubmit</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"insertAction();return false;"</span> <span style="color:#009900;">action</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"#"</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;</span></span></span>

</tt></pre>
<p>Relocate the form just before the tabs div:</p>
<pre style="border:1px solid #eeeeee;overflow:auto;"><tt><span style="font-weight:bold;"><span style="color:#0000ff;">&lt;form</span></span> <span style="color:#009900;">onsubmit</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"insertAction();return false;"</span> <span style="color:#009900;">action</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"#"</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;</span></span>

 <span style="font-weight:bold;"><span style="color:#0000ff;">&lt;div</span></span> <span style="color:#009900;">class</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"tabs"</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;</span></span>

</tt></pre>
</li>
<li>Add a form for the image upload image.htm.  Create a new div called &#8220;image-upload&#8221; to house the form. The form needs to have multipart/form-data encoding and will call a javascript function ts_onload (which we will write shortly) on submit. The target for our form is html_editor_image_upload_frame which we will create dynamically to avoid javascript errors when the plugin removes the IFRAME containing the inline popup window.
<pre style="border:1px solid #eeeeee;overflow:auto;"><tt><span style="font-weight:bold;"><span style="color:#0000ff;">&lt;div</span></span> <span style="color:#009900;">id</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"image-upload"</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;</span></span>

  <span style="font-weight:bold;"><span style="color:#0000ff;">&lt;fieldset&gt;</span></span>

    <span style="font-weight:bold;"><span style="color:#0000ff;">&lt;legend&gt;</span></span>Upload New Image<span style="font-weight:bold;"><span style="color:#0000ff;">&lt;/legend&gt;</span></span></tt><tt>
</tt><tt>    <span style="font-weight:bold;"><span style="color:#0000ff;">&lt;form</span></span> <span style="color:#009900;">id</span><span style="color:#990000;">=</span><span style="color:#009900;">'image_upload_form'</span> <span style="color:#009900;">enctype</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"multipart/form-data"</span> <span style="color:#009900;">method</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"post"</span> <span style="color:#009900;">onsubmit</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"ts_onload(); return true;"</span> <span style="color:#009900;">target</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"html_editor_image_upload_frame"</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;</span></span>

      <span style="font-weight:bold;"><span style="color:#0000ff;">&lt;input</span></span> <span style="color:#009900;">class</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"input-file"</span> <span style="color:#009900;">id</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"image_uploaded_data"</span> <span style="color:#009900;">name</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"image[uploaded_data]"</span> <span style="color:#009900;">size</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"30"</span> <span style="color:#009900;">type</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"file"</span> <span style="font-weight:bold;"><span style="color:#0000ff;">/&gt;</span></span>

      <span style="font-weight:bold;"><span style="color:#0000ff;">&lt;div</span></span> <span style="color:#009900;">class</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"submit"</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;</span></span>

        <span style="font-weight:bold;"><span style="color:#0000ff;">&lt;input</span></span> <span style="color:#009900;">class</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"input-submit"</span> <span style="color:#009900;">name</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"commit"</span> <span style="color:#009900;">type</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"submit"</span> <span style="color:#009900;">value</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"Upload &amp; Insert"</span> <span style="font-weight:bold;"><span style="color:#0000ff;">/&gt;</span></span>

      <span style="font-weight:bold;"><span style="color:#0000ff;">&lt;/div&gt;</span></span>

    <span style="font-weight:bold;"><span style="color:#0000ff;">&lt;/form&gt;</span></span>

  <span style="font-weight:bold;"><span style="color:#0000ff;">&lt;/fieldset&gt;</span></span>

<span style="font-weight:bold;"><span style="color:#0000ff;">&lt;/div&gt;</span></span>

</tt></pre>
</li>
<li>Adding the form to the panel breaks the plugin because the plugin was originally written assuming that there would only be one form. We need to change instances of document.forms[0] to document.forms[1].  We could simple do a find and replace but if we ever add a form in the future we would have to do that again.  Instead let&#8217;s create a function called formElement that returns the proper form:
<pre style="border:1px solid #eeeeee;overflow:auto;"><tt><span style="font-weight:bold;"><span style="color:#0000ff;">function</span></span> <span style="font-weight:bold;"><span style="color:#000000;">formElement</span></span><span style="color:#990000;">()</span> <span style="color:#ff0000;">{</span>

 <span style="font-weight:bold;"><span style="color:#0000ff;">return</span></span> document<span style="color:#990000;">.</span>forms<span style="color:#990000;">[</span><span style="color:#993399;">1</span><span style="color:#990000;">];</span>

<span style="color:#ff0000;">}</span></tt><tt>
</tt></pre>
<p>Now, search for instances of document.forms[0] and replace them with calls to formElement(); (there should be sixteen).</li>
<li>Create  javascript functions to create the IFRAME and determine the path for the form action in tiny_mce/plugins/ts_advimage/jscripts/functions.jsts_onload: Create a hidden one pixel by one pixel IFRAME with an id of html_editor_image_upload_frame and add it to the end of the image-upload div we created in step two.  The function also modifies our form action with the result from ts_upload_image_path().  The code highlighted below was generated [2] by <a href="http://muffinresearch.co.uk/code/javascript/DOMTool/">DOMTool v1.1</a>
<pre style="border:1px solid #eeeeee;overflow:auto;"><tt><span style="font-weight:bold;"><span style="color:#0000ff;">function</span></span> <span style="font-weight:bold;"><span style="color:#000000;">ts_onload</span></span><span style="color:#990000;">()</span><span style="color:#ff0000;">{</span>

 <span style="font-weight:bold;background-color:#ffffcc;"><span style="font-weight:bold;"><span style="color:#0000ff;">var</span></span> iframe1<span style="color:#990000;">=</span><span style="font-weight:bold;"><span style="color:#000000;">ts_ce</span></span><span style="color:#990000;">(</span><span style="color:#ff0000;">'iframe'</span><span style="color:#990000;">,</span><span style="color:#ff0000;">'html_editor_image_upload_frame'</span><span style="color:#990000;">);</span>

 iframe1<span style="color:#990000;">.</span><span style="font-weight:bold;"><span style="color:#000000;">setAttribute</span></span><span style="color:#990000;">(</span><span style="color:#ff0000;">'src'</span><span style="color:#990000;">,</span><span style="color:#ff0000;">'about:blank'</span><span style="color:#990000;">);</span>

 iframe1<span style="color:#990000;">.</span>style<span style="color:#990000;">.</span>border<span style="color:#990000;">=</span><span style="color:#ff0000;">"0px none"</span><span style="color:#990000;">;</span>

 iframe1<span style="color:#990000;">.</span>style<span style="color:#990000;">.</span>position<span style="color:#990000;">=</span><span style="color:#ff0000;">"absolute"</span><span style="color:#990000;">;</span>

 iframe1<span style="color:#990000;">.</span>style<span style="color:#990000;">.</span>width<span style="color:#990000;">=</span><span style="color:#ff0000;">"1px"</span><span style="color:#990000;">;</span>

 iframe1<span style="color:#990000;">.</span>style<span style="color:#990000;">.</span>height<span style="color:#990000;">=</span><span style="color:#ff0000;">"1px"</span><span style="color:#990000;">;</span>

 iframe1<span style="color:#990000;">.</span>style<span style="color:#990000;">.</span>visibility<span style="color:#990000;">=</span><span style="color:#ff0000;">"hidden"</span><span style="color:#990000;">;</span>

 iframe1<span style="color:#990000;">.</span><span style="font-weight:bold;"><span style="color:#000000;">setAttribute</span></span><span style="color:#990000;">(</span><span style="color:#ff0000;">'id'</span><span style="color:#990000;">,</span><span style="color:#ff0000;">'html_editor_image_upload_frame'</span></span><span style="color:#990000;">);</span>

 $<span style="color:#990000;">(</span><span style="color:#ff0000;">'image-upload'</span><span style="color:#990000;">).</span><span style="font-weight:bold;"><span style="color:#000000;">appendChild</span></span><span style="color:#990000;">(</span>iframe1<span style="color:#990000;">);</span>

 $<span style="color:#990000;">(</span><span style="color:#ff0000;">'image_upload_form'</span><span style="color:#990000;">).</span><span style="font-weight:bold;"><span style="color:#000000;">setAttribute</span></span><span style="color:#990000;">(</span><span style="color:#ff0000;">"action"</span><span style="color:#990000;">,</span> <span style="font-weight:bold;"><span style="color:#000000;">ts_upload_image_path</span></span><span style="color:#990000;">());</span>

<span style="color:#ff0000;">}</span></tt><tt>
</tt></pre>
<p>ts_ce: A helper for creating the iframe</p>
<pre style="border:1px solid #eeeeee;overflow:auto;">
<tt><span style="font-weight:bold;"><span style="color:#0000ff;">function</span></span> <span style="font-weight:bold;"><span style="color:#000000;">ts_ce</span></span><span style="color:#990000;">(</span>tag<span style="color:#990000;">,</span>name<span style="color:#990000;">)</span><span style="color:#ff0000;">{</span>

  <span style="font-weight:bold;"><span style="color:#0000ff;">if</span></span> <span style="color:#990000;">(</span>name <span style="color:#990000;">&amp;&amp;</span> window<span style="color:#990000;">.</span>ActiveXObject<span style="color:#990000;">)</span><span style="color:#ff0000;">{</span>

    element <span style="color:#990000;">=</span> document<span style="color:#990000;">.</span><span style="font-weight:bold;"><span style="color:#000000;">createElement</span></span><span style="color:#990000;">(</span><span style="color:#ff0000;">'&lt;'</span><span style="color:#990000;">+</span>tag<span style="color:#990000;">+</span><span style="color:#ff0000;">' name="'</span><span style="color:#990000;">+</span>name<span style="color:#990000;">+</span><span style="color:#ff0000;">'"&gt;'</span><span style="color:#990000;">);</span>

  <span style="color:#ff0000;">}</span><span style="font-weight:bold;"><span style="color:#0000ff;">else</span></span><span style="color:#ff0000;">{</span>

    element <span style="color:#990000;">=</span> document<span style="color:#990000;">.</span><span style="font-weight:bold;"><span style="color:#000000;">createElement</span></span><span style="color:#990000;">(</span>tag<span style="color:#990000;">);</span>

    element<span style="color:#990000;">.</span><span style="font-weight:bold;"><span style="color:#000000;">setAttribute</span></span><span style="color:#990000;">(</span><span style="color:#ff0000;">'name'</span><span style="color:#990000;">,</span>name<span style="color:#990000;">);</span>

  <span style="color:#ff0000;">}</span>

  <span style="font-weight:bold;"><span style="color:#0000ff;">return</span></span> element<span style="color:#990000;">;</span>

<span style="color:#ff0000;">}</span></tt><tt>
</tt><tt><span style="font-weight:bold;"><span style="color:#0000ff;"></span></span></tt>

<tt>
</tt></pre>
<p>ts_upload_image_path: Determine the action for the image upload form based on the URI of the parent. Divide the path into segments  delimited by  a forward slash. Our path_prefix is always the token after the domain name.  The result is  a string used to call the controller with the action for uploading images.</p>
<pre style="border:1px solid #eeeeee;overflow:auto;"><tt><span style="font-weight:bold;"><span style="color:#0000ff;">function</span></span> <span style="font-weight:bold;"><span style="color:#000000;">ts_upload_image_path</span></span><span style="color:#990000;">()</span> <span style="color:#ff0000;">{</span>

  path_prefix <span style="color:#990000;">=</span> window<span style="color:#990000;">.</span>parent<span style="color:#990000;">.</span>location<span style="color:#990000;">.</span>pathname<span style="color:#990000;">.</span><span style="font-weight:bold;"><span style="color:#000000;">split</span></span><span style="color:#990000;">(</span><span style="color:#ff0000;">"/"</span><span style="color:#990000;">)[</span><span style="color:#993399;">1</span><span style="color:#990000;">];</span>

  to_path <span style="color:#990000;">=</span> <span style="color:#ff0000;">"/"</span> <span style="color:#990000;">+</span> path_prefix <span style="color:#990000;">+</span> <span style="color:#ff0000;">"/manage_images.js"</span><span style="color:#990000;">;</span>

  <span style="font-weight:bold;"><span style="color:#0000ff;">return</span></span> to_path<span style="color:#990000;">;</span>

<span style="color:#ff0000;">}</span>

    </tt></pre>
</li>
<li> With the HTML and javascript completed, let&#8217;s revisit our manage images controller. In part one our controllers respond_to block looked like this:
<pre style="border:1px solid #eeeeee;overflow:auto;"><tt>    respond_to <span style="font-weight:bold;"><span style="color:#0000ff;">do</span></span> <span style="color:#990000;">|</span>format<span style="color:#990000;">|</span>

      format<span style="color:#990000;">.</span>html

      format<span style="color:#990000;">.</span>js

    <span style="font-weight:bold;"><span style="color:#0000ff;">end</span></span>

</tt></pre>
<p>We need to modify our create action so it notifies the parent IFRAME that the image was uploaded.  We will use a responds_to_parent block to call the javascript ts_insert_image function we wrote in part one:</p>
<pre style="border:1px solid #eeeeee;overflow:auto;"><tt><span style="font-weight:bold;"><span style="color:#0000ff;">def</span></span> create

  <span style="color:#009900;">@image</span> <span style="color:#990000;">=</span> handle_uploaded_image params<span style="color:#990000;">[:</span>image<span style="color:#990000;">]</span>

  respond_to <span style="font-weight:bold;"><span style="color:#0000ff;">do</span></span> <span style="color:#990000;">|</span>format<span style="color:#990000;">|</span>

    <span style="font-weight:bold;"><span style="color:#0000ff;">if</span></span> <span style="color:#009900;">@image</span><span style="color:#990000;">.</span>save

      format<span style="color:#990000;">.</span>js <span style="font-weight:bold;"><span style="color:#0000ff;">do</span></span>

        responds_to_parent <span style="font-weight:bold;"><span style="color:#0000ff;">do</span></span>

          render <span style="color:#990000;">:</span>update <span style="font-weight:bold;"><span style="color:#0000ff;">do</span></span> <span style="color:#990000;">|</span>page<span style="color:#990000;">|</span>

            page <span style="color:#990000;">&lt;&lt;</span> <span style="color:#ff0000;">"ts_insert_image('#{@image.public_filename()}', '#{@image.name}');"</span>

          <span style="font-weight:bold;"><span style="color:#0000ff;">end</span></span>

        <span style="font-weight:bold;"><span style="color:#0000ff;">end</span></span>

      <span style="font-weight:bold;"><span style="color:#0000ff;">end</span></span>

    <span style="font-weight:bold;"><span style="color:#0000ff;">else</span></span>

      format<span style="color:#990000;">.</span>js <span style="font-weight:bold;"><span style="color:#0000ff;">do</span></span>

        responds_to_parent <span style="font-weight:bold;"><span style="color:#0000ff;">do</span></span>

          render <span style="color:#990000;">:</span>update <span style="font-weight:bold;"><span style="color:#0000ff;">do</span></span> <span style="color:#990000;">|</span>page<span style="color:#990000;">|</span>

            page<span style="color:#990000;">.</span>alert<span style="color:#990000;">(</span><span style="color:#ff0000;">'sorry, error uploading image'</span><span style="color:#990000;">)</span>

          <span style="font-weight:bold;"><span style="color:#0000ff;">end</span></span>

        <span style="font-weight:bold;"><span style="color:#0000ff;">end</span></span>

      <span style="font-weight:bold;"><span style="color:#0000ff;">end</span></span>

    <span style="font-weight:bold;"><span style="color:#0000ff;">end</span></span>

  <span style="font-weight:bold;"><span style="color:#0000ff;">end</span></span>

<span style="font-weight:bold;"><span style="color:#0000ff;">end</span></span></tt><tt>
</tt></pre>
</li>
<li>One final step.  We need to modify the responds_to_parent plugin (vendor/plugins/responds_to_parent/lib/responds_to_parent.rb) to fix a javascript error caused when the IFRAME is removed from the DOM by the tinyMCE plugin. Change the rendor block near the end of the file from:
<pre style="border:1px solid #eeeeee;overflow:auto;"><tt>render <span style="color:#990000;">:</span>text <span style="color:#990000;">=&gt;</span> "<span style="color:#ff0000;">&lt;html&gt;&lt;body&gt;&lt;script type='text/javascript' charset='utf-8'&gt;</span>

        var loc <span style="color:#990000;">=</span> document<span style="color:#990000;">.</span>location<span style="color:#990000;">;</span>

        with<span style="color:#990000;">(</span>window<span style="color:#990000;">.</span>parent<span style="color:#990000;">)</span> <span style="color:#ff0000;">{</span> setTimeout<span style="color:#990000;">(</span>function<span style="color:#990000;">()</span> <span style="color:#ff0000;">{</span> window<span style="color:#990000;">.</span>eval<span style="color:#990000;">(</span><span style="color:#ff0000;">'#{script}'</span><span style="color:#990000;">);</span> loc<span style="color:#990000;">.</span>replace<span style="color:#990000;">(</span><span style="color:#ff0000;">'about:blank'</span><span style="color:#990000;">);</span> <span style="color:#ff0000;">}</span><span style="color:#990000;">,</span> <span style="color:#993399;">1</span><span style="color:#990000;">)</span> <span style="color:#ff0000;">}</span>

      <span style="color:#ff0000;">&lt;/script&gt;&lt;/body&gt;&lt;/html&gt;</span>"

</tt></pre>
<p>To:</p>
<pre style="border:1px solid #eeeeee;overflow:auto;"><tt>render <span style="color:#990000;">:</span>text <span style="color:#990000;">=&gt;</span> "<span style="color:#ff0000;">&lt;html&gt;&lt;body&gt;&lt;script type='text/javascript' charset='utf-8'&gt;</span>

  var loc <span style="color:#990000;">=</span> document<span style="color:#990000;">.</span>location<span style="color:#990000;">;</span>

  with<span style="color:#990000;">(</span>window<span style="color:#990000;">.</span>parent<span style="color:#990000;">)</span> <span style="color:#ff0000;">{</span> setTimeout<span style="color:#990000;">(</span>function<span style="color:#990000;">()</span> <span style="color:#ff0000;">{</span> window<span style="color:#990000;">.</span>eval<span style="color:#990000;">(</span><span style="color:#ff0000;">'#{script}'</span><span style="color:#990000;">);</span><span style="font-weight:bold;background-color:#ffffcc;"> try <span style="color:#ff0000;">{</span> loc<span style="color:#990000;">.</span>replace<span style="color:#990000;">(</span><span style="color:#ff0000;">'about:blank'</span><span style="color:#990000;">);</span> <span style="color:#ff0000;">}</span> <span style="font-weight:bold;"><span style="color:#0000ff;">catch</span></span><span style="color:#990000;">(</span>ignored<span style="color:#990000;">)</span><span style="color:#ff0000;">{}</span> <span style="color:#ff0000;">}</span></span><span style="color:#990000;">,</span> <span style="color:#993399;">1</span><span style="color:#990000;">)</span> <span style="color:#ff0000;">}</span>

<span style="color:#ff0000;">&lt;/script&gt;&lt;/body&gt;&lt;/html&gt;</span>"</tt><tt>
</tt></pre>
</li>
</ol>
<p>You now have a new tinyMCE image plugin that allows a user to select an existing uploaded image or use a form to upload a new image. Once the image is uploaded the IFRAME is removed from the DOM and the image  is inserted into the tinyMCE text box.</p>
<p><strong>Notes:</strong></p>
<ol>
<li>The responds_to_parent plugin  allows   &#8220;AJAX&#8221; style file uploads  by posting a form to a hidden IFRAME.</li>
<li>Dynamic IFRAME  javascript code was generated by  <a href="http://muffinresearch.co.uk/code/javascript/DOMTool/">http://muffinresearch.co.uk/code/javascript/DOMTool/ </a>&#8211; &#8220;The compatibility mode for attributes in Internet Explorer is only required should the user need to use innerHTML or outerHTML to get hold of the markup for a form. Using either name properties or setAttribute results in the name attributes being present in the document but not available to innerHTML or outerHTML. When disabled DOMTool uses setAttribute to generate name attributes&#8221;</li>
</ol>
]]></content:encoded>
					
					<wfw:commentRss>https://hackd.wordpress.com/2007/08/28/part-two-how-to-create-an-image-selection-plugin-for-tinymce-with-ruby-on-rails/feed/</wfw:commentRss>
			<slash:comments>28</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">13</post-id>
		<media:content url="https://0.gravatar.com/avatar/673379bc8488f4a9bf2f150252cd5dd9d6e3fce48b94bd33b907f523e9c4acf1?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Dan</media:title>
		</media:content>

		<media:content url="https://hackd.wordpress.com/wp-content/uploads/2007/08/picture-1.png" medium="image">
			<media:title type="html">picture-1.png</media:title>
		</media:content>
	</item>
		<item>
		<title>How-To Make a Rails Partial With Optional Locals (Parameters)</title>
		<link>https://hackd.wordpress.com/2007/08/25/how-to-make-a-rails-partial-with-optional-locals-parameters/</link>
					<comments>https://hackd.wordpress.com/2007/08/25/how-to-make-a-rails-partial-with-optional-locals-parameters/#comments</comments>
		
		<dc:creator><![CDATA[Matt]]></dc:creator>
		<pubDate>Sun, 26 Aug 2007 05:57:00 +0000</pubDate>
				<category><![CDATA[DRY]]></category>
		<category><![CDATA[partials]]></category>
		<guid isPermaLink="false">http://hackd.wordpress.com/2007/08/25/how-to-make-a-rails-partial-with-optional-locals-parameters/</guid>

					<description><![CDATA[Sorry, this article has moved! http://hackd.thrivesmarthq.com/how-to-make-a-rails-partial-with-optional-locals-parameters]]></description>
										<content:encoded><![CDATA[<p><strong>Sorry, this </strong><a href="http://hackd.thrivesmarthq.com/how-to-make-a-rails-partial-with-optional-locals-parameters"><strong>article has moved</strong></a><strong>!</strong></p>
<p><a href="http://hackd.thrivesmarthq.com/how-to-make-a-rails-partial-with-optional-locals-parameters"><strong>http://hackd.thrivesmarthq.com/how-to-make-a-rails-partial-with-optional-locals-parameters</strong></a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://hackd.wordpress.com/2007/08/25/how-to-make-a-rails-partial-with-optional-locals-parameters/feed/</wfw:commentRss>
			<slash:comments>17</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">12</post-id>
		<media:content url="https://0.gravatar.com/avatar/09722deb67a0ab6414e1b5bc6b190a9b907662a9508c38d8f2bc86afd7b51c84?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">matt</media:title>
		</media:content>
	</item>
		<item>
		<title>How to Create an Image Selection Plugin for tinyMCE with Ruby on Rails</title>
		<link>https://hackd.wordpress.com/2007/08/23/how-to-create-an-image-selction-plugin-for-tinymce-with-ruby-on-rails/</link>
					<comments>https://hackd.wordpress.com/2007/08/23/how-to-create-an-image-selction-plugin-for-tinymce-with-ruby-on-rails/#comments</comments>
		
		<dc:creator><![CDATA[Dan]]></dc:creator>
		<pubDate>Thu, 23 Aug 2007 04:35:12 +0000</pubDate>
				<category><![CDATA[User Interface]]></category>
		<guid isPermaLink="false">http://hackd.wordpress.com/2007/08/23/how-to-create-an-image-selction-plugin-for-tinymce-with-ruby-on-rails/</guid>

					<description><![CDATA[TinyMCE is a great content editor written in javascript from the folks at Moxiecode systems. We created a plugin for tinyMCE that allows users to select images from a selection of thumbnails instead of having to type a URL into a popup. This is part one of a two part tutorial on creating a custom [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><a href="http://tinymce.moxiecode.com/" title="tinyMCE" target="_blank">TinyMCE</a> is a great content editor written in javascript from the folks at Moxiecode systems.  We created a plugin for tinyMCE that allows users to select images from a selection of thumbnails instead of having to type a URL into a popup.  This is part one of a two part tutorial on creating a custom tinyMCE plugin for image selection.  Part one covers the basics of getting the plugin created.  Part two will add image upload functionality.  At the end of this tutorial you should have a tinyMCE popup window like this:</p>
<p style="text-align:center;"><img src="https://hackd.wordpress.com/wp-content/uploads/2007/08/picture-3.png?w=450" alt="picture-3.png" /></p>
<p>Some administrative details before we get started.  You will need a couple things before you can follow along:</p>
<ol>
<li>A working rails project and some images.</li>
<li>TinyMCE installed and working &#8211; A tutorial for that is <a href="http://wiki.moxiecode.com/index.php/TinyMCE:Installation">here</a></li>
</ol>
<p><span id="more-9"></span><br />
We start a plugin that comes with tinyMCE called advimage and modify it by creating a a tab called uploaded images that will contain thumbnail images that can be selected by clicking one of them.  After being clicked the window should close and the image should appear in the tinyMCE enabled text box.  We want to keep the ability to provide a URL and alt text manually via the general tab.  With that out of the way, lets jump into the code!</p>
<ol>
<li>Navigate to the tiny_mce/plugins directory.</li>
<li>make a copy of the advimage directory, I called mine ts_advimage,</li>
<li>open ts_advimage/image.htm (or whatever you called your directory, from here on it will be ts_advimage)</li>
<li>We need to add prototype.js to the head section because we are going to use AJAX to fetch the images from our controller:
<pre style="overflow:auto;"> <tt><span style="font-weight:bold;"><span style="color:#0000ff;">&lt;script</span></span> <span style="color:#009900;">language</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"javascript"</span> <span style="color:#009900;">type</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"text/javascript"</span> <span style="color:#009900;">src</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"/javascripts/prototype.js"</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;&lt;/script&gt;</span></span></tt></pre>
</li>
<li>look for the div with class=tabs and add code for a new tab:
<pre style="overflow:auto;"><tt><span style="font-weight:bold;"><span style="color:#0000ff;">&lt;div</span></span> <span style="color:#009900;">class</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"tabs"</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;</span></span></tt><tt> <span style="font-weight:bold;"><span style="color:#0000ff;">&lt;ul&gt;</span></span></tt>
<tt></tt><tt>  <span style="font-weight:bold;"><span style="color:#0000ff;">&lt;li</span></span> <span style="color:#009900;">id</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"dynamic_select_tab"</span> <span style="color:#009900;">class</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"current"</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;&lt;span&gt;&lt;a</span></span> <span style="color:#009900;">href</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"javascript:mcTabs.displayTab('dynamic_select_tab','dynamic_select_panel');"</span> <span style="color:#009900;">onmousedown</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"return false;"</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;</span></span>Uploaded Images<span style="font-weight:bold;"><span style="color:#0000ff;">&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;</span></span></tt><tt></tt>
<span style="font-weight:bold;"><tt>  &lt;!--- existing plugin tab code ---&gt;</tt></span>
<tt></tt><tt>  <span style="font-weight:bold;"><span style="color:#0000ff;">&lt;li</span></span> <span style="color:#009900;">id</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"general_tab"</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;&lt;span&gt;&lt;a</span></span> <span style="color:#009900;">href</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"javascript:mcTabs.displayTab('general_tab','general_panel');"</span> <span style="color:#009900;">onmousedown</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"return false;"</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;</span></span>{$lang_advimage_tab_general}<span style="font-weight:bold;"><span style="color:#0000ff;">&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;</span></span></tt>
<tt>  <span style="font-weight:bold;"><span style="color:#0000ff;">&lt;li</span></span> <span style="color:#009900;">id</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"appearance_tab"</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;&lt;span&gt;&lt;a</span></span> <span style="color:#009900;">href</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"javascript:mcTabs.displayTab('appearance_tab','appearance_panel');"</span> <span style="color:#009900;">onmousedown</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"return false;"</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;</span></span>{$lang_advimage_tab_appearance}<span style="font-weight:bold;"><span style="color:#0000ff;">&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;</span></span></tt>
<tt>  <span style="font-weight:bold;"><span style="color:#0000ff;">&lt;li</span></span> <span style="color:#009900;">id</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"advanced_tab"</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;&lt;span&gt;&lt;a</span></span> <span style="color:#009900;">href</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"javascript:mcTabs.displayTab('advanced_tab','advanced_panel');"</span> <span style="color:#009900;">onmousedown</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"return false;"</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;</span></span>{$lang_advimage_tab_advanced}<span style="font-weight:bold;"><span style="color:#0000ff;">&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;</span></span></tt>
<tt> <span style="font-weight:bold;"><span style="color:#0000ff;">&lt;/ul&gt;</span></span></tt>
<tt></tt><span style="font-weight:bold;"><span style="color:#0000ff;"><tt>&lt;/div&gt;</tt></span></span></pre>
<p>The new tab is called dynamic_select_tab with a label of &#8216;Uploaded Images&#8217; it will open dynamic_select_panel, and it is the current tab, i.e. the default when the form is rendered.  The only thing you should change below the existing plugin tab code line is to remove class=&#8221;current&#8221; from general_tab.</li>
<li>Create a new panel to house the images we are pulling from the controller.
<pre style="overflow:auto;"><tt><span style="font-weight:bold;"><span style="color:#0000ff;">&lt;div</span></span> <span style="color:#009900;">class</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"panel_wrapper"</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;</span></span></tt><tt>  <span style="font-weight:bold;"><span style="color:#0000ff;">&lt;div</span></span> <span style="color:#009900;">id</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"dynamic_select_panel"</span> <span style="color:#009900;">class</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"panel current"</span> <span style="color:#009900;">style</span><span style="color:#990000;">=</span><span style="color:#009900;">'overflow:auto'</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;</span></span></tt><tt>
    <span style="font-weight:bold;"><span style="color:#0000ff;">&lt;fieldset&gt;</span></span></tt>
    <span style="font-weight:bold;"><span style="color:#0000ff;"> &lt;legend&gt;</span></span>Available Images<span style="color:#0000ff;">&lt;/legend&gt;</span>
<tt><span style="font-weight:bold;"><span style="color:#0000ff;"></span></span></tt><tt>     <span style="font-weight:bold;"><span style="color:#0000ff;">&lt;script</span></span> <span style="color:#009900;">type</span><span style="color:#990000;">=</span><span style="color:#ff0000;">"text/javascript"</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;</span></span>//&lt;![CDATA[</tt>
        new Ajax.Request("/manage_images",
          {asynchronous:true, evalScripts:true, method:'get'});     //]]&gt;
     <span style="font-weight:bold;"><span style="color:#0000ff;">&lt;/script&gt;</span></span>
<span style="font-style:italic;"><span style="color:#9a1900;"></span></span>     <span style="font-weight:bold;"><span style="color:#0000ff;">&lt;div</span></span> <span style="color:#009900;">id</span><span style="color:#990000;">=</span><span style="color:#009900;">'dynamic_images_list'</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;</span></span>
        Loading Images...<span style="font-weight:bold;"><span style="color:#0000ff;">&lt;br</span></span> <span style="font-weight:bold;"><span style="color:#0000ff;">/&gt;</span></span>
<span style="font-weight:bold;"><span style="color:#0000ff;">        &lt;img</span></span> <span style="color:#009900;">src</span><span style="color:#990000;">=</span><span style="color:#009900;">'/images/loading.gif'</span><span style="font-weight:bold;"><span style="color:#0000ff;">&gt;</span></span>
<span style="font-weight:bold;"><span style="color:#0000ff;">    &lt;/div&gt;
</span></span><tt><span style="font-weight:bold;"><span style="color:#0000ff;">   &lt;/fieldset&gt;</span></span></tt>
<span style="font-weight:bold;"><span style="color:#0000ff;">&lt;/div&gt;</span></span></pre>
<p>The &#8216;/manage_images&#8217; parameter to Ajax.Request will need to be replaced with the path to your controller.  It is important to note the style overflow:auto in the above code snippet.  This will allow the area with images to grow (i.e. a scroll bar will appear as needed).</li>
<li>Modify your image controller&#8217;s index action to respond to javascript.  In the index action for the controller you need to make sure the resond_to block has a format.js section has format.js:
<pre style="overflow:auto;"><tt>    respond_to <span style="font-weight:bold;"><span style="color:#0000ff;">do</span></span> <span style="color:#990000;">|</span>format<span style="color:#990000;">|</span></tt><tt></tt><tt></tt><tt>
</tt><tt>      format<span style="color:#990000;">.</span>html</tt>
<tt>      format<span style="color:#990000;">.</span>js</tt>
<tt>    <span style="font-weight:bold;"><span style="color:#0000ff;">end</span></span></tt></pre>
</li>
<li>Create a new file in the controller&#8217;s views sub-folder called index.js with the following rjs code:
<pre style="overflow:auto;"><tt>page<span style="color:#990000;">.</span>replace_html <span style="color:#990000;">:</span>dynamic_images_list<span style="color:#990000;">,</span> <span style="color:#990000;">:</span>partial <span style="color:#990000;">=&gt;</span> <span style="color:#ff0000;">'show_image_list'</span><span style="color:#990000;">,</span> <span style="color:#990000;">:</span>locals <span style="color:#990000;">=&gt;</span> <span style="color:#ff0000;">{</span> <span style="color:#990000;">:</span>images <span style="color:#990000;">=&gt;</span> <span style="color:#009900;">@images</span> <span style="color:#ff0000;">}</span></tt><tt></tt><tt></tt><tt>
</tt></pre>
<p>I chose to use a partial show_image_list, you can do the same and call it _show_image_list.rhtml.<br />
The page.replace_html call will convert the .rhtml from the partial to javascript and replace the dynamic_images_list div we created earlier with our list of images.  The code for the partial:</p>
<pre style="overflow:auto;"><tt><span style="color:#ff0000;">&lt;% if images.size &gt;</span> <span style="color:#993399;">0</span> <span style="color:#990000;">%&gt;</span></tt><tt></tt><tt>
</tt><span style="color:#ff0000;"><tt>&lt;ul&gt;</tt></span>
<tt>  <span style="color:#ff0000;">&lt;% images.each do |image| %&gt;</span></tt><tt></tt>
<tt><span style="color:#ff0000;">    &lt;li&gt;</span></tt>
<span style="color:#990000;"><tt>      &lt;</tt></span><tt>a href<span style="color:#990000;">=</span><span style="color:#ff0000;">"javascript:void(0)"</span> onclick<span style="color:#990000;">=</span><span style="color:#ff0000;">"&lt;%="</span>ts_insert_image<span style="color:#990000;">(</span><span style="color:#ff0000;">'#{image.val.public_filename()}'</span><span style="color:#990000;">,</span> <span style="color:#ff0000;">'#{image.name}'</span><span style="color:#990000;">);</span><span style="color:#ff0000;">" %&gt;"</span><span style="color:#990000;">&gt;</span></tt>
<span style="color:#ff0000;"><tt>      &lt;%= image_tag( image.val.public_filename(:thumb) ) %&gt;&lt;/a&gt;</tt></span>
<tt>    &lt;/li&gt;</tt>
<tt>  <span style="color:#ff0000;">&lt;% end %&gt;</span></tt><tt></tt>
<span style="color:#ff0000;"><tt>&lt;/ul&gt;</tt></span><tt></tt>
<span style="color:#ff0000;"><tt>&lt;% else %&gt;</tt></span><tt></tt>
<tt> No Images Uploaded Yet<span style="color:#990000;">.</span></tt><tt></tt>
<span style="color:#ff0000;"><tt>&lt;% end %&gt;</tt></span><tt></tt></pre>
<p>The class variable @images contains all of the image models we would like displayed.</p>
<p><strong>QUICK TIP</strong>: If there is a chance that your image name or filename could have single quotes in it, you should escape them.</li>
<li>An onclick event in the partial is used to take action when a user clicks an image: onclick=&#8221;&lt;%=&#8221;ts_insert_image(&#8216;#{image.val.public_filename()}&#8217;, &#8216;#{image.name}&#8217;);&#8221; %&gt;&#8221;.  This javascript function sets fields in the tinyMCE popup.  Create this function in functions.js which lives in ts_advimage/jscripts/functions.js:
<pre style="overflow:auto;"><tt><span style="font-weight:bold;"><span style="color:#0000ff;">function</span></span> <span style="font-weight:bold;"><span style="color:#000000;">ts_insert_image</span></span><span style="color:#990000;">(</span>url<span style="color:#990000;">,</span> alt_text<span style="color:#990000;">)</span><span style="color:#ff0000;">{</span></tt><tt>
<tt></tt> <span style="font-weight:bold;"><span style="color:#0000ff;">var</span></span> formObj <span style="color:#990000;">=</span> document<span style="color:#990000;">.</span>forms<span style="color:#990000;">[</span><span style="color:#993399;">0</span><span style="color:#990000;">];</span></tt><tt> formObj<span style="color:#990000;">.</span>src<span style="color:#990000;">.</span>value <span style="color:#990000;">=</span> url<span style="color:#990000;">;</span></tt>
<tt> formObj<span style="color:#990000;">.</span>alt<span style="color:#990000;">.</span>value <span style="color:#990000;">=</span> alt_text<span style="color:#990000;">;</span></tt><tt></tt>
<tt> <span style="font-weight:bold;"><span style="color:#000000;">insertAction</span></span><span style="color:#990000;">();</span></tt><tt></tt>
<span style="color:#ff0000;"><tt>}</tt></span></pre>
<p>This function sets the fields in the general tab and closes the popup inserting the image into the text box.</li>
<li>We are only a couple of steps away from being done, so hang in there.  We need to tell tinyMCE about our new plugin so open up ts_advimage/editor_plugin.js.  It is one long line (if you want to study the structure of the file look at editor_plugin_src.js).  The code below is copied from editor_plugin_src.js so it is easy to understand.  You must also make the changes in editor_plugin.js.  What I changed is highlighted below:
<pre style="overflow:auto;"><tt>tinyMCE<span style="color:#990000;">.</span><span style="font-weight:bold;"><span style="color:#000000;">importPluginLanguagePack</span></span><span style="color:#990000;">(</span><span style="color:#ff0000;">'ts_advimage'</span><span style="color:#990000;">);</span></tt><tt>
</tt><span style="font-weight:bold;"><span style="color:#0000ff;"><tt>var</tt></span></span><tt> TinyMCE_<span style="font-weight:bold;background-color:#ffffcc;">ThriveSmart</span>AdvancedImagePlugin <span style="color:#990000;">=</span> <span style="color:#ff0000;">{</span></tt>
<tt> getInfo <span style="color:#990000;">:</span> <span style="font-weight:bold;"><span style="color:#0000ff;">function</span></span><span style="color:#990000;">()</span> <span style="color:#ff0000;">{</span></tt>
<tt> 	<span style="font-weight:bold;"><span style="color:#0000ff;">return</span></span> <span style="color:#ff0000;">{</span></tt><span style="font-weight:bold;background-color:#ffffcc;">
<tt> 		longname <span style="color:#990000;">:</span> <span style="color:#ff0000;">'ThriveSmart Advanced image'</span><span style="color:#990000;">,</span></tt>
<tt> 		author <span style="color:#990000;">:</span> <span style="color:#ff0000;">'ThriveSmart LLC'</span><span style="color:#990000;">,</span></tt>
<tt> 		authorurl <span style="color:#990000;">:</span> <span style="color:#ff0000;">'http://www.thrivesmart.com'</span><span style="color:#990000;">,</span></tt>
<tt> 		infourl <span style="color:#990000;">:</span> <span style="color:#ff0000;">'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/advimage'</span><span style="color:#990000;">,</span></tt>
<tt> 		version <span style="color:#990000;">:</span> tinyMCE<span style="color:#990000;">.</span>majorVersion <span style="color:#990000;">+</span> <span style="color:#ff0000;">"."</span> <span style="color:#990000;">+</span> tinyMCE<span style="color:#990000;">.</span>minorVersion</tt></span>
<tt> 	<span style="color:#ff0000;">}</span><span style="color:#990000;">;</span></tt>
<tt> <span style="color:#ff0000;">}</span><span style="color:#990000;">,</span></tt>
<tt> getControlHTML <span style="color:#990000;">:</span> <span style="font-weight:bold;"><span style="color:#0000ff;">function</span></span><span style="color:#990000;">(</span>cn<span style="color:#990000;">)</span> <span style="color:#ff0000;">{</span></tt>
<tt> 	<span style="font-weight:bold;"><span style="color:#0000ff;">switch</span></span> <span style="color:#990000;">(</span>cn<span style="color:#990000;">)</span> <span style="color:#ff0000;">{</span></tt>
<tt> 		<span style="font-weight:bold;"><span style="color:#0000ff;">case</span></span> <span style="font-weight:bold;background-color:#ffffcc;"><span style="color:#ff0000;">"ts_image"</span></span><span style="color:#990000;">:</span></tt>
<tt> 			<span style="font-weight:bold;"><span style="color:#0000ff;">return</span></span> tinyMCE<span style="color:#990000;">.</span><span style="font-weight:bold;"><span style="color:#000000;">getButtonHTML</span></span><span style="color:#990000;">(</span>cn<span style="color:#990000;">,</span> <span style="color:#ff0000;">'lang_image_desc'</span><span style="color:#990000;">,</span> <span style="color:#ff0000;">'{$themeurl}/images/image.gif'</span><span style="color:#990000;">,</span> <span style="font-weight:bold;background-color:#ffffcc;"><span style="color:#ff0000;">'mceTSAdvImage'</span></span><span style="color:#990000;">);</span></tt>
<tt> 	<span style="color:#ff0000;">}</span></tt>
<tt> 	<span style="font-weight:bold;"><span style="color:#0000ff;">return</span></span> <span style="color:#ff0000;">""</span><span style="color:#990000;">;</span></tt>
<tt> <span style="color:#ff0000;">}</span><span style="color:#990000;">,</span></tt>
<tt> execCommand <span style="color:#990000;">:</span> <span style="font-weight:bold;"><span style="color:#0000ff;">function</span></span><span style="color:#990000;">(</span>editor_id<span style="color:#990000;">,</span> element<span style="color:#990000;">,</span> command<span style="color:#990000;">,</span> user_interface<span style="color:#990000;">,</span> value<span style="color:#990000;">)</span> <span style="color:#ff0000;">{</span></tt>
<tt> 	<span style="font-weight:bold;"><span style="color:#0000ff;">switch</span></span> <span style="color:#990000;">(</span>command<span style="color:#990000;">)</span> <span style="color:#ff0000;">{</span></tt>
<tt> 		<span style="font-weight:bold;background-color:#ffffcc;"><span style="font-weight:bold;"><span style="color:#0000ff;">case</span></span> <span style="font-weight:bold;background-color:#ffffcc;"><span style="color:#ff0000;">"mceTSAdvImage"</span></span><span style="color:#990000;">:</span></span></tt>
<tt> 			<span style="font-weight:bold;background-color:#ffffcc;"><span style="font-weight:bold;background-color:#ffffcc;"><span style="font-weight:bold;"><span style="color:#0000ff;">var</span></span> template <span style="color:#990000;">=</span> <span style="font-weight:bold;"><span style="color:#0000ff;">new</span></span> <span style="font-weight:bold;"><span style="color:#000000;">Array</span></span><span style="color:#990000;">();</span></span></span></tt>
<tt> 			<span style="font-weight:bold;background-color:#ffffcc;">template<span style="color:#990000;">[</span><span style="color:#ff0000;">'file'</span><span style="color:#990000;">]</span>   <span style="color:#990000;">=</span> <span style="color:#ff0000;">'../../plugins/ts_advimage/image.htm'</span><span style="color:#990000;">;</span></span></tt>
<tt> 			<span style="font-weight:bold;background-color:#ffffcc;">template<span style="color:#990000;">[</span><span style="color:#ff0000;">'width'</span><span style="color:#990000;">]</span>  <span style="color:#990000;">=</span> <span style="color:#993399;">480</span><span style="color:#990000;">;</span></span></tt>
<tt> 			<span style="font-weight:bold;background-color:#ffffcc;">template<span style="color:#990000;">[</span><span style="color:#ff0000;">'height'</span><span style="color:#990000;">]</span> <span style="color:#990000;">=</span> <span style="color:#993399;">480</span><span style="color:#990000;">;</span></span></tt>
<tt> 			<span style="font-style:italic;"><span style="color:#9a1900;">// Language specific width and height addons</span></span></tt>
<tt> 			template<span style="color:#990000;">[</span><span style="color:#ff0000;">'width'</span><span style="color:#990000;">]</span>  <span style="color:#990000;">+=</span> tinyMCE<span style="color:#990000;">.</span><span style="font-weight:bold;"><span style="color:#000000;">getLang</span></span><span style="color:#990000;">(</span><span style="color:#ff0000;">'lang_advimage_delta_width'</span><span style="color:#990000;">,</span> <span style="color:#993399;">0</span><span style="color:#990000;">);</span></tt>
<tt> 			template<span style="color:#990000;">[</span><span style="color:#ff0000;">'height'</span><span style="color:#990000;">]</span> <span style="color:#990000;">+=</span> tinyMCE<span style="color:#990000;">.</span><span style="font-weight:bold;"><span style="color:#000000;">getLang</span></span><span style="color:#990000;">(</span><span style="color:#ff0000;">'lang_advimage_delta_height'</span><span style="color:#990000;">,</span> <span style="color:#993399;">0</span><span style="color:#990000;">);</span></tt>
<tt> 			<span style="font-weight:bold;"><span style="color:#0000ff;">var</span></span> inst <span style="color:#990000;">=</span> tinyMCE<span style="color:#990000;">.</span><span style="font-weight:bold;"><span style="color:#000000;">getInstanceById</span></span><span style="color:#990000;">(</span>editor_id<span style="color:#990000;">);</span></tt>
<tt> 			<span style="font-weight:bold;"><span style="color:#0000ff;">var</span></span> elm <span style="color:#990000;">=</span> inst<span style="color:#990000;">.</span><span style="font-weight:bold;"><span style="color:#000000;">getFocusElement</span></span><span style="color:#990000;">();</span></tt>
<tt> 			<span style="font-weight:bold;"><span style="color:#0000ff;">if</span></span> <span style="color:#990000;">(</span>elm <span style="color:#990000;">!=</span> <span style="font-weight:bold;"><span style="color:#0000ff;">null</span></span> <span style="color:#990000;">&amp;&amp;</span> tinyMCE<span style="color:#990000;">.</span><span style="font-weight:bold;"><span style="color:#000000;">getAttrib</span></span><span style="color:#990000;">(</span>elm<span style="color:#990000;">,</span> <span style="color:#ff0000;">'class'</span><span style="color:#990000;">).</span><span style="font-weight:bold;"><span style="color:#000000;">indexOf</span></span><span style="color:#990000;">(</span><span style="color:#ff0000;">''</span><span style="color:#990000;">)</span> <span style="color:#990000;">!=</span> <span style="color:#990000;">-</span><span style="color:#993399;">1</span><span style="color:#990000;">)</span></tt>
<tt> 				<span style="font-weight:bold;"><span style="color:#0000ff;">return</span></span> <span style="font-weight:bold;"><span style="color:#0000ff;">true</span></span><span style="color:#990000;">;</span></tt>
<tt> 			tinyMCE<span style="color:#990000;">.</span><span style="font-weight:bold;"><span style="color:#000000;">openWindow</span></span><span style="color:#990000;">(</span>template<span style="color:#990000;">,</span> <span style="color:#ff0000;">{</span>editor_id <span style="color:#990000;">:</span> editor_id<span style="color:#990000;">,</span> inline <span style="color:#990000;">:</span> <span style="color:#ff0000;">"yes"</span><span style="color:#ff0000;">}</span><span style="color:#990000;">);</span></tt>
<tt> 			<span style="font-weight:bold;"><span style="color:#0000ff;">return</span></span> <span style="font-weight:bold;"><span style="color:#0000ff;">true</span></span><span style="color:#990000;">;</span></tt>
<tt> 	<span style="color:#ff0000;">}</span></tt>
<tt> 	<span style="font-weight:bold;"><span style="color:#0000ff;">return</span></span> <span style="font-weight:bold;"><span style="color:#0000ff;">false</span></span><span style="color:#990000;">;</span></tt>
<tt> <span style="color:#ff0000;">}</span><span style="color:#990000;">,</span></tt></pre>
</li>
<li>In the last line of editor_plugin.js and editor_plugin_src.js you need to change<br />
tinyMCE.addPlugin to <font color="#ff0000">tinyMCE.addPlugin(&#8220;ts_advimage&#8221;, TinyMCE_ThriveSmartAdvancedImagePlugin);</font></li>
<li>Now we need to add our ts_advimage plugin to the tinyMCE menu bar
<pre style="overflow:auto;"><tt>	tinyMCE<span style="color:#990000;">.</span><span style="font-weight:bold;"><span style="color:#000000;">init</span></span><span style="color:#990000;">(</span><span style="color:#ff0000;">{</span></tt><tt>
</tt><tt>  	mode <span style="color:#990000;">:</span> <span style="color:#ff0000;">"textareas"</span><span style="color:#990000;">,</span></tt>
<tt>  	editor_selector <span style="color:#990000;">:</span> <span style="color:#ff0000;">"tiny_mce"</span><span style="color:#990000;">,</span></tt>
<tt>  	theme <span style="color:#990000;">:</span> <span style="color:#ff0000;">"advanced"</span><span style="color:#990000;">,</span></tt>
<tt>  	plugins <span style="color:#990000;">:</span> <span style="color:#ff0000;">"inlinepopups,<span style="font-weight:bold;background-color:#ffffcc;">ts_advimage</span>,advlink,emotions,iespell,zoom,searchreplace,fullscreen,visualchars,youtube"</span><span style="color:#990000;">,</span></tt>
<tt>  	theme_advanced_buttons1 <span style="color:#990000;">:</span> <span style="color:#ff0000;">"undo,redo,removeformat,|,bold,italic,underline,strikethrough,sub,sup,|,outdent,indent,bullist,numlist,hr,backcolor,|,link,unlink,charmap,emotions,<span style="font-weight:bold;background-color:#ffffcc;">ts_image</span>,youtube,iespell,|,search,replace,|,cleanup,code,fullscreen,help"</span><span style="color:#990000;">,</span></tt>
<tt>  	theme_advanced_buttons2 <span style="color:#990000;">:</span> <span style="color:#ff0000;">""</span><span style="color:#990000;">,</span></tt>
<tt>  	theme_advanced_buttons3 <span style="color:#990000;">:</span> <span style="color:#ff0000;">""</span><span style="color:#990000;">,</span></tt>
<tt>  	theme_advanced_toolbar_location <span style="color:#990000;">:</span> <span style="color:#ff0000;">"top"</span><span style="color:#990000;">,</span></tt>
<tt>  	theme_advanced_toolbar_align <span style="color:#990000;">:</span> <span style="color:#ff0000;">"left"</span><span style="color:#990000;">,</span></tt>
<tt>  	theme_advanced_path_location <span style="color:#990000;">:</span> <span style="color:#ff0000;">"bottom"</span><span style="color:#990000;">,</span></tt>
<tt>  	gecko_spellcheck <span style="color:#990000;">:</span> <span style="font-weight:bold;"><span style="color:#0000ff;">true</span></span><span style="color:#990000;">,</span></tt>
<tt>  	extended_valid_elements <span style="color:#990000;">:</span> <span style="color:#ff0000;">"a[name|href|target|title|onclick],img[class|src|style|border=0|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name],hr[class|width|size|noshade],span[class|align|style]"</span><span style="color:#990000;">,</span></tt>
<tt>  	theme_advanced_resizing <span style="color:#990000;">:</span> <span style="font-weight:bold;"><span style="color:#0000ff;">true</span></span><span style="color:#990000;">,</span></tt>
<tt>  	theme_advanced_resize_horizontal <span style="color:#990000;">:</span> <span style="font-weight:bold;"><span style="color:#0000ff;">false</span></span></tt>
<tt>  <span style="color:#ff0000;">}</span><span style="color:#990000;">);</span></tt></pre>
<p>I&#8217;ve included the entire block for clarity, the important portions of the above code are in plugins : ts_advimage and<br />
theme_advanced_buttons1 : ts_image</li>
</ol>
<p>Fire up your browser, clear the cache and try it out because now you have an image chooser plugin that works with tinyMCE.</p>
<p>I hope you enjoyed this post. <a href="https://hackd.wordpress.com/2007/08/28/part-two-how-to-create-an-image-selection-plugin-for-tinymce-with-ruby-on-rails/">Part two is out as well!</a><strike> will be out soon so stay tuned!</strike></p>
]]></content:encoded>
					
					<wfw:commentRss>https://hackd.wordpress.com/2007/08/23/how-to-create-an-image-selction-plugin-for-tinymce-with-ruby-on-rails/feed/</wfw:commentRss>
			<slash:comments>29</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">9</post-id>
		<media:content url="https://0.gravatar.com/avatar/673379bc8488f4a9bf2f150252cd5dd9d6e3fce48b94bd33b907f523e9c4acf1?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Dan</media:title>
		</media:content>

		<media:content url="https://hackd.wordpress.com/wp-content/uploads/2007/08/picture-3.png" medium="image">
			<media:title type="html">picture-3.png</media:title>
		</media:content>
	</item>
		<item>
		<title>UI Tip: Be Physical &#038; Real</title>
		<link>https://hackd.wordpress.com/2007/06/01/ui-tip-be-physical-real/</link>
					<comments>https://hackd.wordpress.com/2007/06/01/ui-tip-be-physical-real/#comments</comments>
		
		<dc:creator><![CDATA[Matt]]></dc:creator>
		<pubDate>Fri, 01 Jun 2007 05:55:49 +0000</pubDate>
				<category><![CDATA[User Interface]]></category>
		<guid isPermaLink="false">http://hackd.wordpress.com/2007/06/01/ui-tip-be-physical-real/</guid>

					<description><![CDATA[I was playing around with a new web app the other day, called BuzzWord. I play around with as many new services as I can so I can get as many ideas as I can for new styles of user interface. (Screenshot included). Despite the fact that it was flash (I said it!), something struck [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><a href="https://hackd.wordpress.com/wp-content/uploads/2007/06/picture-1.png" title="BuzzWord (Beta)"><img loading="lazy" src="https://hackd.wordpress.com/wp-content/uploads/2007/06/picture-1.png?w=249&#038;h=179" style="border:1px solid #999999;display:block;float:right;margin:5px;" alt="BuzzWord (Beta)" height="179" width="249" /></a>I was playing around with a new web app the other day, called <a href="http://preview.getbuzzword.com/">BuzzWord</a>.  I play around with as many new services as I can so I can get as many ideas as I can for new styles of user interface.  (Screenshot included).  Despite the fact that it was flash (I said it!), something struck me about the program: it was a joy to use.  But I couldn&#8217;t figure out why.  I knew I definitely didn&#8217;t get that feeling from using <a href="http://docs.google.com/">another online word processor</a>.</p>
<p><a href="https://hackd.wordpress.com/wp-content/uploads/2007/06/picture-2.png" title="Google Doc"><img loading="lazy" src="https://hackd.wordpress.com/wp-content/uploads/2007/06/picture-2.png?w=267&#038;h=180" alt="Google Doc" style="border:1px solid #999999;display:block;float:left;margin:5px;" height="180" width="267" /><br />
</a>And then it hit me &#8211; it actually graphically displayed the concept of pages, and more natural spacing between words.  And that made all the difference.  I started looking around the web a bit more, and indeed, many layouts are starting to incorporate <a href="http://csszengarden.com/?cssfile=/202/202.css&amp;page=0">more</a> <a href="http://csszengarden.com/?cssfile=/195/195.css&amp;page=0">real-life</a> physicality and images into their layouts.  It just makes people want to use the applications more.  Don&#8217;t get me wrong &#8211; features are equally if not more important too (which is why I will continue to use the product displayed on the left).   There is a company that is doing this really well right now: Apple.  If you look at their products, from the iPod, to Pages, to iTunes, many of them incorporate real life, realistic graphics, not to mention a great <a href="http://www.symphonious.net/2007/05/22/two-finger-scrolling-rocks/">tactile</a> <a href="http://news.com.com/2010-1041_3-5375101.html">experience</a>.</p>
<p><a href="https://hackd.wordpress.com/wp-content/uploads/2007/06/surface.jpg" title="The new Microsoft Surface"><img src="https://hackd.wordpress.com/wp-content/uploads/2007/06/surface.jpg?w=450" alt="The new Microsoft Surface" style="border:1px solid #999999;display:block;float:left;margin:5px;" /></a></p>
<p>&#8230; And then I saw <a href="http://www.techcrunch.com/2007/05/29/microsoft-announces-surface-computer/">Microsoft Surface (at techcrunch, of course!)</a>.   I have been koolaided. Multi-input, context aware,  graphical interface is the next biggest thing in user experience since the window manager and the mouse!  Yes, it&#8217;s been around since the &#8217;80s, yes other companies might succeed over Microsoft at making this actually work,  but the possibilities with this are endless.  Combine it with a Wii controller (or something that takes gestures from a distance away), and you&#8217;re golden.  Put your planner on the surface, and all your favorite web services talk to it and tell you what you should be doing when.  Oy vey, I&#8217;m getting too excited &#8211; I need to rest.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://hackd.wordpress.com/2007/06/01/ui-tip-be-physical-real/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">6</post-id>
		<media:content url="https://0.gravatar.com/avatar/09722deb67a0ab6414e1b5bc6b190a9b907662a9508c38d8f2bc86afd7b51c84?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">matt</media:title>
		</media:content>

		<media:content url="https://hackd.wordpress.com/wp-content/uploads/2007/06/picture-1.png" medium="image">
			<media:title type="html">BuzzWord (Beta)</media:title>
		</media:content>

		<media:content url="https://hackd.wordpress.com/wp-content/uploads/2007/06/picture-2.png" medium="image">
			<media:title type="html">Google Doc</media:title>
		</media:content>

		<media:content url="https://hackd.wordpress.com/wp-content/uploads/2007/06/surface.jpg" medium="image">
			<media:title type="html">The new Microsoft Surface</media:title>
		</media:content>
	</item>
		<item>
		<title>Grading Web Sites on Their SEO</title>
		<link>https://hackd.wordpress.com/2007/05/21/grading-web-sites-on-their-seo/</link>
					<comments>https://hackd.wordpress.com/2007/05/21/grading-web-sites-on-their-seo/#comments</comments>
		
		<dc:creator><![CDATA[Matt]]></dc:creator>
		<pubDate>Mon, 21 May 2007 22:53:16 +0000</pubDate>
				<category><![CDATA[SEO]]></category>
		<guid isPermaLink="false">http://hackd.wordpress.com/2007/05/21/grading-web-sites-on-their-seo/</guid>

					<description><![CDATA[How do you stack up at the web site grader? http://www.websitegrader.com/. This is a great tool to figure out how to improve your site in search rankings. Sending ThriveSmart through it showed that there is a lot of room for improvement. Things like using H1 tags and making sure your title has important keywords in [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" src="https://hackd.wordpress.com/wp-content/uploads/2007/05/picture-1.png?w=253&#038;h=204" alt="ThriveSmart Grade" style="float:left;margin:4px;" height="204" width="253" /> How do you stack up at the web site grader? <a href="http://www.websitegrader.com/">http://www.websitegrader.com/</a>.  This is a great tool to figure out how to improve your site in search rankings.</p>
<p>Sending <a href="http://www.thrivesmart.com/">ThriveSmart</a> through it showed that there is a lot of room for improvement.  Things like using H1 tags and making sure your title has important keywords in it are really important.  Put more than just the name of your product!</p>
<p>Guess we&#8217;ll be spending a few days cleaning up the site.  Big time.  And adding ways for interested people to sign up for updates to our business, like a feed and a newsletter.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://hackd.wordpress.com/2007/05/21/grading-web-sites-on-their-seo/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3</post-id>
		<media:content url="https://0.gravatar.com/avatar/09722deb67a0ab6414e1b5bc6b190a9b907662a9508c38d8f2bc86afd7b51c84?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">matt</media:title>
		</media:content>

		<media:content url="https://hackd.wordpress.com/wp-content/uploads/2007/05/picture-1.png" medium="image">
			<media:title type="html">ThriveSmart Grade</media:title>
		</media:content>
	</item>
	</channel>
</rss>
