tag:blogger.com,1999:blog-44035260885454171262008-06-18T03:33:08.782-04:00Coding FrenzyAlexhttp://www.blogger.com/profile/04839463833553068390noreply@blogger.comBlogger4125tag:blogger.com,1999:blog-4403526088545417126.post-64422255969220312412008-01-09T11:52:00.000-05:002008-01-24T00:19:29.578-05:00AJAX, Django, RoRMichael has a <a href="http://mrlauer.wordpress.com/2008/01/07/django-ajax-scriptaculous/">couple </a>of <a href="http://mrlauer.wordpress.com/2008/01/03/django-and-ajax/">posts </a>on ajax and django. Since we occasionally discuss the merits and faults of rails and django, I thought I would provide a similar example in rails (version 2.02). At the end of this post I've included the entire source code of a rails application that creates a search form, submits the search string via XMLHttpRequest, generates random search data, updates the search results independently of the rest of the page, and for kicks - makes the search results flash.<br /><br />It is simple but instructive. To my eye, it is more elegant than the django code. for a couple of reasons:<br /><ul><li>No JavaScript. I love JavaScript and have written plenty of it, but for simple and moderately complex things rails gets the abstraction correct. Rails' ajax helpers (form_remote_tag and page in this case), do all the work for you.</li></ul><ul><li>Easy reuse of partials. Michael had to jump through a few hoops to reuse his 'searchresults' partial (partial in rails == tag in djago). This is because django is not aware of the ajax library and thus cannot provide facilities to automate the reuse.<br /></li></ul>Edit: My apologies for the code formatting. The formatter I used does not recognize the html.erb syntax, and made a mess of the entire code block.<br /><br /><pre><span class="comment"># 1) create a rails application by running "rails ajaxform" at a command prompt</span><br /><span class="comment"># 2) create the files listed below</span><br /><span class="comment"># 3) start the server by running "script/server" (mac,*nix) or "ruby script/server" (windows)</span><br /><span class="comment"># 4) point your webrowser at http://localhost:3000</span><br /><br /><span class="comment"># ----- app/views/foos/search.html.erb -----</span><br /><span class="punct"><%</span> <span class="ident">form_remote_tag</span><span class="punct">(</span><span class="symbol">:url=</span><span class="punct">>{</span><span class="symbol">:action=</span><span class="punct">>'</span><span class="string">search</span><span class="punct">'})</span> <span class="keyword">do</span> <span class="punct">%></span><span class="string"><br /><%= text_field_tag('search_str') %</span><span class="punct">></span><br /><span class="punct"><%=</span><span class="string"> submit_tag 'Search' %><br /><% end %><br /><%</span><span class="punct">=</span> <span class="ident">render</span> <span class="symbol">:partial=</span><span class="punct">>'</span><span class="string">search_results</span><span class="punct">'%></span><span class="string"><br /><br /># ----- app/views/foos/_search_results.html.erb -----<br /><div id='search_results'</span><span class="punct">></span><br /><span class="punct"><%=</span><span class="string"> @search_results.size > 0 ? @search_results.collect do |result| "<p><span class="expr">#{result}</span></p>" end.join : "No Search Results" %><br /></div><br /><br /># ----- app/views/foos/search.js.rjs--------<br />page[:search_results].replace(:partial</span><span class="punct">=>'</span><span class="string">search_results</span><span class="punct">')</span><br /><span class="ident">page</span><span class="punct">[</span><span class="symbol">:search_results</span><span class="punct">].</span><span class="ident">visual_effect</span><span class="punct">(</span><span class="symbol">:pulsate</span><span class="punct">)</span> <span class="comment"># just for fun!`</span><br /><br /><span class="comment"># ----- app/controllers/foos_controller.rb -----</span><br /><span class="keyword">class </span><span class="class">FoosController</span> <span class="punct"><</span> <span class="constant">ApplicationController</span><br /><span class="keyword">def </span><span class="method">search</span><br /><span class="attribute">@search_results</span><span class="punct">=[]</span><br /><span class="keyword">if</span> <span class="ident">search_str</span><span class="punct">=</span><span class="ident">params</span><span class="punct">[</span><span class="symbol">:search_str</span><span class="punct">]</span><br /><span class="attribute">@search_results</span> <span class="punct">=</span> <span class="punct">(</span><span class="number">1</span><span class="punct">..</span><span class="ident">rand</span><span class="punct">(</span><span class="number">10</span><span class="punct">)).</span><span class="ident">collect</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">ii</span><span class="punct">|</span> <span class="punct">"</span><span class="string"><span class="expr">#{search_str}</span> + <span class="expr">#{ii}</span></span><span class="punct">"</span> <span class="keyword">end</span><br /><span class="keyword">end</span><br /><span class="ident">respond_to</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">format</span><span class="punct">|</span><br /><span class="ident">format</span><span class="punct">.</span><span class="ident">html</span><br /><span class="ident">format</span><span class="punct">.</span><span class="ident">js</span><br /><span class="keyword">end</span><br /><span class="keyword">end</span><br /><span class="keyword">end</span><br /><br /><span class="comment"># ----- app/views/layouts/application.html.erb -----</span><br /><span class="punct"><</span><span class="ident">html</span><span class="punct">></span><br /><span class="punct"><</span><span class="ident">head</span><span class="punct">></span><br /><span class="punct"><%=</span><span class="string">javascript_include_tag :defaults%><br /></head><br /><body><br /><%</span><span class="punct">=</span> <span class="keyword">yield</span> <span class="punct">%></span><span class="string"><br /></body</span><span class="punct">></span><br /><span class="punct"></</span><span class="regex">html><span class="normal"><br /></span></span></pre>Alexhttp://www.blogger.com/profile/04839463833553068390noreply@blogger.comtag:blogger.com,1999:blog-4403526088545417126.post-76557515265255888182007-12-07T11:58:00.001-05:002007-12-07T12:05:23.939-05:00How to Format Ruby Code in a Blog PostMy previous post was the first time I had ever presented ruby code in a post. <a href="http://blog.wolfman.com/articles/2006/05/26/howto-format-ruby-code-for-blogs">This article</a> saved me the hassle of figuring it out how to make it look pretty (I stuck the css directly into my blogger template). Thanks Wolfmann.Alexhttp://www.blogger.com/profile/04839463833553068390noreply@blogger.comtag:blogger.com,1999:blog-4403526088545417126.post-18105254868328886842007-12-07T10:18:00.001-05:002008-01-24T00:20:12.239-05:00Sending GMail from a Standalone Ruby ScriptAs part of my rails application, I need to send emails from a stand alone ruby script. For example, the back end of my rails application is a (currently) small postgres database. The easiest way to back it up is to send a database dump to myself via gmail.<br /><br />There are several tutorials on how to <a href="http://www.stephenchu.com/2006_06_01_archive.html">send gmail directly from a rails app</a>. Presented here is a method for doing it from a standalone script. This method assumes rails is installed, but the script itself runs outside of any rails application. In my case in the wee hours of the morning as a cron job.<br /><br />Usage of this script would be something like:<br /><pre><span class="ident">require</span> <span class="punct">'</span><span class="string">send_gmail</span><span class="punct">'</span><br /><span class="ident">hsh</span><span class="punct">={</span><span class="symbol">:to=</span><span class="punct">>'</span><span class="string">name@domain.com</span><span class="punct">',</span> <span class="symbol">:subject=</span><span class="punct">>'</span><span class="string">subject</span><span class="punct">',</span> <span class="symbol">:body=</span><span class="punct">>'</span><span class="string">body</span><span class="punct">'}</span><br /><span class="constant">SendGMail</span><span class="punct">.</span><span class="ident">send_gmail</span><span class="punct">(</span><span class="ident">hsh</span><span class="punct">)</span><br /></pre><br />The script can also handle attachments, albeit in an unusual way. Instead of giving it a file, you give it the data directly, along with a filename, mime_type, and transfer encoding:<br /><pre><span class="ident">raw_attachment</span><span class="punct">={</span><span class="symbol">:mime_type=</span><span class="punct">>'</span><span class="string">application/x-gzip</span><span class="punct">',</span> <span class="symbol">:body=</span><span class="punct">></span><span class="ident">make_body</span><span class="punct">,</span> <span class="symbol">:transfer_encoding=</span><span class="punct">>'</span><span class="string">base64</span><span class="punct">',</span> <span class="symbol">:filename=</span><span class="punct">>'</span><span class="string">backup.tar.gz</span><span class="punct">'</span> <span class="punct">}</span><br /><span class="ident">hsh</span><span class="punct">[</span><span class="symbol">:raw_attachment</span><span class="punct">]=</span><span class="ident">raw_attachment</span><br /></pre><br />It should be easy enough to modify the script to handle files as attachments directly, but I didn't have such a need.<br /><br />Here is the complete listing. My thanks to Stephun Chu, as most of this is cribbed from his aforementioned <a href="http://www.stephenchu.com/2006_06_01_archive.html">post</a>.<br /><br />Edit: Fixed syntax error - Thanks Nolan! <br /><br /><pre>send_gmail.rb<br /><br /><br /><span class="comment">#!/usr/bin/env ruby</span><br /><span class="ident">require</span> <span class="punct">'</span><span class="string">rubygems</span><span class="punct">'</span><br /><span class="ident">gem</span> <span class="punct">'</span><span class="string">actionmailer</span><span class="punct">'</span><br /><span class="ident">require</span> <span class="punct">'</span><span class="string">action_mailer</span><span class="punct">'</span><br /><span class="ident">require</span> <span class="punct">'</span><span class="string">openssl</span><span class="punct">'</span><br /><span class="ident">require</span> <span class="punct">'</span><span class="string">net/smtp</span><span class="punct">'</span><br /><br /><span class="keyword">module </span><span class="module">SendGMail</span><br /><br /><span class="attribute">@user_name</span><span class="punct">='</span><span class="string">username@domain.com</span><span class="punct">'</span><br /><span class="attribute">@domain</span><span class="punct">='</span><span class="string">domain.com</span><span class="punct">'</span><br /><span class="attribute">@password</span><span class="punct">='</span><span class="string">password</span><span class="punct">'</span><br /><br /><br /><span class="keyword">def </span><span class="method">SendGMail.send_gmail</span><span class="punct">(</span><span class="ident">hsh</span><span class="punct">)</span><br /><br /><span class="ident">raw_attachments</span><span class="punct">=</span><span class="ident">hsh</span><span class="punct">.</span><span class="ident">fetch</span><span class="punct">(</span><span class="symbol">:raw_attachements</span><span class="punct">,</span> <span class="punct">[])</span><br /><span class="keyword">if</span> <span class="ident">hsh</span><span class="punct">.</span><span class="ident">has_key?</span><span class="punct">(</span><span class="symbol">:raw_attachment</span><span class="punct">)</span><br /> <span class="ident">raw_attachments</span><span class="punct">.</span><span class="ident">push</span><span class="punct">(</span><span class="ident">hsh</span><span class="punct">[</span><span class="symbol">:raw_attachment</span><span class="punct">])</span><br /><span class="keyword">end</span><br /><br /><span class="ident">mail</span><span class="punct">=</span><span class="constant">TMail</span><span class="punct">::</span><span class="constant">Mail</span><span class="punct">.</span><span class="ident">new</span><br /><span class="ident">mail</span><span class="punct">.</span><span class="ident">to</span><span class="punct">=</span><span class="ident">hsh</span><span class="punct">[</span><span class="symbol">:to</span><span class="punct">]</span><br /><span class="ident">mail</span><span class="punct">.</span><span class="ident">date</span><span class="punct">=</span><span class="constant">Time</span><span class="punct">.</span><span class="ident">now</span><br /><span class="ident">mail</span><span class="punct">.</span><span class="ident">from</span><span class="punct">=</span><span class="attribute">@user_name</span><br /><span class="ident">mail</span><span class="punct">.</span><span class="ident">subject</span><span class="punct">=</span><span class="ident">hsh</span><span class="punct">[</span><span class="symbol">:subject</span><span class="punct">]</span><br /><br /><span class="ident">main</span><span class="punct">=</span><span class="ident">mail</span><br /><span class="ident">main</span><span class="punct">=</span><span class="constant">TMail</span><span class="punct">::</span><span class="constant">Mail</span><span class="punct">.</span><span class="ident">new</span><br /><span class="ident">main</span><span class="punct">.</span><span class="ident">body</span> <span class="punct">=</span> <span class="ident">hsh</span><span class="punct">[</span><span class="symbol">:body</span><span class="punct">]</span><br /><span class="ident">puts</span> <span class="ident">main</span><span class="punct">.</span><span class="ident">body</span><br /><span class="ident">main</span><span class="punct">.</span><span class="ident">set_content_type</span><span class="punct">('</span><span class="string">text/plain</span><span class="punct">',</span> <span class="constant">nil</span><span class="punct">,</span> <span class="punct">'</span><span class="string">charset</span><span class="punct">'=>'</span><span class="string">utf-8</span><span class="punct">')</span><br /><span class="ident">mail</span><span class="punct">.</span><span class="ident">parts</span><span class="punct">.</span><span class="ident">push</span><span class="punct">(</span><span class="ident">main</span><span class="punct">)</span><br /><br /><span class="keyword">for</span> <span class="ident">raw_attachment</span> <span class="keyword">in</span> <span class="ident">raw_attachments</span><br /> <span class="ident">part</span> <span class="punct">=</span> <span class="constant">TMail</span><span class="punct">::</span><span class="constant">Mail</span><span class="punct">.</span><span class="ident">new</span><br /> <span class="ident">transfer_encoding</span><span class="punct">=</span><span class="ident">raw_attachment</span><span class="punct">[</span><span class="symbol">:transfer_encoding</span><span class="punct">]</span><br /> <span class="ident">body</span><span class="punct">=</span><span class="ident">raw_attachment</span><span class="punct">[</span><span class="symbol">:body</span><span class="punct">]</span><br /> <span class="keyword">case</span> <span class="punct">(</span><span class="ident">transfer_encoding</span> <span class="punct">||</span> <span class="punct">"</span><span class="punct">").</span><span class="ident">downcase</span><br /> <span class="keyword">when</span> <span class="punct">"</span><span class="string">base64</span><span class="punct">"</span> <span class="keyword">then</span><br /> <span class="ident">part</span><span class="punct">.</span><span class="ident">body</span> <span class="punct">=</span> <span class="constant">TMail</span><span class="punct">::</span><span class="constant">Base64</span><span class="punct">.</span><span class="ident">folding_encode</span><span class="punct">(</span><span class="ident">body</span><span class="punct">)</span><br /> <span class="keyword">when</span> <span class="punct">"</span><span class="string">quoted-printable</span><span class="punct">"</span><br /> <span class="ident">part</span><span class="punct">.</span><span class="ident">body</span> <span class="punct">=</span> <span class="punct">[</span><span class="ident">body</span><span class="punct">].</span><span class="ident">pack</span><span class="punct">("</span><span class="string">M*</span><span class="punct">")</span><br /> <span class="keyword">else</span><br /> <span class="ident">part</span><span class="punct">.</span><span class="ident">body</span> <span class="punct">=</span> <span class="ident">body</span><br /> <span class="keyword">end</span><br /> <br /> <span class="ident">part</span><span class="punct">.</span><span class="ident">transfer_encoding</span> <span class="punct">=</span> <span class="ident">transfer_encoding</span><br /> <span class="ident">part</span><span class="punct">.</span><span class="ident">set_content_type</span><span class="punct">(</span><span class="ident">raw_attachment</span><span class="punct">[</span><span class="symbol">:mime_type</span><span class="punct">],</span> <span class="constant">nil</span><span class="punct">,</span> <span class="punct">'</span><span class="string">name</span><span class="punct">'</span> <span class="punct">=></span> <span class="ident">raw_attachment</span><span class="punct">[</span><span class="symbol">:filename</span><span class="punct">])</span><br /> <span class="ident">part</span><span class="punct">.</span><span class="ident">set_content_disposition</span><span class="punct">("</span><span class="string">attachment</span><span class="punct">",</span> <span class="punct">"</span><span class="string">filename</span><span class="punct">"=></span><span class="ident">raw_attachment</span><span class="punct">[</span><span class="symbol">:filename</span><span class="punct">])</span><br /> <span class="ident">mail</span><span class="punct">.</span><span class="ident">parts</span><span class="punct">.</span><span class="ident">push</span><span class="punct">(</span><span class="ident">part</span><span class="punct">)</span><br /><span class="keyword">end</span><br /><br /><span class="ident">mail</span><span class="punct">.</span><span class="ident">set_content_type</span><span class="punct">('</span><span class="string">multipart</span><span class="punct">',</span> <span class="punct">'</span><span class="string">mixed</span><span class="punct">')</span> <br /><span class="constant">ActionMailer</span><span class="punct">::</span><span class="constant">Base</span><span class="punct">.</span><span class="ident">deliver</span><span class="punct">(</span><span class="ident">mail</span><span class="punct">)</span><br /><br /><span class="keyword">end</span><br /><br /><span class="constant">ActionMailer</span><span class="punct">::</span><span class="constant">Base</span><span class="punct">.</span><span class="ident">smtp_settings</span> <span class="punct">=</span> <span class="punct">{</span><br /><span class="symbol">:address</span> <span class="punct">=></span> <span class="punct">'</span><span class="string">smtp.gmail.com</span><span class="punct">',</span><br /><span class="symbol">:domain</span> <span class="punct">=></span> <span class="attribute">@domain</span><span class="punct">,</span><br /><span class="symbol">:authentication</span> <span class="punct">=></span> <span class="symbol">:plain</span><span class="punct">,</span><br /><span class="symbol">:port</span> <span class="punct">=></span> <span class="number">587</span><span class="punct">,</span><br /><span class="symbol">:user_name</span> <span class="punct">=></span> <span class="attribute">@user_name</span><span class="punct">,</span><br /><span class="symbol">:password</span> <span class="punct">=></span> <span class="attribute">@password</span><br /><span class="punct">}</span><br /><br /><span class="constant">Net</span><span class="punct">::</span><span class="constant">SMTP</span><span class="punct">.</span><span class="ident">class_eval</span> <span class="keyword">do</span><br /><span class="ident">private</span><br /><span class="keyword">def </span><span class="method">do_start</span><span class="punct">(</span><span class="ident">helodomain</span><span class="punct">,</span> <span class="ident">user</span><span class="punct">,</span> <span class="ident">secret</span><span class="punct">,</span> <span class="ident">authtype</span><span class="punct">)</span><br /> <span class="keyword">raise</span> <span class="constant">IOError</span><span class="punct">,</span> <span class="punct">'</span><span class="string">SMTP session already started</span><span class="punct">'</span> <span class="keyword">if</span> <span class="attribute">@started</span><br /> <span class="ident">check_auth_args</span> <span class="ident">user</span><span class="punct">,</span> <span class="ident">secret</span><span class="punct">,</span> <span class="ident">authtype</span> <span class="keyword">if</span> <span class="ident">user</span> <span class="keyword">or</span> <span class="ident">secret</span><br /><br /> <span class="ident">sock</span> <span class="punct">=</span> <span class="ident">timeout</span><span class="punct">(</span><span class="attribute">@open_timeout</span><span class="punct">)</span> <span class="punct">{</span> <span class="constant">TCPSocket</span><span class="punct">.</span><span class="ident">open</span><span class="punct">(</span><span class="attribute">@address</span><span class="punct">,</span> <span class="attribute">@port</span><span class="punct">)</span> <span class="punct">}</span><br /> <span class="attribute">@socket</span> <span class="punct">=</span> <span class="constant">Net</span><span class="punct">::</span><span class="constant">InternetMessageIO</span><span class="punct">.</span><span class="ident">new</span><span class="punct">(</span><span class="ident">sock</span><span class="punct">)</span><br /> <span class="attribute">@socket</span><span class="punct">.</span><span class="ident">read_timeout</span> <span class="punct">=</span> <span class="number">60</span> <span class="comment">#@read_timeout</span><br /> <span class="attribute">@socket</span><span class="punct">.</span><span class="ident">debug_output</span> <span class="punct">=</span> <span class="constant">STDERR</span> <span class="comment">#@debug_output</span><br /><br /> <span class="ident">check_response</span><span class="punct">(</span><span class="ident">critical</span> <span class="punct">{</span> <span class="ident">recv_response</span><span class="punct">()</span> <span class="punct">})</span><br /> <span class="ident">do_helo</span><span class="punct">(</span><span class="ident">helodomain</span><span class="punct">)</span><br /><br /> <span class="keyword">raise</span> <span class="punct">'</span><span class="string">openssl library not installed</span><span class="punct">'</span> <span class="keyword">unless</span> <span class="keyword">defined?</span><span class="punct">(</span><span class="constant">OpenSSL</span><span class="punct">)</span><br /> <span class="ident">starttls</span><br /> <span class="ident">ssl</span> <span class="punct">=</span> <span class="constant">OpenSSL</span><span class="punct">::</span><span class="constant">SSL</span><span class="punct">::</span><span class="constant">SSLSocket</span><span class="punct">.</span><span class="ident">new</span><span class="punct">(</span><span class="ident">sock</span><span class="punct">)</span><br /> <span class="ident">ssl</span><span class="punct">.</span><span class="ident">sync_close</span> <span class="punct">=</span> <span class="constant">true</span><br /> <span class="ident">ssl</span><span class="punct">.</span><span class="ident">connect</span><br /> <span class="attribute">@socket</span> <span class="punct">=</span> <span class="constant">Net</span><span class="punct">::</span><span class="constant">InternetMessageIO</span><span class="punct">.</span><span class="ident">new</span><span class="punct">(</span><span class="ident">ssl</span><span class="punct">)</span><br /> <span class="attribute">@socket</span><span class="punct">.</span><span class="ident">read_timeout</span> <span class="punct">=</span> <span class="number">60</span> <span class="comment">#@read_timeout</span><br /> <span class="attribute">@socket</span><span class="punct">.</span><span class="ident">debug_output</span> <span class="punct">=</span> <span class="constant">STDERR</span> <span class="comment">#@debug_output</span><br /> <span class="ident">do_helo</span><span class="punct">(</span><span class="ident">helodomain</span><span class="punct">)</span><br /><br /> <span class="ident">authenticate</span> <span class="ident">user</span><span class="punct">,</span> <span class="ident">secret</span><span class="punct">,</span> <span class="ident">authtype</span> <span class="keyword">if</span> <span class="ident">user</span><br /> <span class="attribute">@started</span> <span class="punct">=</span> <span class="constant">true</span><br /><span class="keyword">ensure</span><br /> <span class="keyword">unless</span> <span class="attribute">@started</span><br /> <span class="comment"># authentication failed, cancel connection.</span><br /> <span class="attribute">@socket</span><span class="punct">.</span><span class="ident">close</span> <span class="keyword">if</span> <span class="keyword">not</span> <span class="attribute">@started</span> <span class="keyword">and</span> <span class="attribute">@socket</span> <span class="keyword">and</span> <span class="keyword">not</span> <span class="attribute">@socket</span><span class="punct">.</span><span class="ident">closed?</span><br /> <span class="attribute">@socket</span> <span class="punct">=</span> <span class="constant">nil</span><br /> <span class="keyword">end</span><br /><span class="keyword">end</span><br /><br /><span class="keyword">def </span><span class="method">do_helo</span><span class="punct">(</span><span class="ident">helodomain</span><span class="punct">)</span><br /> <span class="keyword">begin</span><br /> <span class="keyword">if</span> <span class="attribute">@esmtp</span><br /> <span class="ident">ehlo</span> <span class="ident">helodomain</span><br /> <span class="keyword">else</span><br /> <span class="ident">helo</span> <span class="ident">helodomain</span><br /> <span class="keyword">end</span><br /> <span class="keyword">rescue</span> <span class="constant">Net</span><span class="punct">::</span><span class="constant">ProtocolError</span><br /> <span class="keyword">if</span> <span class="attribute">@esmtp</span><br /> <span class="attribute">@esmtp</span> <span class="punct">=</span> <span class="constant">false</span><br /> <span class="attribute">@error_occured</span> <span class="punct">=</span> <span class="constant">false</span><br /> <span class="keyword">retry</span><br /> <span class="keyword">end</span><br /> <span class="keyword">raise</span><br /> <span class="keyword">end</span><br /><span class="keyword">end</span><br /><br /><span class="keyword">def </span><span class="method">starttls</span><br /> <span class="ident">getok</span><span class="punct">('</span><span class="string">STARTTLS</span><span class="punct">')</span><br /><span class="keyword">end</span><br /><br /><span class="keyword">def </span><span class="method">quit</span><br /> <span class="keyword">begin</span><br /> <span class="ident">getok</span><span class="punct">('</span><span class="string">QUIT</span><span class="punct">')</span><br /> <span class="keyword">rescue</span> <span class="constant">EOFError</span><span class="punct">,</span> <span class="constant">OpenSSL</span><span class="punct">::</span><span class="constant">SSL</span><span class="punct">::</span><span class="constant">SSLError</span><br /> <span class="keyword">end</span><br /><span class="keyword">end</span><br /><span class="keyword">end</span><br /><span class="keyword">end</span><br /><br /></pre>Alexhttp://www.blogger.com/profile/04839463833553068390noreply@blogger.comtag:blogger.com,1999:blog-4403526088545417126.post-19105569750636280522007-11-15T13:55:00.000-05:002007-11-16T11:54:55.778-05:00Syntax Coloring for Dynamic StylesheetsI often need to dynamically generate stylesheets. Thankfully this path is well worn and solutions are readily available for Ruby on Rails. I chose the ERb/CSS based solution presented here:<br /><br /><a href="http://blog.hasmanythrough.com/2006/03/23/dirt-simple-rcss-templates">Dirt Simple .rcss templates</a><br /><a href="http://blog.hasmanythrough.com/2007/10/18/simpler-than-dirt-restful-dynamic-css">Simpler than dirt: RESTful Dynamic CSS<br /></a><br />If you're in the market, I'd also recommend looking at <a href="http://haml.hamptoncatlin.com/docs/rdoc/classes/Sass.html">Sass (Syntactically Awesome StyleSheets)</a>. I'll explain my choice in favor of ERb/CSS in a future post.<br /><br />One of the issues with the ERb/CSS solution is that editors are not aware of the syntax. To remedy this, I have created a plugin for ActiveState's Komodo IDE .<br /><br />The plugins are here (with the usual <a href="http://www.alexpmay.com/disclaimer">disclaimer</a>):<br /><br /><a href="http://www.alexpmay.com/css-erb-highlight-only-1.0.0-ko.xpi">css-erb-highlight-only-1.0.0-ko.xpi</a><br /><a href="http://www.alexpmay.com/css-erb-highlight-and-check-1.0.0-ko.xpi">css-erb-highlight-and-check-1.0.0-ko.xpi</a><br /><a href="http://www.alexpmay.com/rcss-highlight-only-1.0.0-ko.xpi">rcss-highlight-only-1.0.0-ko.xpi</a><br /><a href="http://www.alexpmay.com/rcss-highlight-and_check-1.0.0-ko.xpi">rcss-highlight-and_check-1.0.0-ko.xpi</a><br /><br />The "highlight-and-check" versions provide syntax highlighting, syntax checking, and auto indentation. However due to a shortcoming in ActiveState's tools, the syntax checking is imperfect and you will see syntax errors where there are none. I will remedy this as soon at the tools allow.<br /><br />It should go without saying that the "highlight-only" versions only provide syntax highlighting, and the "css-erb" and "rcss" versions provide the functionality for the ".css.erb" and ".rcss" extensions respectively.<br /><br />In a future post, I hope detail how these extensions were created.<br /><br />I'm using Komodo IDE 4.2 on Mac OS X, but I believe the extensions will work in all Komodo 4 products. Please let me know if they don't.Alexhttp://www.blogger.com/profile/04839463833553068390noreply@blogger.com