<?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"
	>

<channel>
	<title>Foliosus &#187; Web Technology</title>
	<atom:link href="http://www.foliosus.com/category/web-technology/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.foliosus.com</link>
	<description>Plants, food and web design</description>
	<pubDate>Mon, 05 May 2008 23:27:50 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>Connecting Ruby on Rails to Oracle on an Intel Mac in Leopard, take 2</title>
		<link>http://www.foliosus.com/2008/05/05/connecting-ruby-on-rails-to-oracle-on-an-intel-mac-in-leopard-take-2/</link>
		<comments>http://www.foliosus.com/2008/05/05/connecting-ruby-on-rails-to-oracle-on-an-intel-mac-in-leopard-take-2/#comments</comments>
		<pubDate>Mon, 05 May 2008 23:24:31 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/?p=99</guid>
		<description><![CDATA[Since I posted the first version of this article, there have been a couple of changes.  The biggest one is that Intel has released Intel Mac versions of the InstantClient.  Woohoo!  That makes the previous version rather too complicated, so I&#8217;ve updated it here.  This tutorial assumes that you&#8217;re using Rails [...]]]></description>
			<content:encoded><![CDATA[<p>Since I posted the first version of this article, there have been a couple of changes.  The biggest one is that Intel has released Intel Mac versions of the InstantClient.  Woohoo!  That makes the previous version rather too complicated, so I&#8217;ve updated it here.  This tutorial assumes that you&#8217;re using Rails 2.0 or greater.  If you&#8217;re starting from the setup we had before, and you want to fix it, <a href="#fat_fix" title="Jump to the fixer-upper instructions">start with the cleanup instructions at the bottom</a>, and then come back here. <span id="more-99"></span></p>
<h2 id="get_oracle">Grab the new Oracle InstantClient libraries</h2>
<p>The new Intel Mac versions are available from the <a href="http://www.oracle.com/technology/software/tech/oci/instantclient/htdocs/intel_macsoft.html" title="Get the libraries: login required">Oracle downloads site</a>.  Install them in <code>/Library/Oracle/</code>.  You can do side-by-side installations in folders with whatever names you want, since apps find them by using the <code>$ORACLE_HOME</code> environment variable (and it&#8217;s friends). I&#8217;ve got mine in <code>/Library/Oracle/instantclient/10.2.0.4</code>.  Also make sure that you&#8217;ve got the files required to run sqlplus and the sdk.  You can drop those in the same directory.</p>
<p>Oh, and don&#8217;t forget to copy over your <code>tnsnames.ora</code> file.</p>
<h3>Symlink the libraries</h3>
<p>In the directory where you&#8217;ve installed the instant client, run this:</p>
<pre class="code">ln -s libclntsh.dylib.10.1 libclntsh.dylib</pre>
<h3>Set the environment variables correctly</h3>
<p>You&#8217;ll probably want to put these lines in your <code>.bash_profile</code>, but they also must be run (or <code>source</code>&#8216;d) from the command line to take effect:</p>
<pre class="code">export ORACLE_HOME=/Library/Oracle/instantclient/10.2.0.4
export TNS_ADMIN=$ORACLE_HOME
export LD_LIBRARY_PATH=$ORACLE_HOME
export DYLD_LIBRARY_PATH=$ORACLE_HOME
export PATH=$PATH:$ORACLE_HOME
</pre>
<p>On to the next step, making Rails &#038; Oracle play nice.</p>
<h2>Getting Rails to talk to Oracle</h2>
<p>First,</p>
<pre class="code">sudo gem install activerecord-oracle-adapter --source http://gems.rubyonrails.org</pre>
<p>This installs the oracle adapter, which is how ActiveRecord deals with Oracle.  It doesn&#8217;t, however, install the Ruby oci8 driver, which is how Ruby talks to Oracle.  We&#8217;ll do that now.</p>
<h3>Compile the ruby-oci8 library</h3>
<p>Make sure you’ve got the <a title="Download the Oracle Instant Client SDK" href="http://www.oracle.com/technology/software/tech/oci/instantclient/htdocs/intel_macsoft.html">Oracle Instant Client SDK</a> installed in your Oracle Instant Client directory (/Library/Oracle/instantclient/10.2.0.4)</p>
<p>The most recent stable version of the oci8 library is <a title="Ruby oci8 library" href="http://rubyforge.org/projects/ruby-oci8/">1.0.1</a>.  Download it and unpack the file in the finder: it should unzip into <code>~/Downloads/ruby-oci8-1.0.1</code>.</p>
<p>Now we can finish configuring the environment before we compile the library.</p>
<pre class="code">cd ~/Downloads/ruby-oci8-1.0.0
export SQLPATH=$ORACLE_HOME
export RC_ARCHS=i386
ruby setup.rb config
make
sudo make install</pre>
<p>These steps should cause some compiler output to scroll by.  Pay attention if you run into any errors on the setup step; the error messages are reasonably helpful at pointing you towards any problems.</p>
<h2>Test connectivity</h2>
<p>At this point, we&#8217;re done.  We&#8217;ve got the latest Oracle InstantClient, and we&#8217;ve installed the ruby-oci8 library.  Now it&#8217;s a question of making sure that everything works as advertised:</p>
<pre class="code">ruby /usr/bin/irb</pre>
<p>In the IRb console, type:</p>
<pre class="code">require 'oci8'</pre>
<p>If the console returns <code>true</code> or <code>[]</code>, you’re in business.</p>
<h2>Configure your database.yml</h2>
<p>The last step is to make your application use the Oracle connection.  In your <code>database.yml</code>, use the following to make it work:</p>
<pre class="code">development:
adapter: oracle
database: your_instance_name
username: your_user_name
password: your_password</pre>
<p>The database name comes straight out of your <code>tnsnames.ora</code> file.  You don&#8217;t need to specify any other connection information in <code>database.yml</code>, since the <code>tnsnames.ora</code> file has everything you need.</p>
<p>Your application is now talking to Oracle, without Rosetta!</p>
<h2 id="fat_fix">Fix the <code>ruby_fat</code> and <code>ruby_ppc</code> setup</h2>
<p>If you followed my <a href="/2007/11/19/connecting-ruby-on-rails-to-oracle-on-an-intel-mac-in-leopard-mac-osx-105/" title="Don't read these: you don't want them anymore">previous instructions</a> and went through all of the shenanigans with the <code>ruby_ppc</code> and <code>ruby_fat</code> versions and would like to undo them, it&#8217;s quite simple.  Just remove the <code>ruby_ppc</code> files, and the symlinks to them (called <code>ruby</code>, and rename <code>ruby_fat</code> as <code>ruby</code>:</p>
<pre class="code">cd /usr/bin
sudo rm ruby
sudo rm ruby_ppc
sudo mv ruby_fat ruby
cd /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin
sudo rm ruby
sudo rm ruby_ppc
sudo mv ruby_fat ruby</pre>
<p>Then, you should also remove the 2 management scripts:</p>
<pre class="code">sudo rm /usr/bin/ppc_ruby.sh
sudo rm /usr/bin/fat_ruby.sh</pre>
<p>And that&#8217;s enough for the cleanup.  From here you can start following the instructions beginning with <a href="#get_oracle" title="Start from the top">getting the new Oracle libraries.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2008/05/05/connecting-ruby-on-rails-to-oracle-on-an-intel-mac-in-leopard-take-2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>HOWTO monkeypatch Rake: overriding a Rake task</title>
		<link>http://www.foliosus.com/2008/05/05/howto-monkeypatch-rake-overriding-a-rake-task/</link>
		<comments>http://www.foliosus.com/2008/05/05/howto-monkeypatch-rake-overriding-a-rake-task/#comments</comments>
		<pubDate>Mon, 05 May 2008 16:33:49 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/?p=98</guid>
		<description><![CDATA[I know that some people really don&#8217;t like monkeypatching, and I see why.  But sometimes it&#8217;s just unavoidable.  Recently at work we came across a situation where the standard rake db:schema:dump task just wasn&#8217;t working. So I started by writing the new version of the rake task that I wanted:
namespace :db do
  [...]]]></description>
			<content:encoded><![CDATA[<p>I know that some people really don&#8217;t like monkeypatching, and I see why.  But sometimes it&#8217;s just unavoidable.  Recently at work we came across a situation where the standard <code>rake db:schema:dump</code> task just wasn&#8217;t working. So I started by writing the new version of the rake task that I wanted:</p>
<pre class="code">namespace :db do
  namespace :schema do
    desc "Create a db/schema.rb file"
    task :dump => :environment do
      require 'active_record/schema_dumper'
      puts "Creating schema:"
      File.open(ENV['SCHEMA'] || &#8220;db/schema.rb&#8221;, &#8220;w&#8221;) do |file|
        ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
      end
    end
  end
end</pre>
<p>This task as shown does exactly what the default rake task does, except for the <code>puts</code> line.  Let&#8217;s just pretend that it&#8217;s a radically different and wonderful version that solves world hunger and raises your children. Now, if you drop this into a rakefile in your app&#8217;s <code>lib/tasks</code> directory, and then you run <code>rake db:schema:dump --trace</code> you&#8217;ll notice that the schema.rb file gets created <strong>twice</strong>.  What the??? <span id="more-98"></span></p>
<h3>Check the docs</h3>
<p>So I started poking around the <a href="http://rake.rubyforge.org/" title="Read the RDocs for Rake">Rake docs</a>. <code>Rake::Task.define_task</code> does the following:</p>
<blockquote><p>Define a task given args and an option block. If a rule with the given name already exists, the prerequisites and actions are added to the existing task. Returns the defined task.</p></blockquote>
<p>Aha!  So instead of overriding the existing task (monkeypatching it), I&#8217;m adding to it.  That&#8217;s why the schema gets dumped twice.  But what if I don&#8217;t want that?  What to do if I want to replace the rake task with my new version?</p>
<h3>Check the internets</h3>
<p>About an hour of googling later, I finally came across <a href="http://matthewbass.com/2007/03/07/overriding-existing-rake-tasks/" title="The solution to my rake problems!">a post from Matthew Bass</a> explaining the solution to my problem:</p>
<pre class="code">Rake::TaskManager.class_eval do
  def remove_task(task_name)
    @tasks.delete(task_name.to_s)
  end
end

def remove_task(task_name)
  Rake.application.remove_task(task_name)
end

# Override existing test task to prevent integrations
# from being run unless specifically asked for
remove_task 'db:schema:dump'

# Now define db:schema:dump again, the way we did above</pre>
<p>And that was it. It&#8217;s relatively straight-forward, but has a tendency to do strange things when rails gets updated.  So you could abstract it into <a href="http://www.taknado.com/2007/7/30/overriding-rake-tasks" title="Plugin to override or monkeypatch rake tasks">a plugin</a>, with tests, but don&#8217;t forget to test it whenever you <code>gem update rails</code>.</p>
<h3>Alternative solution</h3>
<p>While I was googling I also ran into <a href="http://playtype.net/past/2008/3/27/multiple_databases_in_rails_without/" title="alias_task_chain source">a very interesting post on <code>alias_task_chain</code></a>, a method that patches Rake tasks to work like more typical methods with <code>alias_method_chain</code>.  If you were clever and wanted to spend the time, you could get a solution to the problem using this method.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2008/05/05/howto-monkeypatch-rake-overriding-a-rake-task/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to choose a web designer, freelancer or agency</title>
		<link>http://www.foliosus.com/2008/03/25/how-to-choose-a-web-designer-freelancer-or-agency/</link>
		<comments>http://www.foliosus.com/2008/03/25/how-to-choose-a-web-designer-freelancer-or-agency/#comments</comments>
		<pubDate>Wed, 26 Mar 2008 06:25:04 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Design]]></category>

		<category><![CDATA[Web Technology]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2008/03/25/how-to-choose-a-web-designer-freelancer-or-agency/</guid>
		<description><![CDATA[Before I launch in to this, let me just say that, really, there&#8217;s no universally right way to choose the ideal web designer.  There is no idea web designer.  There&#8217;s just the best way for you, and the best web designer for you.  I hope that the thoughts I lay out below [...]]]></description>
			<content:encoded><![CDATA[<p>Before I launch in to this, let me just say that, really, there&#8217;s no universally <em>right</em> way to choose the ideal web designer.  There is no idea web designer.  There&#8217;s just the best way for you, and the best web designer for you.  I hope that the thoughts I lay out below help you to clear up your right way is.</p>
<h3>What you know</h3>
<p>Some clients approach me saying that they want a website.  Some say that they want a website that looks nice.  Some say they want a website that performs functions x, y and z. Some say they want a website set in 12pt Verdana with a background that&#8217;s exactly this shade of green, on a 960 pixel grid.  And written in PHP with a custom CMS, please.</p>
<p>There&#8217;s nothing wrong with any of these, although the last client always tends to give me pause, for reasons I&#8217;ll discuss at the end of the article.  I like to think of hiring a web professional the way I would hire a contractor to work on my house.  Because, really, that&#8217;s what you&#8217;re doing: you&#8217;re hiring a contractor to work on your digital house.  Not all contractors are the same.  They produce work of differing quality, in different styles and at different prices.</p>
<p>The problem for most home owners/clients is that the sheer number of choices is overwhelming; they don&#8217;t even know where to start.  If you want a contractor for your house, there&#8217;s a very clear geographic constraint on the choice &mdash; the contractor must be in the same place as you, so they can come to your house to do the work.  But with the web, that&#8217;s not true; we&#8217;re all just one e-mail away from each other. (6 degrees of separation? Hah!)</p>
<p><span id="more-91"></span></p>
<h3>Who might you hire?</h3>
<p>Chances are pretty good that you&#8217;re not the first business in your industry to have a website.  They&#8217;re also pretty good that you&#8217;re not the first business of your size to have a website.  So look at some of these other businesses on the web, and find out who did their sites.  Most web pros will have some link to themselves somewhere on the sites they design, usually in the footer or on an &#8220;About&#8221; page.</p>
<p>Start building a list of potential contractors in this way.  You can also do a Google local search to find web designers in your area.  They have the advantage of being able to meet you face to face, which is something that I really like, although it&#8217;s not necessary.</p>
<p>You&#8217;ll very quickly end up with 10-20 potential site builders this way.  Collect &#8216;em all.</p>
<h3>Who do you like?</h3>
<p>This is the most fun part of selecting a web designer: making a short list.  Everybody&#8217;s a critic, and this is your chance. Start by browsing their web sites.</p>
<p>If their site is old, clunky or ugly, then maybe you should take them off the list.  If they tend to make sites radically different from the kind of site you&#8217;re looking for, take them off.  If their personal style doesn&#8217;t match up with your vision of your site, then perhaps they&#8217;re not right for you.  Although be careful; some people have amazing ranges and can surprise you.</p>
<p>Many web pros have a blog.  Read some of it.  Do they seem like the kind of person you would want working for you?</p>
<p>After going through this, you should be down to some kind of a short list.</p>
<h3>Your ideas</h3>
<p>Note that, so far, I haven&#8217;t said much about refining the ideas for your site.  That&#8217;s because you don&#8217;t need to do that alone. The analogy about hiring a contractor isn&#8217;t really appropriate anymore.  Really, when you hire someone (or some company) to build your site, you&#8217;re hiring an architect <em>and</em> a contractor all at the same time.  The architect will help you refine your vision when you&#8217;re deciding on the addition to your house; let the web professional do the same.</p>
<p>You shouldn&#8217;t refine your ideas alone.  The best designs come from lots of interaction between the designer and the client.</p>
<h3>Talk to them</h3>
<p>Now we get down to the nitty gritty. E-mail or call every member of your short list, and make an appointment. Speak with them.  Ask them about their process.  How do they get you from where you are to having a completed site?  How much feedback is there between them and you along the way?  What does their process emphasize? How flexible is the process?</p>
<p>Although there are wrong answers to these questions, there aren&#8217;t any right answers.  What&#8217;s important here is that the way they work fit with what you want.  Personality is a big part of this.  You have to be able to talk to your web pro, and you have to be able to trust that their process will produce the end result that you&#8217;re looking for.</p>
<h3>Get a quote</h3>
<p>This one speaks for itself.  Get a quote.  Find out what their pricing method is.  Do they bill hourly?  Is it a flat fee?  What are the restrictions about changing details of the project mid-stream?  What kind of timeline can they work with?  Is the quote firm?</p>
<p>Again, there aren&#8217;t really right answers, although there can be wrong ones. Comparing quotes is very difficult, as they are frequently apples and oranges. Unfortunately I don&#8217;t really have any good advice here, except this: in the low range of web design, you almost always get what you pay for, but above that it&#8217;s a free-for-all, and price frequently bears little correlation to the quality of the finished product. </p>
<h4>Be wary of hidden costs</h4>
<p>Be careful about hidden costs. For example, all web sites need to be hosted somewhere.  Does your web designer offer their own web hosting?  Many do.  If so, what do they charge?  What does the charge include?  You can easily price this against any web hosting company&#8217;s rates to see if what you&#8217;re paying is reasonable.</p>
<p>If they don&#8217;t offer hosting, will they set you up with a reputable web host?  Will they charge you for that?</p>
<p>How does your site get updated?  Will you be able to do it, without breaking anything?  If not, how much will it cost you to make changes?  Be wary of being nickel-and-dimed to death with site updates, especially when nickels cost $80 an hour.</p>
<p>Search engine optimization (SEO) is another favored charge.  Some web pros won&#8217;t submit your new site to the search engines.  Or they will charge you for it.  Some will issue repeated charges for re-submission every few months.  This is a very bad idea: once the search engines are aware of you, they will re-index your site regularly.  Re-submission is usually grounds for removal of your site from their search results. There can be a wide variety of charges associated with SEO; make sure that they are legitimate and useful for you.</p>
<h3>Choose someone!</h3>
<p>By now you&#8217;re very well equipped to choose the best web designer for you.  You know a lot about the people on your short list: you understand something about who they are, how they think and how they will approach your project. Weigh that against your budget, and make your choice.</p>
<h3>Trust your designer</h3>
<p>Once you have chosen a designer, don&#8217;t be afraid to trust them.  If you don&#8217;t think you can trust them, <em>don&#8217;t hire them</em>.</p>
<p>If you know as much as your designer does about web technology, then hiring them is a bad idea; let them sort out the design and the tech.  They know if PHP is the best technology for your site or not. Discuss it with them, but listen to what they have to say.  After all, you hired them to be your web expert.  As long as you have enough input in to the process, they should be trusted to make the best decisions for you.  If they can&#8217;t, then you hired a bad web professional &mdash; fire them and get your money back.</p>
<p>With trust and confidence on both sides, you will end up with a site that you love.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2008/03/25/how-to-choose-a-web-designer-freelancer-or-agency/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Microsoft has seen the light on IE8</title>
		<link>http://www.foliosus.com/2008/03/03/microsoft-has-seen-the-light-on-ie8/</link>
		<comments>http://www.foliosus.com/2008/03/03/microsoft-has-seen-the-light-on-ie8/#comments</comments>
		<pubDate>Tue, 04 Mar 2008 06:13:35 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Browsers]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2008/03/03/microsoft-has-seen-the-light-on-ie8/</guid>
		<description><![CDATA[Woohoo! Today, Microsoft made the right decision about IE8. The default rendering mode will be fully standards compliant. They&#8217;re not going to punish the people who know what they&#8217;re doing.
This is truly great news, for several reasons.  One is that Microsoft is now arguing for greater openness.  That can only help the marketplace. [...]]]></description>
			<content:encoded><![CDATA[<p><b>Woohoo!</b> Today, <a href=http://blogs.msdn.com/ie/archive/2008/03/03/microsoft-s-interoperability-principles-and-ie8.aspx" title="Read the announcement for yourself">Microsoft made the right decision about IE8.</a> The default rendering mode will be fully standards compliant. They&#8217;re not going to <a href="/2008/01/22/two-wrongs-dont-make-a-right-microsoft-needs-to-fix-themselves/" title="Read my earlier post on the subject">punish the people who know what they&#8217;re doing</a>.</p>
<p>This is truly great news, for several reasons.  One is that Microsoft is now arguing for greater openness.  That can only help the marketplace. The other is that, for the first time in a long time, they&#8217;re making a very good decision with respect to IE, and they&#8217;re making it <em>for the right reasons</em>.  They&#8217;re making it because they want to play nicer with their clients and their developers.  That&#8217;s what I call a win-win: they win, and we win.  Everybody wins!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2008/03/03/microsoft-has-seen-the-light-on-ie8/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Call URLs on your app from the Rails console</title>
		<link>http://www.foliosus.com/2008/02/06/call-urls-on-your-app-from-the-rails-console/</link>
		<comments>http://www.foliosus.com/2008/02/06/call-urls-on-your-app-from-the-rails-console/#comments</comments>
		<pubDate>Wed, 06 Feb 2008 19:46:37 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2008/02/06/call-urls-on-your-app-from-the-rails-console/</guid>
		<description><![CDATA[Here&#8217;s a neat trick I just learned from Obie Fernandez (The Rails Way, p. 30: you can see what your Rails app&#8217;s HTML output is from the console. To make this work you have to fool the app into thinking that there&#8217;s a request coming in by setting some environmental variables, and then call the [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a neat trick I just learned from Obie Fernandez (<a href="http://www.amazon.com/exec/obidos/tg/detail/-/0321445619/foliosuscom-20" title="Buy the book from Amazon">The Rails Way</a>, p. 30: you can see what your Rails app&#8217;s HTML output is from the console. To make this work you have to fool the app into thinking that there&#8217;s a request coming in by setting some environmental variables, and then call the dispatcher.</p>
<p>But wouldn&#8217;t it be nice to have a single method call, that uses <code>url_for</code> syntax?</p>
<p><span id="more-92"></span></p>
<pre class="code">class Object
  def request(options = {})
    method = options.delete(:method) || :get
    options.reverse_merge!(:only_path => true)
    ENV['REQUEST_URI'] = app.url_for(options)
    ENV['REQUEST_METHOD'] = method.to_s
    Dispatcher.dispatch
  end
end</pre>
<p>First we pull the method (<code>:get</code>, <code>:post</code> etc.) out, if it exists.  By default we want it to be <code>:get</code>.  Then we call <code>url_for</code> and have it only return the path, without any leading domain info.  Next we populate the environmental variables and call the dispatcher.  The return output will be the HTML your app renders.</p>
<p>To make the trick universally accessible on your development box, put the above code in <code>~/.irbrc</code>:</p>
<p>Then, fire up the console to your favorite rails app, and call:</p>
<pre class="code">>> request(:controller => 'my_controller', :action => 'the_action')</pre>
<p>You should see the HTML output scroll by.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2008/02/06/call-urls-on-your-app-from-the-rails-console/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Two wrongs don&#8217;t make a right: Microsoft needs to fix themselves</title>
		<link>http://www.foliosus.com/2008/01/22/two-wrongs-dont-make-a-right-microsoft-needs-to-fix-themselves/</link>
		<comments>http://www.foliosus.com/2008/01/22/two-wrongs-dont-make-a-right-microsoft-needs-to-fix-themselves/#comments</comments>
		<pubDate>Wed, 23 Jan 2008 02:30:50 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Browsers]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2008/01/22/two-wrongs-dont-make-a-right-microsoft-needs-to-fix-themselves/</guid>
		<description><![CDATA[Yesterday two articles appeared at A List Apart discussing a Microsoft-backed proposal to change how the web works (round-up here).  The proposal, on its face, is quite simple.  Developers would put a meta tag in their documents (X-UA-Compatible) stating what version of a browser the pages were coded against.  The browsers would [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday two articles appeared at <a href="http://www.alistapart.com/issues/251" title="read the articles here">A List Apart</a> discussing a Microsoft-backed proposal to change how the web works (<a href="http://www.digital-web.com/news/2008/01/IE8_Version_Targeting_causes_quite_a_stir" title="Summary of blog posts and articles about this">round-up here</a>).  The proposal, on its face, is quite simple.  Developers would put a meta tag in their documents (<code>X-UA-Compatible</code>) stating what version of a browser the pages were coded against.  The browsers would read the tag, and render the page with legacy behavior, including all of the quirks, of that browser.  The goal is to &#8220;not break the web&#8221; with browser upgrades.</p>
<p>It sounds like a great idea, right? I mean, why should I have to worry that Microsoft released IE7? If I used this tag, and specified IE6, then my page would always render correctly in IE, even if IE was on version 28.</p>
<h3>WRONG!!!</h3>
<p><span id="more-88"></span></p>
<p>Let&#8217;s really look at this situation.  There are two wrongs here, and Microsoft wants to add a third.  Let&#8217;s look at how we got here.</p>
<ol>
<li>Microsoft made a bad browser: it didn&#8217;t (and still doesn&#8217;t) support the CSS standard</li>
<li>Developers everywhere screwed up by coding pages that take advantage of the IE bugs, in a way that breaks in standards-compliant browsers (never mind that conditional comments makes this unnecessary)</li>
<li>Microsoft upgrades IE to version 7, and those bad sites break</li>
<li>Microsoft says, &#8220;If every web developer were to just change how they work, we could have upgrades that are ok.&#8221;</li>
</ol>
<p>Do you see the fatal flaw in the logic?</p>
<p>It&#8217;s right there in steps 1 and 2.</p>
<p>If Microsoft made browsers that support the standards, we wouldn&#8217;t be in this mess.  I say, <strong>no</strong> to Microsoft&#8217;s proposal.  I say, if Microsoft doesn&#8217;t want to make browsers that support the standards, then their customers get what they deserve if the web starts breaking for them.  I say, how about Microsoft step up to the plate and make a rendering engine that works instead of relying on <strong>everyone else</strong> to fix their problems for them.</p>
<p>&#8220;But what about all of those pages that the IE7 upgrade broke?&#8221; you ask.  Those are bad pages, and IE7 is a bad browser.  They&#8217;re either not coded to standards, or IE7 choked on the correct standards-compliant code they were using, or both.  That&#8217;s why they broke.  The people who paid for that development should switch developers to get someone who knows what they&#8217;re doing, who will code pages that actually work.  The browser shouldn&#8217;t have been released if it didn&#8217;t support the standards.</p>
<p>This is why they&#8217;re called &#8220;Web Standards.&#8221;  Because they&#8217;re <em>standard</em>.  I make a page that works in Firefox, I know that it works in Safari.  I should know that it works in IE.  If that&#8217;s not true, then it&#8217;s IE&#8217;s problem, not mine.</p>
<h3>Note to Microsoft</h3>
<p><strong>FIX YOUR D*** BROWSER ALREADY</strong>. It&#8217;s almost been a <em>decade</em> since IE5 started support for CSS 2, and they still haven&#8217;t gotten it right.  They make <a href="http://en.wikipedia.org/wiki/Microsoft" title="I'm serious. They're wealthier than just about everybody.">$50 billion dollars a year</a> and can&#8217;t make their browser behave.</p>
<h3>Note to web developers</h3>
<p><strong>FIX YOUR D*** PAGES ALREADY</strong>. It&#8217;s almost been a <em>decade</em> since CSS2 came out.  You haven&#8217;t figured out how it works yet? You call yourself a professional?  Get with it.</p>
<h3>I&#8217;m a bleeding-heart liberal</h3>
<p><a href="http://www.zeldman.com/2008/01/22/in-defense-of-version-targeting/" title="A very good argument for the new proposal">Zeldman</a> posted about people just like me.  He says, &#8220;We won’t get converts by breaking sites and ridiculing their creators for not knowing as much as we do.&#8221;  He&#8217;s right.</p>
<p>Except that we&#8217;ve tried that, and it doesn&#8217;t work.  It doesn&#8217;t work because many of the web pages out there aren&#8217;t made by professionals.  Anybody heard of Dreamweaver WYSIWYG mode?  If the pages work, people are happy.  Except that they don&#8217;t work.  If they work in IE6, but not in IE7, they never worked.  They just had the illusion of working.</p>
<p>Let&#8217;s make an analogy, to print design.  If I, a rank amateur in the print design world, decided to print a book in 5 point Comic Sans and it was totally illegible, that&#8217;s my problem.  It&#8217;s not the printer&#8217;s problem, or the reader&#8217;s problem.  It&#8217;s mine.  I screwed up, I made content that wasn&#8217;t accessible to anybody.  Some readers have figured out that if they use a magnifying glass, it&#8217;s not so bad, they can read it.  That doesn&#8217;t mean that my book wasn&#8217;t broken. Now let&#8217;s say that these people buy another book of mine, this time printed in 72 point Bembo.  With their magnifying glass, they now complain that the new book is broken!  They can&#8217;t read it.  Nobody else can either, because the type is just too big.  If I said, &#8220;Well, every publisher needs to do something so that my books are legible&#8221; you would say I&#8217;m stupid.  It&#8217;s up to me to books that are legible.  And that&#8217;s right.  That&#8217;s why it&#8217;s up to Microsoft to stop making a browser that&#8217;s broken and expecting people to work around them.  And it&#8217;s also up to developers to stop coddling the browser that&#8217;s broken.</p>
<h3>Why the doctype switch isn&#8217;t targeting</h3>
<p>One problem in this debate is that <a href="http://snook.ca/archives/browsers/version_targeting_ie8/" title="Snook got it wrong on this one">people are confusing doctype switching with version targeting</a>. Using a standard doctype is like a contract: I, the developer, support this <strong>standard</strong> of HTML and CSS, so that you, the browser, can render it properly according to the same <strong>standard</strong>.  The standard provides a common language, a shared vocabulary, so that the garbage I put in to the system is the same garbage that comes out.  Targeting a browser isn&#8217;t the same thing.  When I use conditional comments or other CSS hacks, I&#8217;m saying &#8220;hey browser, you&#8217;re don&#8217;t understand this sentence in our standard vocabulary, so I&#8217;m going to give you a sentence that you understand.&#8221;  That&#8217;s not the same thing as saying which vocab you&#8217;re using.  It&#8217;s like talking to a child — if you use a word the child doesn&#8217;t understand, you talk around it, explain it, you don&#8217;t switch languages.  If I use the new meta-tag, and I target IE7, IE8, or IE42, it should render my page the same, according to the contract I say I&#8217;m holding to in my doctype declaration.  End of story.  If they don&#8217;t then they&#8217;ve got bugs.</p>
<h3>Really?</h3>
<p>Are we really going this way? I can&#8217;t believe that this industry is even <em>considering</em> Microsoft&#8217;s proposal. If the browsers aren&#8217;t upholding their end of the contract, why should we work around them?  Let them be broken, let people decide they don&#8217;t want a broken browser, let the bad browsers die.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2008/01/22/two-wrongs-dont-make-a-right-microsoft-needs-to-fix-themselves/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Connecting Ruby on Rails to Oracle on an Intel Mac in Leopard (Mac OSX 10.5)</title>
		<link>http://www.foliosus.com/2007/11/19/connecting-ruby-on-rails-to-oracle-on-an-intel-mac-in-leopard-mac-osx-105/</link>
		<comments>http://www.foliosus.com/2007/11/19/connecting-ruby-on-rails-to-oracle-on-an-intel-mac-in-leopard-mac-osx-105/#comments</comments>
		<pubDate>Mon, 19 Nov 2007 16:58:15 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2007/11/19/connecting-ruby-on-rails-to-oracle-on-an-intel-mac-in-leopard-mac-osx-105/</guid>
		<description><![CDATA[NOTE: This tutorial has been superseded by a newer version that takes advantage of the newly-released Intel Mac version of the Oracle InstantClient. The new version is much, much simpler, and causes far fewer headaches.
Updated (12/11/07): The ruby-oci8 library just went to full 1.0.0 release.  I&#8217;ve updated that section to reflect the new file [...]]]></description>
			<content:encoded><![CDATA[<p><strong>NOTE:</strong> This tutorial has been superseded by <a href="/2008/05/05/connecting-ruby-on-rails-to-oracle-on-an-intel-mac-in-leopard-take-2/" title="Read this tutorial!  The one you're looking at isn't any good any more.">a newer version</a> that takes advantage of the newly-released Intel Mac version of the Oracle InstantClient. The new version is much, much simpler, and causes far fewer headaches.</p>
<p><strong>Updated (12/11/07):</strong> The <code>ruby-oci8</code> library just went to full 1.0.0 release.  I&#8217;ve updated that section to reflect the new file names.</p>
<p><strong>Updated (5/5/08):</strong> The oracle adapter installation has been on-again-off-again with successive Rails releases, but there&#8217;s an easy fix for it.  I&#8217;ve updated the relevant section.</p>
<p>At my new job, I&#8217;m using Ruby on Rails to connect to multiple databases — multiple Oracle (10g) instances, as well as MySQL and FileMaker.  There&#8217;s a lot of challenges to doing this, so I&#8217;m going to post some of the less obvious solutions as they come up.</p>
<p>The first challenge I had was to get RoR to talk to Oracle.  There isn&#8217;t a lot of information about this online, because the people who tend to use Oracle are not the people who tend to use open source software like Rails.</p>
<h2>Upgrade Rails to version 2.0</h2>
<p>To start out, I wanted to use the most recent release candidate of Rails: version 1.99.  I figured that I might as well upgrade before writing my first application, so that the codebase is all Rails 2.0 and up.  Leopard comes with both Ruby and Rails, and upgrading is actually very easy:<span id="more-80"></span></p>
<pre class="code">sudo gem install rails --source http://gems.rubyonrails.org</pre>
<p>Then enter “y” at each prompt, to install all of the dependencies.  That’s it!  Check yourself with</p>
<pre class="code">rails –v</pre>
<p>You should see <code>Rails 1.99.0</code> or <code>Rails 2.0</code>.</p>
<h2>Getting Rails to talk to Oracle</h2>
<p>Now,</p>
<pre class="code">sudo gem install activerecord-oracle-adapter --source http://gems.rubyonrails.org</pre>
<p>This installs the oracle adapter.  It doesn&#8217;t, however, install the Ruby oci8 driver.  We&#8217;ll do that now.</p>
<p>Make sure you’ve got the <a title="Download the Oracle Instant Client SDK" href="http://www.oracle.com/technology/software/tech/oci/instantclient/htdocs/macsoft.html">Oracle Instant Client SDK</a> installed in your Oracle Instant Client directory (/Library/Oracle/instantclient/10.1.0.3)</p>
<p>There&#8217;s a problem on new Intel Macs with this library.  Oracle hasn&#8217;t seen fit to release an Intel version of the library in the past year and a half, and that&#8217;s going to cause problems since the Ruby binary is going to run as Intel-native, but the Instant Client will run under Rosetta.  To solve this, we have to make a PPC version of the Ruby binary.</p>
<h3>Make PPC and fat versions of Ruby</h3>
<p>This is easier than it sounds.  We don&#8217;t have to recompile, since the Ruby binary in <code>/user/bin</code> is fat.  You can check this:</p>
<pre class="code">file `which ruby`</pre>
<p>This should show you a PPC and a i386 version:</p>
<pre class="code">/usr/bin/ruby_fat: Mach-O universal binary with 2 architectures
/usr/bin/ruby_fat (for architecture ppc7400):	Mach-O executable ppc
/usr/bin/ruby_fat (for architecture i386):	Mach-O executable i386</pre>
<p>All we have to do is extract the PPC version as a standalone binary, and trick the system into using that only.  It will make our Ruby slower, but it will get Ruby to talk to Oracle, so I&#8217;m willing to take the performance hit.  It&#8217;s so fast on the Intel Macs anyway, unless your Rails apps are doing massive amounts of processing, you probably won&#8217;t notice.</p>
<p>We&#8217;ll use <code>ditto</code> to extract the PPC version:</p>
<pre class="code">sudo ditto -arch ppc7400 /usr/bin/ruby /usr/bin/ruby_ppc
sudo mv /usr/bin/ruby /usr/bin/ruby_fat</pre>
<p>Now we&#8217;ve got two versions of the Ruby binary — the original fat version, and a PPC only version.</p>
<p>There&#8217;s a catch here, though: we actually have <em>two</em> copies of the <code>ruby</code> binary on our system.  The second binary is a part of the Ruby Framework, and that&#8217;s the binary that&#8217;s used by <code>irb</code>, <code>rake</code> and other very useful Rails helpers, so let&#8217;s fix this one too:</p>
<pre class="code">sudo ditto -arch ppc7400 /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby_ppc
sudo mv /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby_fat</pre>
<p>Now we&#8217;ll need a facility for switching between the fat and PPC only binaries.  Create <code>/usr/bin/ppc_ruby.sh</code>:</p>
<pre class="code">#!/bin/bash
ln -fs /usr/bin/ruby_ppc /usr/bin/ruby
ln -fs /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby_ppc /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby</pre>
<p>Create <code>/usr/bin/fat_ruby.sh</code>:</p>
<pre class="code">#!/bin/bash
ln -fs /usr/bin/ruby_fat /usr/bin/ruby
ln -fs /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby_fat /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby</pre>
<p>Now, make them both executable:</p>
<pre class="code">sudo chmod 0711 /usr/bin/ppc_ruby.sh
sudo chmod 0711 /usr/bin/fat_ruby.sh</pre>
<p>Run <code>ruby_ppc.sh</code> to switch to using the PPC version:</p>
<pre class="code">sudo /usr/bin/ppc_ruby.sh</pre>
<p>Verify this worked:</p>
<pre class="code">file `which ruby`</pre>
<p>This should return <code>/usr/bin/ruby: Mach-O executable PPC</code>.</p>
<p>We&#8217;re getting closer.  Now we need the ruby-oci8 library.</p>
<h3>Compile the ruby-oci8 library</h3>
<p>The most recent stable version of the oci8 library is <a title="Ruby oci8 library" href="http://rubyforge.org/projects/ruby-oci8/">1.0.0</a>.  Download it and unpack the file in the finder: it should unzip into <code>~/Downloads/ruby-oci8-1.0.0</code>.</p>
<p>Before we can compile this library, we have to fool the system into making it PPC only, or it&#8217;s not going to work.  With your favorite text editor, edit <code>/usr/lib/ruby/1.8/universal-darwin9.0/rbconfig.rb</code>.  Comment out line 17 (<code>'-arch ppc -arch i386'</code> and replace it with <code>'-arch ppc'</code>.  Save your changes.  Leave the file open in your text editor, because we&#8217;ll come back to it.</p>
<p>Now we can finish configuring the environment before we compile the library.</p>
<pre class="code">cd ~/Downloads/ruby-oci8-1.0.0
export DYLD_LIBRARY_PATH=/Library/Oracle/instantclient/10.1.0.3
export SQLPATH=/Library/Oracle/instantclient/10.1.0.3
ruby setup.rb config
make
sudo make install</pre>
<p>Now you can go back to your text editor and restore line 17, save your changes and exit.</p>
<h2>Test connectivity</h2>
<p>At this point, we&#8217;re done.  We&#8217;ve fooled our system into running a PPC version of Ruby under Rosetta, and we&#8217;ve installed the ruby-oci8 library.  Now it&#8217;s a question of making sure that it works:</p>
<pre class="code">ruby /usr/bin/irb</pre>
<p>In the IRb console, type:</p>
<pre class="code">require 'oci8'</pre>
<p>If the console returns <code>true</code>, you’re in business.</p>
<h2>Configure your database.yml</h2>
<p>The last step is to make your application use the Oracle connection.  In your database.yml, use the following to make it work:</p>
<pre class="code">development:
adapter: oracle
database: your_instance_name
username: your_user_name
password: your_password</pre>
<p>The database name comes straight out of your <code>/Library/Oracle/instantclient/10.1.0.3/network/admin/tnsnames.ora</code> file.  You don&#8217;t need to specify any other connection information in database.yml, since the tnsnames.ora file has everything you need.</p>
<p>Your application is now talking to Oracle!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2007/11/19/connecting-ruby-on-rails-to-oracle-on-an-intel-mac-in-leopard-mac-osx-105/feed/</wfw:commentRss>
		</item>
		<item>
		<title>HOWTO: Upgrade your Ruby on Rails install to version 2.0 on Leopard (Mac OSX 10.5)</title>
		<link>http://www.foliosus.com/2007/11/13/howto-upgrade-your-ruby-on-rails-install-to-version-20-on-leopard-mac-osx-105/</link>
		<comments>http://www.foliosus.com/2007/11/13/howto-upgrade-your-ruby-on-rails-install-to-version-20-on-leopard-mac-osx-105/#comments</comments>
		<pubDate>Tue, 13 Nov 2007 16:37:35 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Operating systems]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2007/11/13/howto-upgrade-your-ruby-on-rails-install-to-version-20-on-leopard-mac-osx-105/</guid>
		<description><![CDATA[This one&#8217;s real easy.  Leopard ships with a default Rails installation (/usr/bin/rails), but overriding it is quite simple, since it&#8217;s just a gem.
sudo gem install rails --source http://gems.rubyonrails.org
Then, enter &#8220;y&#8221; at each prompt, to install all of the dependencies.  That’s it!  Check yourself with:
rails -v
Right now it will show Rails 1.99.0 which [...]]]></description>
			<content:encoded><![CDATA[<p>This one&#8217;s <em>real</em> easy.  Leopard ships with a default Rails installation (<code>/usr/bin/rails</code>), but overriding it is quite simple, since it&#8217;s just a <code>gem</code>.</p>
<pre class="code">sudo gem install rails --source http://gems.rubyonrails.org</pre>
<p>Then, enter &#8220;y&#8221; at each prompt, to install all of the dependencies.  That’s it!  Check yourself with:</p>
<pre class="code">rails -v</pre>
<p>Right now it will show <code>Rails 1.99.0</code> which is the current release candidate.  When rails goes fully 2.0, the same instructions should work to get the full release installed.</p>
<p>And don&#8217;t forget, you can always <code>rake rails:freeze</code> to lock a Rails app to a particular version of Rails by copying all of the Rails libraries into the <code>/vendor</code> directory.</p>
<p>Happy coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2007/11/13/howto-upgrade-your-ruby-on-rails-install-to-version-20-on-leopard-mac-osx-105/feed/</wfw:commentRss>
		</item>
		<item>
		<title>An &#8220;else&#8221; condition for link_to_unless_current</title>
		<link>http://www.foliosus.com/2007/04/18/else_for_link_to_unless_current/</link>
		<comments>http://www.foliosus.com/2007/04/18/else_for_link_to_unless_current/#comments</comments>
		<pubDate>Thu, 19 Apr 2007 04:17:21 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2007/04/18/else_for_link_to_unless_current/</guid>
		<description><![CDATA[Every time I get frustrated with an aspect of Rails, it turns out that it&#8217;s just my idiocy and not actually something to do with Rails.
Most recently, I wanted to code this algorithm:
If on the current page
  show &#60;a href="blah1"&#62;link 1&#60;/a&#62;
else
  show &#60;a href="blah2&#62;link 2&#60;/a&#62;

Rails has, of course, the nifty link_to_unless_current, but all [...]]]></description>
			<content:encoded><![CDATA[<p>Every time I get frustrated with an aspect of Rails, it turns out that it&#8217;s just my idiocy and not actually something to do with Rails.</p>
<p>Most recently, I wanted to code this algorithm:</p>
<pre class="code">If on the current page
  show &lt;a href="blah1"&gt;link 1&lt;/a&gt;
else
  show &lt;a href="blah2&gt;link 2&lt;/a&gt;</pre>
<p><span id="more-69"></span></p>
<p>Rails has, of course, the nifty <span class="code">link_to_unless_current</span>, but all that does is show the text of the link:</p>
<pre class="code">If on the current page
  show link
else
  show &lt;a href="blah"&gt;link&lt;/a&gt;</pre>
<p>That&#8217;s not quite what I&#8217;m looking for.  But when I was looking up link_to_unless_current in the <a href="http://api.rubyonrails.org/" title="The full Rails API">docs</a>, I realized that there IS an else condition on <span class="code">link_to_unless_current</span>.  The function takes a block as its last parameter, and that&#8217;s what gives you the &#8220;else.&#8221;</p>
<p>This code, in a view:</p>
<pre class="code">&lt;%= link_to_unless_current('Link text', my_url) { 'Alternate text' } %&gt;</pre>
<p>produces this algorithmic result:</p>
<pre class="code">If on the current page
  show Alternate text
else
  show &lt;a href="my_url"&gt;Link text&lt;/a&gt;</pre>
<p>Mission accomplished.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2007/04/18/else_for_link_to_unless_current/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Fonts for the masses (of designers)</title>
		<link>http://www.foliosus.com/2006/08/29/fonts-for-the-masses-of-designers/</link>
		<comments>http://www.foliosus.com/2006/08/29/fonts-for-the-masses-of-designers/#comments</comments>
		<pubDate>Tue, 29 Aug 2006 18:43:43 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Design]]></category>

		<category><![CDATA[Ephemeral]]></category>

		<category><![CDATA[Web Technology]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2006/08/29/fonts-for-the-masses-of-designers/</guid>
		<description><![CDATA[Right on, Mr. H!
Andrei Herasimchuk has just written an open letter to John Warnock at Adobe, suggesting that he, and really Adobe, contribute a small group of roughly 10 core fonts to the public domain.  That&#8217;s not so cool.  What&#8217;s cool is the rationale behind the request.  If these fonts — fonts [...]]]></description>
			<content:encoded><![CDATA[<p>Right on, <a title="An open letter to John Warnock, by Andrei Herasimchuk" href="http://www.designbyfire.com/">Mr. H</a>!</p>
<p>Andrei Herasimchuk has just written <a title="Please let's have some fonts" href="http://www.designbyfire.com/?p=30">an open letter to John Warnock at Adobe</a>, suggesting that he, and really Adobe, contribute a small group of roughly 10 core fonts to the public domain.  That&#8217;s not so cool.  What&#8217;s cool is the rationale behind the request.  If these fonts — fonts like <a title="Great sans-serif" href="http://store.adobe.com/type/browser/P/P_1186.html">Frutiger</a>, <a title="The essence of modernism" href="http://store.adobe.com/type/browser/P/P_1199.html">Helvetica Neue</a> and <a title="Contemporary humanism" href="http://store.adobe.com/type/browser/P/P_1709.html">Warnock Pro</a> — go public and are released in Windows and MacOS distributions, then web designers might be able to use more than FIVE fonts for designing web pages.</p>
<p>Given the technological limitations that web designers face, what with problems in cross-browser support for standards as well as requirements for testing sites on multiple platforms (mac, win, cell phones, screen readers), it would be nice if we got a break for once, and were able to expand our design options beyond Helvetica, Times, Trebuchet, Georgia and Verdana.  As nice as those are, the inability to rely on any kind of typographical range is a real handicap.  If you&#8217;ve ever wondered why many &#8220;Web 2.0&#8243; sites look alike, look no further than the choice of 3 good sans-serif fonts that are truly avaliable cross-platform.  Choice of fonts will allow our sites to have unique character and identity.  Seriously — if Adobe released just 10 fonts in this manner, it would <em>triple</em> the number of available choices.</p>
<p>Mr. H, you have my support.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2006/08/29/fonts-for-the-masses-of-designers/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Ready or not, here I(E7) come(s)</title>
		<link>http://www.foliosus.com/2006/08/23/ready_or_not_here_ie_comes/</link>
		<comments>http://www.foliosus.com/2006/08/23/ready_or_not_here_ie_comes/#comments</comments>
		<pubDate>Wed, 23 Aug 2006 23:48:44 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Browsers]]></category>

		<category><![CDATA[CSS]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2006/08/23/ready_or_not_here_ie_comes/</guid>
		<description><![CDATA[Whether or not you&#8217;re ready for it, IE7 is coming.  And it&#8217;s coming soon.  It&#8217;s coming as an automatic update, although the IE7 blog folks have been a little shy about specifying a date.
This is great news!
Wait a minute.  Let&#8217;s try that again.
This should be great news!
The IE7 blog posted today about [...]]]></description>
			<content:encoded><![CDATA[<p>Whether or not you&#8217;re ready for it, IE7 is coming.  And it&#8217;s coming soon.  It&#8217;s coming as an <a title="IE7 developers' blog" href="http://blogs.msdn.com/ie/archive/2006/07/26/678149.aspx">automatic update</a>, although the IE7 blog folks have been a little shy about specifying a date.</p>
<p>This is great news!</p>
<p>Wait a minute.  Let&#8217;s try that again.</p>
<p>This should be great news!</p>
<p><span id="more-51"></span>The IE7 blog <a title="IE7 developers' blog" href="http://blogs.msdn.com/ie/archive/2006/08/22/712830.aspx">posted today</a> about all of the CSS rendering bugs that they&#8217;ve fixed. The list is extensive, including almost all of the problems from <a title="Insidious browser bugs revealed" href="http://www.positioniseverything.net">positioniseverything.net</a>.  Notice that I say almost.  The <a title="My previous rant on the subject" href="/2006/03/23/is-microsoft-screg-the-web-community-again/">float clearing bug</a> is still a bug in IE7.  It seems so strange to me — they can squash all of the bugs but one?  That&#8217;s like running the 100 yard dash and stopping at yard 98.  Why can&#8217;t they seem to do what <a title="Firefox" href="http://www.getfirefox.com">every</a> <a title="Safari" href="http://www.apple.com/macosx/features/safari/">other</a> <a href="http://www.opera.com/">major</a> browser developer has done?  Is Microsoft so incompetent that they can&#8217;t even toe the line anymore?  So much for being the largest, richest, most powerful corporation in the computer industry.</p>
<p>The impending mass adoption (because of the automatic update) of IE7, with is myriad bug fixes should make every web designer jump for joy, but alas it&#8217;s a mixed bag, because IE7 falls a little short of expectations.  On the fateful day that IE7 rolls out, our sites will have to be instanteously compatible.  Thankfully, for the most part they will.  But be warned if you&#8217;ve ever used float clearing to make a layout work…<br />
At least there will still be ways to target IE7, despite the fixing of the Holly hack, * html hack, etc. by the IE7 dev team.  Not only have new hacks been discovered, which I won&#8217;t comment on, but it&#8217;s easy enough to put all IE7-directed CSS into a single file, and use <a title="Why you should stop using CSS hacks" href="http://www.456bereastreet.com/archive/200510/stop_using_css_hacks_now/">conditional comments</a> to target that file to IE7 alone.</p>
<p>My point, however, is that we shouldn&#8217;t have to.  IE7 should just render the standard which Microsoft, as a member of the W3C, helped create.  Just like everybody else.</p>
<p>Before I convince people that I&#8217;m just a cynical reflexive MS critic, I have to say that they&#8217;ve done quite a bit more than I thought they would.  I mean, they made it to yard 98.  I honestly didn&#8217;t think that the initial release of IE7 would get that far in the race for standards compliance.  Kudos to the IE7 dev team for that.</p>
<p>For an interesting discussion about what people think, look at the conversation on <a href="http://mezzoblue.com/archives/2006/08/23/new_headache/">Dave Shea&#8217;s post</a> in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2006/08/23/ready_or_not_here_ie_comes/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Ruby on Rails has the same appeal as the MacOS</title>
		<link>http://www.foliosus.com/2006/08/05/ruby-on-rails-has-the-same-appeal-as-the-macos/</link>
		<comments>http://www.foliosus.com/2006/08/05/ruby-on-rails-has-the-same-appeal-as-the-macos/#comments</comments>
		<pubDate>Sat, 05 Aug 2006 19:21:10 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Design]]></category>

		<category><![CDATA[Operating systems]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2006/08/05/ruby-on-rails-has-the-same-appeal-as-the-macos/</guid>
		<description><![CDATA[Why do people flip out over RoR?  Primarily, because it&#8217;s fast.  It&#8217;s so fast to develop new applications in RoR.  But why?  What separates RoR from any of the other frameworks out there?  The approach that defines RoR is &#8220;convention over configuration,&#8221; and that&#8217;s where much of the speed comes [...]]]></description>
			<content:encoded><![CDATA[<p>Why do people flip out over <a title="Ruby on Rails, a web application framework" href="http://www.rubyonrails/">RoR</a>?  Primarily, because it&#8217;s fast.  It&#8217;s so fast to develop new applications in RoR.  But why?  What separates RoR from any of the other frameworks out there?  The approach that defines RoR is &#8220;convention over configuration,&#8221; and that&#8217;s where much of the speed comes from.   I had an epiphany this morning: &#8220;convention over configuration&#8221; sounds familliar.  That&#8217;s why I use a Mac.<span id="more-50"></span></p>
<p>My current job is really the first time I&#8217;ve had to use Windows regularly since Windows for Workgroups 3.11.  That&#8217;s way back in 1995 when Windows 95 was still vaporware, much like Vista is now.  Isn&#8217;t it already 3 years overdue?  Anyway, that&#8217;s not relevant to this discussion.</p>
<p>I&#8217;ve had many discussions with people over the years about the old Mac vs. Windows debate.  I&#8217;m no rabid Mac advocate: it&#8217;s not the best solution for all people at all times.  Hardcore Windows users frequently complain that on the Mac there is no Registry, that you can&#8217;t really configure hardware devices etc.  I would argue that on the Mac you don&#8217;t have to.  It&#8217;s convention over configuration.</p>
<p>When I first started using a Mac, I had many of the same misgivings.  Where were the menus with the bazillion options to choose from?  Why couldn&#8217;t I regulate every little detail of the interface?  As I used my Mac more, I realized that I didn&#8217;t have to.  The configuration options I wanted were absent, but the need for them was absent as well.  And I say the MacOS is better off for it, because it lowers the barrier to entry.</p>
<p>I frequently think about interface design in terms of my mom.  I know, a lot of people do this, but it works.  My mom has fought with Windows for years: it doesn&#8217;t do things the way she wants.  What she doesn&#8217;t realize is that she probably can make it work the way she wants it to, if only she knew how.  And therein lies the problem.  It&#8217;s too complicated to get Windows configured just so, and so most users end up just living with it.  Why should a $300 piece of software just be &#8220;lived with?&#8221;</p>
<p>The MacOS takes a different approach.  It comes with a working configuration that is easier to use than what you get with Windows, and with fewer options.  This means that the application and system interface isn&#8217;t cluttered with 1001 widgets all of which let you configure system, and so all you see are the features you want access to.  This seems to be the goal of the UI revisions in &#8220;Office 12,&#8221; but they still don&#8217;t seem to have figured it out.  Too many options mean that most of them just don&#8217;t get used.</p>
<p>If the system has good <em>conventions</em>, or default options, then you don&#8217;t have to spend your time fighting with it, and it generally does 95% of the tasks that 95% of users need done without any hassle.  This is true of the Mac OS, and it&#8217;s true of RoR.  The main difference is that the RoR folks have made their goal explicit.</p>
<p>Accomplishing 95% of what I want to do easily: that&#8217;s design elegance.</p>
<p>&lt;/epiphany&gt;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2006/08/05/ruby-on-rails-has-the-same-appeal-as-the-macos/feed/</wfw:commentRss>
		</item>
		<item>
		<title>HOWTO: Lighttpd with SSL, Rails, PHP and MySQL on OSX 10.4 (Tiger)</title>
		<link>http://www.foliosus.com/2006/04/04/howto-lighttpd-with-ssl-rails-php-and-mysql-on-osx-104-tiger/</link>
		<comments>http://www.foliosus.com/2006/04/04/howto-lighttpd-with-ssl-rails-php-and-mysql-on-osx-104-tiger/#comments</comments>
		<pubDate>Tue, 04 Apr 2006 17:48:44 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Lighttpd]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2006/04/04/howto-lighttpd-with-ssl-rails-php-and-mysql-on-osx-104-tiger/</guid>
		<description><![CDATA[I&#8217;ve run Apache on my Mac for as long as I&#8217;ve had OSX, using either the built-in version or the ServerLogistics package, which they don&#8217;t make anymore.  It always worked great, and when I started learning PHP, it was easy to install and make work.  Getting SSL to work was a little bit [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve run Apache on my Mac for as long as I&#8217;ve had OSX, using either the built-in version or the <a href="http://www.serverlogistics.com/" title="Good installer package for MySQL">ServerLogistics</a> package, which they don&#8217;t make anymore.  It always worked great, and when I started learning PHP, it was <a href="http://www.entropy.ch/software/macosx/php/" title="PHP installer package">easy to install</a> and make work.  Getting SSL to work was a little bit more of a challenge, but once I found <a href="http://forums.serverlogistics.com/viewtopic.php?t=494" title="SSL for Apache 2.0">the right instructions</a> it was a breeze.</p>
<p>But now I need to serve Rails as well.  Getting Apache to do RoR with fcgi can be a hassle, and it&#8217;s apparently slow as well, so I decided to switch to <a href="www.lighttpd.net" title="Lighty home">lighttpd</a>, or lighty as it&#8217;s called.</p>
<p>For development purposes, using the standard <span class="code">script/server</span> is a no-brainer; however I want a &#8220;production&#8221; environment as well.  One that can serve Rails, and legacy PHP, and do SSL for authentication, while talking to MySQL.  I discovered that lighty can do all of these things, but how?<span id="more-34"></span></p>
<p>I looked around, and once you get to the deployment phase of RoR, there isn&#8217;t a lot of good information on the web, especially for smaller set-ups like mine; essentially, I&#8217;m almost the only person who hits my web server, as it houses some personal productivity stuff just for me that most other people don&#8217;t find interesting.  That and my photo collection for friends to browse.</p>
<p>So I looked and looked, and found a lot of disjointed bits and bobs, but I didn&#8217;t find a good how-to for non-unix geeks.  But, given the ease of use of lighty, I&#8217;ve put one together.  Enjoy!</p>
<h3>Requirements</h3>
<ol>
<li>Tiger (OSX 10.4)</li>
<li>XCode 2.0 or newer and developer&#8217;s tools</li>
<li>Patience and a nice snack while waiting for compiling to happen</li>
</ol>
<h3 id="rubyetc">Building Ruby, Gems, RoR, FastCGI, PCRE</h3>
<p>Go to <a href="http://hivelogic.com/articles/2005/12/01/ruby_rails_lighttpd_mysql_tiger">Dan Benjamin&#8217;s excellent instructions</a> to do all of these things, and follow them well.  However, stop when you get to the lighttpd instructions, because we&#8217;re going to make a change.  Do this instead of what he says:</p>
<pre class="code" name="lighttpd">curl -O http://lighttpd.net/download/lighttpd-1.4.11.tar.gz
tar xzvf lighttpd-1.4.11.tar.gz
cd lighttpd-1.4.11
./configure --prefix=/usr/local --with-pcre=/usr/local --with-openssl
make
sudo make install
cd ..</pre>
<p>The only difference is the addition of <span class="code">&#8211;with-openssl</span> to the configuration, which will compile lighttpd with SSL (v2 and v3) support.</p>
<h3 id="mysql">Building MySQL</h3>
<p>You can choose to build MySQL according to <a href="http://hivelogic.com/articles/2005/12/01/ruby_rails_lighttpd_mysql_tiger">the HiveLogic instructions</a>, or you can use the <a href="http://dev.mysql.com/downloads/mysql/5.0.html#Mac_OS_X" title="MySQL 5.0 download page">MySQL 5.0 packages</a> from the dolphin&#8217;s mouth, so to speak, and avoid the compile time.  This works for <a href="http://dev.mysql.com/downloads/mysql/4.1.html#Mac_OS_X" title="MySQL 4.1 download page">version 4.1</a> as well.  I&#8217;ve tried both versions with the setup described here, and both work.</p>
<p>Don&#8217;t forget to install the MySQL native bindings (again, from <a href="http://hivelogic.com/articles/2005/12/01/ruby_rails_lighttpd_mysql_tiger">the HiveLogic instructions</a>) as well.</p>
<h3>But, I&#8217;ve already got this stuff working!</h3>
<p>Chances are, you&#8217;ve already got a full setup that works, because you saw <a href="http://hivelogic.com/articles/2005/12/01/ruby_rails_lighttpd_mysql_tiger">the HiveLogic instructions</a> long before I ever wrote this page.  If that&#8217;s the case, then all you need to do is follow <a href="#lighttpd">my lighttpd compile instructions</a>, which will over-write the pre-existing lighttpd version, with no ill effects.</p>
<h3 id="php">Building PHP</h3>
<p>First, <a href="http://www.php.net/downloads.php" title="PHP download page">download the PHP 5.1.2 full source code</a>, and unpack the tarball by double-clicking it in the finder.  I would recommend moving the unpacked &#8220;php-5.1.2&#8243; folder to the same folder where you downloaded all of the source code from <a href="http://hivelogic.com/articles/2005/12/01/ruby_rails_lighttpd_mysql_tiger">the hivelogic instructions</a>.</p>
<p>Second, open a terminal, and execute the following commands:</p>
<pre class="code">./configure --enable-fastcgi --enable-discard-path --enable-force-redirect --with-zlib --with-xml --with-mysql=/usr/local/mysql --prefix=/usr/local/php5-fcgi --disable-cli --enable-memory-limit --with-layout=GNU --with-regex=php
make
sudo make install</pre>
<p>When this is done, you&#8217;ll have a working cgi-fcgi version of PHP.  We&#8217;ll hook this up to lighttpd in a minute, when we get to the lighty configuration files.</p>
<h3 id="ssl">SSL</h3>
<p>Before we start configuring lighty, we&#8217;ve got to get an SSL certificate.  If you&#8217;re creating your own, you can follow the instructions from the lighty web site:</p>
<pre class="code">openssl req -new -x509 -keyout host.pem -out host.pem -days 365 -nodes</pre>
<p>If you already have a certificate that&#8217;s a .crt and a .key file, you have to make them snuggle up into a single .pem file:</p>
<pre class="code">cat host.key host.crt > host.pem</pre>
<p>Both of these methods result in a single .pem file, usually named &#8220;host.pem&#8221; where &#8220;host&#8221; is the name of the server you&#8217;re using the certificate for.  This file can be stored anywhere you want on your system, since the lighty configuration takes an explicit path to it.</p>
<h3 id="lighttpdconfig">Configuring lighttpd</h3>
<p>Now the more difficult part: we get to configure lighty.  I&#8217;ll present the config files one chunk at a time, explaining what the various commands do.  I&#8217;ve chosen to store mine in <span class="code">/etc/lighttpd/</span> to mimic how Apache stores its files (<span class="code">/etc/httpd/</span>).  Any path will do, just change the references to that directory in the coming intsructions.</p>
<p>First, we&#8217;ll set up 2 top-level files, which are both quite simple.  They set up two nearly identical configurations for the lighty daemon, that run side-by-side.  The first scans port 80, and serves http requests.  Let&#8217;s call this file <span class="code">lighttpd.conf</span>.</p>
<pre class="code">include "lighttpd_shared.conf"

server.port = 80

server.errorlog    = "/etc/lighttpd/lighttpd.error.log"
accesslog.filename = "/etc/lighttpd/lighttpd.access.log"</pre>
<p>The first line causes lighty to parse the main configuration file, which we&#8217;ll go through below.  The next line binds lighty to port 80, the default for http, and then we assign error log files.</p>
<p>We do something very similar for the other top-level file, the one that configures the SSL daemon.  I&#8217;ve called mine <span class="code">lighttpd_ssl.conf</span>.</p>
<pre class="code">include "lighttpd_shared.conf"

server.port = 443

server.errorlog    = "/etc/lighttpd/lighttpd_ssl.error.log"
accesslog.filename = "/etc/lighttpd/lighttpd_ssl.access.log"

ssl.engine         = "enable"
ssl.pemfile        = "/etc/lighttpd/host.pem"</pre>
<p>In this case, we&#8217;ve bound the daemon to port 443, the default for secure connections.  We&#8217;ve specified log files, and then enabled the SSL engine and specified the path to the .pem file.</p>
<p>By the way, the log files must exist before you run the daemon, and have the right permissions.  To do this, simply touch the files, assign them to &#8220;www&#8221; and set the permissions:</p>
<pre class="code">cd /etc/lighttpd
touch lighttpd.error.log
touch lighttpd.access.log
touch lighttpd_ssl.error.log
touch lighttpd_ssl.access.log
sudo chown www *.log
sudo chmod 0666 *log</pre>
<p>Now, on to the meat of the matter.  Both of our top-level files parse the <span class="code">lighttpd_shared.conf</span> file, so that both daemons run in parallel and do the same things.  This means that all pages in our web server can be served with a regular or a secure connection.  Here&#8217;s the meat:</p>
<pre class="code">server.modules = ( "mod_rewrite",
                   "mod_access",
                   "mod_fastcgi",
                   "mod_userdir",
                   "mod_accesslog" )

# Main folder containing web documents
server.document-root = "path/to/main/"

# Allow http://www.domain.com/~username/ style requests
userdir.basepath = "/Users/"
userdir.path = "Sites"
userdir.include-user = ("username") # only allow requests for this user (optional)

# If no file is specified, what to look for?
index-file.names = ( "index.html", "index.htm", "index.php" )

# Required event handler for OS X
server.event-handler = "freebsd-kqueue"

# Run the server under the user-name "www" for security purposes
# To bind to port 80, the server must be called by root user, but we don't want
# the server to have free run of the box, so it runs as "www"
server.username = "www"
server.groupname = "www"

# Set up the appropriate MIME type mappings
mimetype.assign             = (
  ".pdf"          =>      "application/pdf",
  ".sig"          =>      "application/pgp-signature",
  ".spl"          =>      "application/futuresplash",
  ".class"        =>      "application/octet-stream",
  ".ps"           =>      "application/postscript",
  ".torrent"      =>      "application/x-bittorrent",
  ".dvi"          =>      "application/x-dvi",
  ".gz"           =>      "application/x-gzip",
  ".pac"          =>      "application/x-ns-proxy-autoconfig",
  ".swf"          =>      "application/x-shockwave-flash",
  ".tar.gz"       =>      "application/x-tgz",
  ".tgz"          =>      "application/x-tgz",
  ".tar"          =>      "application/x-tar",
  ".zip"          =>      "application/zip",
  ".mp3"          =>      "audio/mpeg",
  ".m3u"          =>      "audio/x-mpegurl",
  ".wma"          =>      "audio/x-ms-wma",
  ".wax"          =>      "audio/x-ms-wax",
  ".ogg"          =>      "application/ogg",
  ".wav"          =>      "audio/x-wav",
  ".gif"          =>      "image/gif",
  ".jpg"          =>      "image/jpeg",
  ".jpeg"         =>      "image/jpeg",
  ".png"          =>      "image/png",
  ".xbm"          =>      "image/x-xbitmap",
  ".xpm"          =>      "image/x-xpixmap",
  ".xwd"          =>      "image/x-xwindowdump",
  ".css"          =>      "text/css",
  ".html"         =>      "text/html",
  ".htm"          =>      "text/html",
  ".js"           =>      "text/javascript",
  ".asc"          =>      "text/plain",
  ".c"            =>      "text/plain",
  ".cpp"          =>      "text/plain",
  ".log"          =>      "text/plain",
  ".conf"         =>      "text/plain",
  ".text"         =>      "text/plain",
  ".txt"          =>      "text/plain",
  ".dtd"          =>      "text/xml",
  ".xml"          =>      "text/xml",
  ".mpeg"         =>      "video/mpeg",
  ".mpg"          =>      "video/mpeg",
  ".mov"          =>      "video/quicktime",
  ".qt"           =>      "video/quicktime",
  ".avi"          =>      "video/x-msvideo",
  ".asf"          =>      "video/x-ms-asf",
  ".asx"          =>      "video/x-ms-asf",
  ".wmv"          =>      "video/x-ms-wmv",
  ".bz2"          =>      "application/x-bzip",
  ".tbz"          =>      "application/x-bzip-compressed-tar",
  ".tar.bz2"      =>      "application/x-bzip-compressed-tar"
 )

# Don't server these files statically, for security
static-file.exclude-extensions = ( ".fcgi", ".php", ".rb", "~", ".inc", ".pl", ".yml" )

# Use mod_access to deny direct access to files ending in ~ or .inc; these are usually
# code or backup files
url.access-deny             = ( "~", ".inc" )

# Disable auto-generated directory listings, for security
dir-listing.activate        = "disable"

# Disable range requests for PDF files
$HTTP["url"] =~ &#8220;\.pdf$&#8221; {
  server.range-requests = &#8220;disable&#8221;
}

# Set up a fastcgi server for PHP
fastcgi.server = ( &#8220;.php&#8221; => ((
                     &#8220;bin-path&#8221; => &#8220;/usr/local/php5-fcgi/bin/php&#8221;, # path to php binary
                     &#8220;socket&#8221; => &#8220;/tmp/php.socket&#8221;,
                 )))

# Now create virtual subdomains for each rails app we want; myrailsapp.domain.com
# Repeat the following block for each rails app, and for each one
# replace &#8220;myrailsapp&#8221; with the name of your application
# This sets up separate fcgi processes for each application

$HTTP["host"] =~ &#8220;^myrailsapp\.&#8221; {
     var.myrailsapp = &#8220;/path/to/rails/app&#8221;
     server.document-root = var. myrailsapp + &#8220;/public&#8221;
     server.error-handler-404 = &#8220;/dispatch.fcgi&#8221;
     fastcgi.server = ( &#8220;.fcgi&#8221; =>
                     ( &#8220;localhost&#8221; =>
                         ( &#8220;bin-environment&#8221; => (&#8221;RAILS_ENV&#8221; => &#8220;production&#8221;),
                           &#8220;bin-path&#8221; => var. myrailsapp + &#8220;/public/dispatch.fcgi&#8221;,
                            &#8220;socket&#8221; => &#8220;/tmp/myrailsapp.fcgi.socket&#8221;
                         )
                      )
                 )
}</pre>
<p>You can tweak the fastcgi performance by using <a href="http://www.lighttpd.net/documentation/fastcgi.html" title="Lighttpd fastcgi configuration options">the lighttpd instructions</a> for directives such as &#8220;min-procs&#8221; and &#8220;max-procs&#8221; but that&#8217;s up to you.</p>
<h3 id="launchd">Lighty at startup</h3>
<p>Wouldn&#8217;t it be nice if lighty launched at startup, and we didn&#8217;t have to worry about it?  How about if it relaunched whenever it crashed?  That would be even better.  Save the following to <span class="code">/Library/LaunchDaemons/net.lighttpd.plist</span> and watch the magic happen, thanks to <a href="http://textsnippets.com/posts/show/124" title="Original launchd instructions">froehle</a>:</p>
<pre class="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
	&lt;key&gt;Label&lt;/key&gt;
	&lt;string&gt;net.lighttpd&lt;/string&gt;
	&lt;key&gt;OnDemand&lt;/key&gt;
	&lt;false /&gt;
	&lt;key&gt;Program&lt;/key&gt;
	&lt;string&gt;/usr/local/sbin/lighttpd&lt;/string&gt;
	&lt;key&gt;ProgramArguments&lt;/key&gt;
	&lt;array&gt;
		&lt;string&gt;/usr/local/sbin/lighttpd&lt;/string&gt;
		&lt;string&gt;-f/path/to/lighttpd.conf&lt;/string&gt;
		&lt;string&gt;-D&lt;/string&gt;
	&lt;/array&gt;
&lt;/dict&gt;
&lt;/plist&gt;</pre>
<p>Oh, wait, before the magic, there&#8217;s one more (<span class="code">/Library/LaunchDaemons/net.lighttpd_ssl.plist</span>):</p>
<pre class="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
	&lt;key&gt;Label&lt;/key&gt;
	&lt;string&gt;net.lighttpd_ssl&lt;/string&gt;
	&lt;key&gt;OnDemand&lt;/key&gt;
	&lt;false /&gt;
	&lt;key&gt;Program&lt;/key&gt;
	&lt;string&gt;/usr/local/sbin/lighttpd&lt;/string&gt;
	&lt;key&gt;ProgramArguments&lt;/key&gt;
	&lt;array&gt;
		&lt;string&gt;/usr/local/sbin/lighttpd&lt;/string&gt;
		&lt;string&gt;-f/path/to/lighttpd_ssl.conf&lt;/string&gt;
		&lt;string&gt;-D&lt;/string&gt;
	&lt;/array&gt;
&lt;/dict&gt;
&lt;/plist&gt;</pre>
<p>Of course, if you&#8217;ve installed the lighttpd binary someplace other than <span class="code">/usr/local/sbin</span> then you should change those 2 lines in each .plist file, and you should specify the path to your .conf files properly.</p>
<h3 id="graceful">Graceful restarts</h3>
<p>Wouldn&#8217;t it be super-nice if we could issue graceful restart commands?  It&#8217;s actually very easy in Tiger (10.4) since launchd monitors apps it has started, and re-opens them if they&#8217;ve quit or crashed.  That means that all we have to do is cause a graceful shutdown, and launchd will take care of the restart for us.  Put the following in <span class="code">/usr/local/sbin/</span> in a file called &#8220;lighttpdctl&#8221; (named after apachectl) with the appropriate path to your config files:</p>
<pre class="code">#!/bin/sh
sudo killall -9 lighttpd</pre>
<p>Make it executable by doing this:</p>
<pre class="code">chmod u+x /usr/local/sbin/lighttpdctl</pre>
<p>Now, from anywhere (since <span class="code">/usr/local/sbin</span> is in our path), you can call <span class="code">lighttpdctl</span> to do a graceful restart.  Note, if you&#8217;re running a port 3000-bound <span class="code">script/server</span> development instance of lighty, it will also quit.</p>
<h3>We&#8217;re done</h3>
<p>Well, almost.  You now have to restart your machine to have launchd do its thing.  If you issue the kill command to lighttpd and the configuration is bad (for whatever reason), and lighty bails on startup, launchd will no longer monitor the process.  This means that when you&#8217;re mucking around, there&#8217;s a lot of <span class="code">sudo lighttpd -f/etc/lighttpd/lighttpd.conf -D</span> from the prompt until you&#8217;ve got it working, followed by a restart.  I&#8217;m pretty sure that there&#8217;s a better way to do the config debugging, but I&#8217;m not 1337 enough with FreeBSD and launchd-speak to do it any better.  If somebody out there knows, please post it in the comments.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2006/04/04/howto-lighttpd-with-ssl-rails-php-and-mysql-on-osx-104-tiger/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Is Microsoft scre***g the web community again?</title>
		<link>http://www.foliosus.com/2006/03/23/is-microsoft-screg-the-web-community-again/</link>
		<comments>http://www.foliosus.com/2006/03/23/is-microsoft-screg-the-web-community-again/#comments</comments>
		<pubDate>Thu, 23 Mar 2006 18:56:29 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Browsers]]></category>

		<category><![CDATA[CSS]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2006/03/23/is-microsoft-screg-the-web-community-again/</guid>
		<description><![CDATA[Many of the leading luminaries of modern standards-based web design have been very excited about the upcoming release of IE7; the promise of not having to support yet another crappy browser has been very tempting.
Let&#8217;s recap what&#8217;s happened, though.

MSFT announces that known hacks won&#8217;t work, and that developers should rely on conditional comments to target [...]]]></description>
			<content:encoded><![CDATA[<p>Many of the leading luminaries of modern standards-based web design have been very excited about the upcoming release of IE7; the promise of not having to support yet another crappy browser has been very tempting.</p>
<p>Let&#8217;s recap what&#8217;s happened, though.<span id="more-33"></span></p>
<ol>
<li>MSFT announces that known hacks won&#8217;t work, and that <a href="http://blogs.msdn.com/ie/archive/2005/10/12/480242.aspx" title="IE Blog">developers should rely on conditional comments to target IE</a>.  At this point, I thought, &#8220;Oh no, here we go.  They&#8217;re going to prevent us from targeting IE7, and IE7 won&#8217;t actually render things properly, so we&#8217;ll be left out to hang.&#8221;</li>
<li>MSFT makes progress, best illustrated by <a href="http://www.molly.com/2006/03/01/microsoft-ie7-progress-sneak-preview-of-mix06-release/" title="Molly on Malarkey and the garden">Molly Holzschlag&#8217;s recap of IE7&#8217;s rendering progress</a> (including <a href="http://www.stuffandnonsense.co.uk/archives/the_ie7_mix_06_release.html" title="Malarkey's progress report on IE7">the rendering of Malarkey&#8217;s site</a>).  I&#8217;ll admit, with the latest release of IE7 beta 2, I thought there was light at the end of the tunnel.  Removing the ability to specifically target IE7 isn&#8217;t a problem <em>as long as it renders according to the standards</em>.</li>
<li>Roger Johansson points out that <a href="http://www.456bereastreet.com/archive/200603/new_clearing_method_needed_for_ie7/" title="456 Berea Street on float clearing"> the latest IE7 beta, the so-called &#8220;layout complete&#8221; version, doesn&#8217;t clear floats properly</a>!  Check the comments if you want to see some vitriol.</li>
<li>Nick Rigby points out that the &#8220;layout complete&#8221; IE7 only fixes 6 of the 7 bugs in his <a href="http://www.nickrigby.com/sandbox/ie7/" title="IE7 bug testing">IE7 test suite</a>.</li>
</ol>
<p>So, essentially, IE7 is still going to be a broken browser, but without hacks we&#8217;ll have no way to target it.  Wasn&#8217;t the whole point to have an IE browser that didn&#8217;t need special support?  Thanks, Microsoft, you&#8217;re doing a bang-up job spending lots of money to make lots of headaches.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2006/03/23/is-microsoft-screg-the-web-community-again/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Lighttpd url rewrites are funny</title>
		<link>http://www.foliosus.com/2006/03/20/lighttpd-url-rewrites-are-funny/</link>
		<comments>http://www.foliosus.com/2006/03/20/lighttpd-url-rewrites-are-funny/#comments</comments>
		<pubDate>Mon, 20 Mar 2006 18:56:58 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Lighttpd]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2006/03/20/lighttpd-url-rewrites-are-funny/</guid>
		<description><![CDATA[Since I&#8217;ve been playing around with RoR I&#8217;ve found the
script/server
trick for development to be fantastically useful.  It&#8217;s quick to use, the server itself is fast, and it&#8217;s everything I could want.  That is, until it&#8217;s time to go in to production mode.  I&#8217;ve been running Apache, using OSX&#8217;s built-in build, but I&#8217;m [...]]]></description>
			<content:encoded><![CDATA[<p>Since I&#8217;ve been playing around with RoR I&#8217;ve found the</p>
<pre class="code">script/server</pre>
<p>trick for development to be fantastically useful.  It&#8217;s quick to use, the server itself is fast, and it&#8217;s everything I could want.  That is, until it&#8217;s time to go in to production mode.  I&#8217;ve been running Apache, using OSX&#8217;s built-in build, but I&#8217;m considering switching my whole setup over to lighty because of the funkiness of Apache and Ruby&#8217;s fcgi.  So I tried it.  Building lighty was really easy.  Getting lighty to then serve my static pages was also very easy.  Then I tried getting it to serve my ruby apps, and that&#8217;s where the problems hit.<span id="more-32"></span></p>
<p>It turns out that my one big config problem was this: &#8220;url.rewrite&#8221; does not work inside a $HTTP["url"] matching block.  So, for example consider this case, where I want to rewrite URL&#8217;s intended for my rails app which has 2 controllers, admin and view:</p>
<pre class="code">$HTTP["url"] =~ &#8220;^/input_path/&#8221; {
  url.rewrite-once (&#8221;/(admin|view)/(.*)&#8221; => &#8220;/some/other/path/$1/$2&#8243;)
}</pre>
<p>If the incoming URL matches &#8220;/input_path/&#8221; then lighty starts processing the code inside the braces, but the url.rewrite-once fails to act.  Instead, the server will invariably look for files inside /input_path/ and serve up a 404.</p>
<p>The proper way to do this sort of work with lighty is to have the regex do all the work:</p>
<pre class="code">url.rewrite-once ("^/input_path/(admin|view)/(.*)" => "some/other/path/$1/$2")</pre>
<p>This isn&#8217;t documented anywhere on the <a href="http://www.lighttpd.net/documentation/" title="LightTPD docs">lighty web site</a>, but there is a <a href="http://article.gmane.org/gmane.comp.web.lighttpd/2992" title="The only documentation?">message on the lighty mailing list</a> that points out the problem.</p>
<p>I have to say, other than this hitch, I&#8217;ve been very impressed with the speed and ease of configuration that lighty offers.  Once I get PHP to work with it, I&#8217;ll be a happy camper.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2006/03/20/lighttpd-url-rewrites-are-funny/feed/</wfw:commentRss>
		</item>
		<item>
		<title>RoR caching and routing</title>
		<link>http://www.foliosus.com/2006/03/15/ror-caching-and-routing/</link>
		<comments>http://www.foliosus.com/2006/03/15/ror-caching-and-routing/#comments</comments>
		<pubDate>Wed, 15 Mar 2006 15:57:18 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2006/03/15/ror-caching-and-routing/</guid>
		<description><![CDATA[I&#8217;ve been trying to learn Ruby on Rails.  So far I&#8217;ve found it to be a very elegant solution to the problem of writing web apps.  Until now I&#8217;ve used Tango or PHP, but I hope that I never have to use them again.
I recently had a rather interesting problem, however.  My [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been trying to learn Ruby on Rails.  So far I&#8217;ve found it to be a very elegant solution to the problem of writing web apps.  Until now I&#8217;ve used Tango or PHP, but I hope that I never have to use them again.</p>
<p>I recently had a rather interesting problem, however.  My first teaching project was a little app to generate a bookmarks page, and it allows me to categorize bookmarks.  Relatively straightforward, right?  Well, I got the code to handle logging in, the categories, subcategories and bookmarks done just fine with no hitches, but then I wanted to test out caching.<span id="more-31"></span></p>
<p>In development.rb I set caching to true, and then enable page caching on my &#8220;view&#8221; controller &emdash; the one that is not behind the login and simply outputs the bookmarks list.  I reload the page, and presto, the index.html page magically appears in my app&#8217;s public folder.  &#8220;Sweet,&#8221; I think.  I then edit one of the pieces of bookmark data, and my sweeper class kicks in, logs that it is expiring the page, and then expires the page.</p>
<pre class="code">
  def expire_view(model)
    model.logger.info("Expiring the cached index")
    expire_page(:controller => "view", :action => "index")
  end
</pre>
<p>Except that the page doesn&#8217;t actually expire.  What the f*@#!?!</p>
<p>After several days of poking around, trying action caching instead, and a few posts to various forums, I figured out what the problem was.  I had reconfigured my routes.rb to essentially point all bogus URL&#8217;s to the view::index action, which was the page being cached.  After I changed routes.rb back, the page started expiring.  I&#8217;m guessing that :caches_page and expire_page() only work when there are single URL&#8217;s pointing to the page being cached.  Has anybody else had a similar experience?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2006/03/15/ror-caching-and-routing/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
