<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Webficient</title>
	
	<link>http://www.webficient.com</link>
	<description>Managed Development Services</description>
	<pubDate>Tue, 30 Dec 2008 17:36:53 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
	<language>en</language>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/Webficient" type="application/rss+xml" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2FWebficient" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FWebficient" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2FWebficient" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.rojo.com/add-subscription?resource=http%3A%2F%2Ffeeds.feedburner.com%2FWebficient" src="http://blog.rojo.com/RojoWideRed.gif">Subscribe with Rojo</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/Webficient" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FWebficient" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FWebficient" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FWebficient" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2FWebficient" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2FWebficient" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://www.yourminis.com/subscribe.aspx?u=http%3A%2F%2Ffeeds.feedburner.com%2FWebficient" src="http://www.yourminis.com/images/addtoyourminisbadge.gif">Subscribe with Yourminis.com</feedburner:feedFlare><feedburner:feedFlare href="http://www.addtoany.com/?linkname=Webficient&amp;linkurl=http%3A%2F%2Ffeeds.feedburner.com%2FWebficient&amp;type=feed" src="http://www.addtoany.com/addfr-b.gif">Add to Any Feed Reader</feedburner:feedFlare><item>
		<title>Easy Rails Patching</title>
		<link>http://feeds.feedburner.com/~r/Webficient/~3/424969681/easy-rails-patching</link>
		<comments>http://www.webficient.com/2008/10/18/easy-rails-patching#comments</comments>
		<pubDate>Sat, 18 Oct 2008 22:58:48 +0000</pubDate>
		<dc:creator>Phil Misiowiec</dc:creator>
		
		<category><![CDATA[Patterns]]></category>

		<category><![CDATA[Solutions]]></category>

		<category><![CDATA[patching]]></category>

		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://www.webficient.com/?p=628</guid>
		<description><![CDATA[If you need to extend Rails for whatever reason, here&#8217;s a quick tip. Simply add your Ruby code to the config/initializers folder. Rails initializers (available since Rails 2 came out) are loaded after the Rails framework and plugins, so any custom script executed at this stage will be last.
Here&#8217;s an example patch which makes &#8220;:disable_with&#8221; [...]]]></description>
			<content:encoded><![CDATA[<p>If you need to extend Rails for whatever reason, here&#8217;s a quick tip. Simply add your Ruby code to the <em>config/initializers</em> folder. Rails initializers (available since Rails 2 came out) are loaded <strong>after</strong> the Rails framework and plugins, so any custom script executed at this stage will be last.</p>
<p>Here&#8217;s an example patch which makes &#8220;:disable_with&#8221; play nicely with the <em>submit_tag</em> when a remote form tag is used*.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">module</span> ActionView
  <span style="color:#9966CC; font-weight:bold;">module</span> Helpers
    <span style="color:#9966CC; font-weight:bold;">module</span> FormTagHelper
&nbsp;
      <span style="color:#9966CC; font-weight:bold;">def</span> submit_tag<span style="color:#006600; font-weight:bold;">&#40;</span>value = <span style="color:#996600;">&quot;Save changes&quot;</span>, options = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        options.<span style="color:#9900CC;">stringify_keys</span>!
&nbsp;
        <span style="color:#9966CC; font-weight:bold;">if</span> disable_with = options.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;disable_with&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
          disable_with = <span style="color:#996600;">&quot;this.value='#{disable_with}'&quot;</span>
          disable_with <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;;#{options.delete('onclick')}&quot;</span> <span style="color:#9966CC; font-weight:bold;">if</span> options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'onclick'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
          disable_with <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;;result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit())&quot;</span>
          disable_with <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;;if (result == false &amp;&amp; this.form.onsubmit &amp;&amp; (this.form.onsubmit+'').indexOf('Ajax.Request') == -1) { this.value = this.getAttribute('originalValue'); this.disabled = false }&quot;</span>
          disable_with <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;;return result&quot;</span>
&nbsp;
          options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;onclick&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006600; font-weight:bold;">&#91;</span>
            <span style="color:#996600;">&quot;this.setAttribute('originalValue', this.value)&quot;</span>,
            <span style="color:#996600;">&quot;this.disabled=true&quot;</span>,
            disable_with
          <span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;;&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
        <span style="color:#9966CC; font-weight:bold;">if</span> confirm = options.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;confirm&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
          options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;onclick&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> ||= <span style="color:#996600;">''</span>
          options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;onclick&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">+</span>= <span style="color:#996600;">&quot;return #{confirm_javascript_function(confirm)};&quot;</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
        tag <span style="color:#ff3333; font-weight:bold;">:input</span>, <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">&quot;type&quot;</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;submit&quot;</span>, <span style="color:#996600;">&quot;name&quot;</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;commit&quot;</span>, <span style="color:#996600;">&quot;value&quot;</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> value <span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">update</span><span style="color:#006600; font-weight:bold;">&#40;</span>options.<span style="color:#9900CC;">stringify_keys</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Be sure you restart your Rails app in order to see your patch take effect.</p>
<p>The above example overrides the existing Rails framework helper. However, you can also use the same technique to extend methods via <a href="http://errtheblog.com/posts/48-aliasmethodbling" target="_blank">alias_method_chain</a>.</p>
<p>*The Rails <em>remote_form_for</em> tag adds a &#8216;return false&#8217; to the form&#8217;s <em>onsubmit</em> event handler. However, the Rails <em>submit_tag</em> helper evaluates whether false was returned via <em>onsubmit</em> and will revert back to the original text (and re-enable the button) if this is the case. This makes sense when you are validating a form&#8230; the validation fails and you need everything reset so that you can correct your error and resubmit the form. However, for remote forms, in which an AJAX call is made to submit the form, we want the RJS response to drive the form&#8217;s (and page&#8217;s) behavior. So the patch evaluates whether an AJAX call is made during <em>onsubmit</em>; if so, it lets the submit button stay disabled. Hacky, I know. But it allows us to do what we need without having to touch the PrototypeHelper module. I tested with normal form_tag&#8217;s that use disable_with and it works in both cases.</p>

<p><a href="http://feeds.feedburner.com/~a/Webficient?a=YSxuqv"><img src="http://feeds.feedburner.com/~a/Webficient?i=YSxuqv" border="0"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Webficient?a=36MGM"><img src="http://feeds.feedburner.com/~f/Webficient?i=36MGM" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Webficient?a=ygcEM"><img src="http://feeds.feedburner.com/~f/Webficient?i=ygcEM" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Webficient?a=TvrEm"><img src="http://feeds.feedburner.com/~f/Webficient?i=TvrEm" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Webficient/~4/424969681" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.webficient.com/2008/10/18/easy-rails-patching/feed</wfw:commentRss>
		<feedburner:origLink>http://www.webficient.com/2008/10/18/easy-rails-patching</feedburner:origLink></item>
		<item>
		<title>Use Phusion Passenger for Development</title>
		<link>http://feeds.feedburner.com/~r/Webficient/~3/422396913/use-phusion-passenger-for-local-development</link>
		<comments>http://www.webficient.com/2008/10/16/use-phusion-passenger-for-local-development#comments</comments>
		<pubDate>Thu, 16 Oct 2008 07:41:12 +0000</pubDate>
		<dc:creator>Phil Misiowiec</dc:creator>
		
		<category><![CDATA[Architecture]]></category>

		<category><![CDATA[mod_rails]]></category>

		<category><![CDATA[passenger]]></category>

		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://www.webficient.com/?p=604</guid>
		<description><![CDATA[Ruby on Rails is single-threaded, which means that an unusually long request such as a file upload or unruly query will block subsequent requests. This is why one of the most popular production architectures for Rails apps involves a cluster of Mongrel servers behind a reverse proxy such as Nginx. Each Mongrel handles a single [...]]]></description>
			<content:encoded><![CDATA[<p>Ruby on Rails is single-threaded, which means that an unusually long request such as a file upload or unruly query will block subsequent requests. This is why one of the most popular production architectures for Rails apps involves a cluster of Mongrel servers behind a reverse proxy such as Nginx. Each Mongrel handles a single request. But in your development environment, you may not want to deal with the additional configuration or resource overhead of setting up something similar.</p>
<p>Usually the above is not even a concern until you really do need your local application to handle more than one request at a time. Let me illustrate with an example. We&#8217;re working on an app in which an HTTP request &#8220;simulator&#8221; (within the same app) is used for testing inbound API requests. The code looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;">payload = <span style="color:#996600;">'stuff'</span>
http = <span style="color:#6666ff; font-weight:bold;">Net::HTTP</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'localhost'</span>,<span style="color:#006666;">3000</span><span style="color:#006600; font-weight:bold;">&#41;</span>
response = http.<span style="color:#9900CC;">post2</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'/receiver'</span>, payload, <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#996600;">'Content-Type'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'application/xml'</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>and should post XML to http://localhost:3000/receiver. However, if you try running it by calling up a page in your browser, your request hangs and eventually times out. This is because the Rails dispatcher (through Mongrel) cannot process a <em>second</em> HTTP request - the XML post - because the first one - the browser request - is still running.</p>
<p>On aside, if you wrap the above into a new thread, you&#8217;ll see it does process immediately, e.g.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#CC00FF; font-weight:bold;">Thread</span>.<span style="color:#9900CC;">new</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
  payload = <span style="color:#996600;">'stuff'</span>
  http = <span style="color:#6666ff; font-weight:bold;">Net::HTTP</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'localhost'</span>,<span style="color:#006666;">3000</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  response = http.<span style="color:#9900CC;">post2</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'/receiver'</span>, payload, <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#996600;">'Content-Type'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'application/xml'</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p>but the last thing you want to do is introduce Ruby threading code into your non-thread safe Rails app (at least prior to <a href="http://weblog.rubyonrails.org/2008/8/16/josh-peek-officially-joins-the-rails-core">version 2.2</a>, which is still in &#8216;edge&#8217; Rails as of this publish date).</p>
<h2>Passenger to the Rescue</h2>
<p>Before we go on, let me point out the lovely <a href="http://www.modrails.com/documentation/Architectural%20overview.html">Passenger architectural overview</a>, which explains how Apache prefork MPM is leveraged to spawn multiple instances of your Rails app. Each instance runs as a separate process but an internal application pool is used to conserve handles. The net result is that now your local Rails app will fork a new process for the next incoming request (while the first one is still running), and any code similar to the first example executes promptly. I want to emphasize that this is similar to having a pack of Mongrels on standby, each one ready to handle a new request. However, the overhead will be substantially less, especially if you use Ruby Enterprise Edition, also from the creators of Passenger.</p>
<h2>Passenger on Mac OS X Leopard</h2>
<p>Running Passenger on the Mac has been covered in detail in &#8220;<a href="http://www.fuzzylizard.com/archives/2008/05/29/947/">Installing Phusion’s Passenger on Leopard (OS X 10.5)</a>,&#8221; a recommended step-by-step walk-through. You won&#8217;t need to compile Apache if you&#8217;re running 10.5 and a recent version of the Passenger gem. Overall, the configuration is quite easy, especially if you&#8217;ve dealt with Apache before.</p>
<p>The only gotcha&#8217;s are remembering to explicitly set the environment to &#8216;development&#8217; in the virtual host settings in your Apache config file:</p>

<div class="wp_syntax"><div class="code"><pre class="text text" style="font-family:monospace;">  DocumentRoot /httpd/spyglass/public
  ServerName spyglass.local
  RailsEnv development</pre></div></div>

<p>&#8230;and adding an entry for your app in /etc/hosts, which we recommend if you work on multiple apps locally:</p>

<div class="wp_syntax"><div class="code"><pre class="text text" style="font-family:monospace;">127.0.0.1 spyglass.local</pre></div></div>

<h2>Easy as Pie*</h2>
<p>If you don&#8217;t want to deal with raw Apache settings or editing your hosts file, be sure to check out the Passenger preferences panel <a href="http://www.fngtps.com/2008/06/putting-the-pane-back-into-deployment">found here</a>. It allows you to drag and drop your existing Rails app into a preferences window and will automatically configure all of the settings for you. The settings are persisted to a file located in <em>/etc/apache2/passenger_pane_vhosts/</em> in case you want to tweak them manually.</p>
<p>*<a href="http://www.phrases.org.uk/meanings/as-easy-as-pie.html">I like pie</a></p>
<h2>Logging Caveat</h2>
<p>While log entries will continue to appear under <em>log/development.log</em>, any Ruby-specific logging is dumped into Apache&#8217;s error log, <em>/var/log/apache2/error.log</em> (also accessible through the Mac Console). So for example, a &#8220;puts @some_variable&#8221; will be piped into Apache&#8217;s log. Therefore, if you are relying on any debug statements in your code, simply use logger.debug(&#8217;string&#8217;) instead, and it will appear in development.log.</p>

<p><a href="http://feeds.feedburner.com/~a/Webficient?a=D5S6SM"><img src="http://feeds.feedburner.com/~a/Webficient?i=D5S6SM" border="0"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Webficient?a=1iL5M"><img src="http://feeds.feedburner.com/~f/Webficient?i=1iL5M" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Webficient?a=L2IVM"><img src="http://feeds.feedburner.com/~f/Webficient?i=L2IVM" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Webficient?a=WNtLm"><img src="http://feeds.feedburner.com/~f/Webficient?i=WNtLm" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Webficient/~4/422396913" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.webficient.com/2008/10/16/use-phusion-passenger-for-local-development/feed</wfw:commentRss>
		<feedburner:origLink>http://www.webficient.com/2008/10/16/use-phusion-passenger-for-local-development</feedburner:origLink></item>
		<item>
		<title>Developer-Specific Environments in Rails</title>
		<link>http://feeds.feedburner.com/~r/Webficient/~3/408475407/developer-specific-environments-in-ruby-on-rails</link>
		<comments>http://www.webficient.com/2008/10/01/developer-specific-environments-in-ruby-on-rails#comments</comments>
		<pubDate>Wed, 01 Oct 2008 18:21:18 +0000</pubDate>
		<dc:creator>Phil Misiowiec</dc:creator>
		
		<category><![CDATA[Solutions]]></category>

		<category><![CDATA[application settings]]></category>

		<category><![CDATA[configuration management]]></category>

		<category><![CDATA[environments]]></category>

		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://www.webficient.com/?p=558</guid>
		<description><![CDATA[When you&#8217;re working on Ruby on Rails applications in a multiple developer team, you&#8217;ll often need to localize certain application settings. You might have your own database credentials, mail server settings, and so on. As a convention, development.rb can be used for settings specific to your development environment. But once this file is added to [...]]]></description>
			<content:encoded><![CDATA[<p>When you&#8217;re working on Ruby on Rails applications in a multiple developer team, you&#8217;ll often need to localize certain application settings. You might have your own database credentials, mail server settings, and so on. As a convention, <em>development.rb</em> can be used for settings specific to your development environment. But once this file is added to the source code repository, every developer on the team shares the settings. Let&#8217;s look at a couple options for handling development environment settings.</p>
<h2>Create a New Environment</h2>
<p>Rails allows you to define new environments without much effort. Simply save a new configuration file to config/environments (example: <em>development-phil.rb</em>) with your custom settings. Then in <em>database.yml</em>, you&#8217;ll need to add a section that matches the name you used (development-phil).</p>
<p>When you start your Mongrel, just pass in your new environment name:</p>

<div class="wp_syntax"><div class="code"><pre class="text text" style="font-family:monospace;">script/server --e=development-phil</pre></div></div>

<p><img class="size-full wp-image-560" title="Screenshot of command line output when starting a Rails application using a custom-defined environment" src="http://www.webficient.com/wp-content/uploads/2008/10/custom-rails-environment.png" alt="Screenshot of command line output when starting a Rails application using a custom-defined environment" width="489" height="112" /></p>
<p>The only <em>caveat</em> with this approach is to be aware of any code in your app that evaluates whether the current environment is &#8216;development.&#8217; Assuming you&#8217;re using a naming convention of <em>development-mycustomname.rb</em> for your environment, simply swap out any instance of this code:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">if</span> RAILS_ENV == <span style="color:#996600;">'development'</span></pre></div></div>

<p>with this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">if</span> RAILS_ENV.<span style="color:#9966CC; font-weight:bold;">include</span>? <span style="color:#996600;">'development'</span></pre></div></div>

<h2>Initializers</h2>
<p>Rails 2 improved configuration management by allowing you to break apart start-up settings into individual files. These settings are stored in <em>config/initializers</em> and are processed <strong>after</strong> <em>environment.rb</em> (and <em>development.rb</em>) are loaded.</p>
<p>If you only have a couple settings you want to localize (e.g. SMTP server), you may not want to spend the effort defining a new development environment as described above. Instead, create a new initializer file (example: <em>mysettings.rb</em>) but <strong>do not</strong> add it to source control. Note: both Subversion and Git allow you to set &#8216;ignore&#8217; properties on specific files in case you are worried about accidentally checking these in (links below).</p>
<p>An initializer can be used to override existing settings in <em>environment.rb</em> and <em>development.rb</em>. The app may have a set of global settings common to all developers but within the initializer you can redefine them as needed.</p>
<p>If you work on multiple projects and are always re-applying the same local settings to your Rails apps, you can externalize your initializer in a common location and then create a <a class="snap_shots" href="http://en.wikipedia.org/wiki/Symbolic_link">symbolic link</a> inside your Rails app. Just save your <em>mysettings.rb</em> outside of your Rails path and from within the console, navigate to your app&#8217;s config/initializers folder and type:</p>

<div class="wp_syntax"><div class="code"><pre class="text text" style="font-family:monospace;">ln -s /apps/mysettings.rb</pre></div></div>

<h2>Additional Resources</h2>
<p>How to ignore specific files during source code repository check-ins:<br />
Git: <a href="http://www.kernel.org/pub/software/scm/git/docs/gitignore.html" target="_blank">.gitignore</a><br />
Subversion: <a href="http://www.mattromaine.com/2007/06/10/svnignore-propset/" target="_blank">propset/propedit</a></p>

<p><a href="http://feeds.feedburner.com/~a/Webficient?a=VMVVec"><img src="http://feeds.feedburner.com/~a/Webficient?i=VMVVec" border="0"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Webficient?a=tfzBM"><img src="http://feeds.feedburner.com/~f/Webficient?i=tfzBM" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Webficient?a=CqgZM"><img src="http://feeds.feedburner.com/~f/Webficient?i=CqgZM" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Webficient?a=DG66m"><img src="http://feeds.feedburner.com/~f/Webficient?i=DG66m" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Webficient/~4/408475407" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.webficient.com/2008/10/01/developer-specific-environments-in-ruby-on-rails/feed</wfw:commentRss>
		<feedburner:origLink>http://www.webficient.com/2008/10/01/developer-specific-environments-in-ruby-on-rails</feedburner:origLink></item>
		<item>
		<title>Testing IE6 on a Mac</title>
		<link>http://feeds.feedburner.com/~r/Webficient/~3/394388044/testing-ie6-on-a-mac</link>
		<comments>http://www.webficient.com/2008/09/16/testing-ie6-on-a-mac#comments</comments>
		<pubDate>Tue, 16 Sep 2008 17:27:35 +0000</pubDate>
		<dc:creator>Phil Misiowiec</dc:creator>
		
		<category><![CDATA[Design]]></category>

		<category><![CDATA[cross-browser]]></category>

		<category><![CDATA[internet explorer]]></category>

		<category><![CDATA[parallels]]></category>

		<category><![CDATA[vmware fusion]]></category>

		<guid isPermaLink="false">http://www.webficient.com/?p=544</guid>
		<description><![CDATA[As of August 2008, Internet Explorer 6 usage still accounts for 30% of the global Web population depending on who you ask. And as all the Web designers in the audience are aware of, making Web sites look good in IE6 can be a bit of a challenge.
If you work on a Mac, then a [...]]]></description>
			<content:encoded><![CDATA[<p>As of August 2008, Internet Explorer 6 usage still accounts for 30% of the global Web population <a href="http://www.w3counter.com/globalstats.php?date=2008-08-31" target="_blank">depending on who you ask</a>. And as all the Web designers in the audience are aware of, making Web sites look good in IE6 can be a bit of a challenge.</p>
<p>If you work on a Mac, then a virtualization solution like <a href="http://www.parallels.com/" target="_blank">Parallels</a> (currently what we&#8217;re using) or <a href="http://www.vmware.com/products/fusion/" target="_blank">VMWare Fusion</a> (also highly recommended by colleagues) is your best bet for running Windows.</p>
<p>The next challenge is being able to run IE6 side by side with IE7 (or the newer IE8 beta). We&#8217;ve explored various tools over the last couple weeks but the one we settled on finally is <a href="http://tredosoft.com/Multiple_IE" target="_blank">TredoSoft&#8217;s IE Installer</a>. Note, however, this installer is optimized for Windows XP, which represents our operating system of choice due to lower memory requirements than Vista (it also has a <a href="http://www.w3counter.com/globalstats.php?date=2008-08-31" target="_blank">74% market share</a> as of August 2008). If you are looking for a solution for running IE6 under Vista, check out <a href="http://tredosoft.com/IE6_For_Vista_Part_1" target="_blank">this article</a>.</p>
<p>TredoSoft installs a fully functional version of IE6. There are some limitations, e.g. not being able to use the IE Developer Toolbar. And others have encountered some issues (read the comments on the bottom of the <a href="http://tredosoft.com/Multiple_IE">TredoSoft IE6 page</a>). However, we&#8217;ve found this solution to be more stable than some of the others we&#8217;ve evaluated.</p>

<p><a href="http://feeds.feedburner.com/~a/Webficient?a=NanB4r"><img src="http://feeds.feedburner.com/~a/Webficient?i=NanB4r" border="0"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Webficient?a=jZ5lL"><img src="http://feeds.feedburner.com/~f/Webficient?i=jZ5lL" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Webficient?a=TqQVL"><img src="http://feeds.feedburner.com/~f/Webficient?i=TqQVL" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Webficient?a=qVhal"><img src="http://feeds.feedburner.com/~f/Webficient?i=qVhal" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Webficient/~4/394388044" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.webficient.com/2008/09/16/testing-ie6-on-a-mac/feed</wfw:commentRss>
		<feedburner:origLink>http://www.webficient.com/2008/09/16/testing-ie6-on-a-mac</feedburner:origLink></item>
		<item>
		<title>Webvanta at Techcrunch50</title>
		<link>http://feeds.feedburner.com/~r/Webficient/~3/386838549/webvanta-techcrunch50</link>
		<comments>http://www.webficient.com/2008/09/08/webvanta-techcrunch50#comments</comments>
		<pubDate>Mon, 08 Sep 2008 16:26:48 +0000</pubDate>
		<dc:creator>Phil Misiowiec</dc:creator>
		
		<category><![CDATA[News]]></category>

		<category><![CDATA[case-studies]]></category>

		<category><![CDATA[clients]]></category>

		<category><![CDATA[ruby on rails]]></category>

		<category><![CDATA[techcrunch]]></category>

		<guid isPermaLink="false">http://www.webficient.com/?p=523</guid>
		<description><![CDATA[
Congrats!
I&#8217;ve had the pleasure of working with Chris and Michael (and their team) on the Webvanta content publishing platform over the last several months. Today, they are unveiling their next generation CMS at the Techcrunch 50.
 Webvanta enables Web and graphics designers to easily create full featured Web sites without having to do any programming. You [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.webvanta.com" target="_blank"><img class="size-full wp-image-526" title="webvanta_logo" src="http://www.webficient.com/wp-content/uploads/2008/09/webvanta_logo.png" alt="Webvanta logo" width="277" height="60" /></a></p>
<h2>Congrats!</h2>
<p>I&#8217;ve had the pleasure of working with Chris and Michael (and their team) on the <a href="http://webvanta.com" target="_blank">Webvanta</a> content publishing platform over the last several months. Today, they are unveiling their next generation CMS at the <a href="http://www.techcrunch50.com/2008/conference/demopit_company.php?demopit=16" target="_blank">Techcrunch 50</a>.</p>
<p> Webvanta enables Web and graphics designers to easily create full featured Web sites without having to do any programming. You can create and categorize all types of content, configure a variety of features, customize the look and feel, and more. To see an example of an actual Webvanta-powered site, check out <a href="http://spartina.com" target="_blank">Spartina</a>.</p>
<p>If you&#8217;re interested in becoming a beta tester, please sign up <a href="http://webvanta.com/" target="_blank">on their home page</a>.</p>
<p>Behind the scenes, Webvanta is a sophisticated <a href="http://www.rubyonrails.org" target="_blank">Ruby on Rails</a> powered application hosted at <a href="http://www.engineyard.com" target="_blank">EngineYard</a>.</p>
<p>The Webvanta project is an example of how my company can help you with your Web development needs. Early stage companies have a common pattern in which there are weeks during which a lot of hours are needed to meet a strategic goal. But in between these &#8220;sprints,&#8221; you may not need or want to incur the same level of costs. With our <strong>on-demand developmen</strong>t services, you only pay for what you need, whether this is one day a month, one day a week, or one full month of development services. <a href="/contact">Contact me</a> if you&#8217;d like to find out more.</p>

<p><a href="http://feeds.feedburner.com/~a/Webficient?a=IvysWa"><img src="http://feeds.feedburner.com/~a/Webficient?i=IvysWa" border="0"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Webficient?a=Va1bL"><img src="http://feeds.feedburner.com/~f/Webficient?i=Va1bL" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Webficient?a=leuAL"><img src="http://feeds.feedburner.com/~f/Webficient?i=leuAL" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Webficient?a=Sk18l"><img src="http://feeds.feedburner.com/~f/Webficient?i=Sk18l" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Webficient/~4/386838549" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.webficient.com/2008/09/08/webvanta-techcrunch50/feed</wfw:commentRss>
		<feedburner:origLink>http://www.webficient.com/2008/09/08/webvanta-techcrunch50</feedburner:origLink></item>
		<item>
		<title>Generate a Google Sitemap in Rails</title>
		<link>http://feeds.feedburner.com/~r/Webficient/~3/384863660/google-sitemap-ruby-on-rails</link>
		<comments>http://www.webficient.com/2008/09/06/google-sitemap-ruby-on-rails#comments</comments>
		<pubDate>Sat, 06 Sep 2008 07:51:48 +0000</pubDate>
		<dc:creator>Phil Misiowiec</dc:creator>
		
		<category><![CDATA[Solutions]]></category>

		<category><![CDATA[capistrano]]></category>

		<category><![CDATA[google sitemap]]></category>

		<category><![CDATA[google webmaster tools]]></category>

		<category><![CDATA[rake]]></category>

		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://www.webficient.com/?p=492</guid>
		<description><![CDATA[A while back, we produced a Capistrano task for automatically crawling your site to pre-cache static content (and find any broken links, exceptions, etc.). We&#8217;ve extended the task to also generate a Google Sitemap for use with the Google Webmaster Tools.
Our needs were simple: create an XML sitemap without having to add any new controllers, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="/2008/06/21/pre-caching-rails-views-during-application-deployment">A while back</a>, we produced a Capistrano task for automatically crawling your site to pre-cache static content (and find any broken links, exceptions, etc.). We&#8217;ve extended the task to also generate a <a href="http://www.google.com/support/webmasters/bin/answer.py?answer=40318&amp;hl=en" target="_blank">Google Sitemap</a> for use with the <a href="https://www.google.com/webmasters/tools/" target="_blank">Google Webmaster Tools</a>.</p>
<p>Our needs were simple: create an XML sitemap without having to add any new controllers, model attributes, and so on. Since we already had a fully functional, deployed Web app, pointing our crawler to it and generating a map containing only valid, internal links made a lot of sense.</p>
<p>Thanks to <a href="http://scoop.cheerfactory.co.uk/2008/02/26/google-sitemap-generator/" target="_blank">Alastair&#8217;s code</a>, we learned about the structure and mechanism for constructing a Google Sitemap, which involves using Rails&#8217; <a href="http://api.rubyonrails.org/classes/Builder/XmlMarkup.html" target="_blank">Builder::XmlMarkup</a> class.</p>
<p>Here&#8217;s the code for the revised crawler. Please refer to the <a href="/2008/06/21/pre-caching-rails-views-during-application-deployment">original article</a> for configuration details.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'mechanize'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Crawler
&nbsp;
  EXTENSIONS_IGNORED = <span style="color:#006600; font-weight:bold;">%</span>w<span style="color:#006600; font-weight:bold;">&#91;</span>.<span style="color:#9900CC;">csv</span> .<span style="color:#9900CC;">doc</span> .<span style="color:#9900CC;">docx</span> .<span style="color:#9900CC;">gif</span> .<span style="color:#9900CC;">jpg</span> .<span style="color:#9900CC;">jpeg</span> .<span style="color:#9900CC;">js</span> .<span style="color:#9900CC;">mp3</span> 
    .<span style="color:#9900CC;">mp4</span> .<span style="color:#9900CC;">mpg</span> .<span style="color:#9900CC;">mpeg</span> .<span style="color:#9900CC;">pdf</span> .<span style="color:#9900CC;">png</span> .<span style="color:#9900CC;">ppt</span> .<span style="color:#9900CC;">rss</span> .<span style="color:#9900CC;">swf</span> .<span style="color:#9900CC;">txt</span> .<span style="color:#9900CC;">xls</span> .<span style="color:#9900CC;">xlsx</span> .<span style="color:#9900CC;">xml</span><span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
  PROTOCOLS_IGNORED = <span style="color:#006600; font-weight:bold;">%</span>w<span style="color:#006600; font-weight:bold;">&#91;</span>feed ftp itms javascript mailto<span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>starting_url, credentials = <span style="color:#0000FF; font-weight:bold;">nil</span>, quiet_mode = <span style="color:#0000FF; font-weight:bold;">false</span>, sitemap = <span style="color:#0000FF; font-weight:bold;">false</span>, debug = <span style="color:#0000FF; font-weight:bold;">false</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@bad_pages</span> = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>  
    <span style="color:#0066ff; font-weight:bold;">@agent</span> = <span style="color:#6666ff; font-weight:bold;">WWW::Mechanize</span>.<span style="color:#9900CC;">new</span>
    <span style="color:#0066ff; font-weight:bold;">@sitemap</span> = sitemap
    <span style="color:#0066ff; font-weight:bold;">@debug</span> = debug
    <span style="color:#0066ff; font-weight:bold;">@visited_pages</span> = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">if</span> credentials
      creds = credentials.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">':'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0066ff; font-weight:bold;">@agent</span>.<span style="color:#9900CC;">basic_auth</span><span style="color:#006600; font-weight:bold;">&#40;</span>creds<span style="color:#006600; font-weight:bold;">&#91;</span>0<span style="color:#006600; font-weight:bold;">&#93;</span>, creds<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#0066ff; font-weight:bold;">@quiet_mode</span> = quiet_mode
    <span style="color:#0066ff; font-weight:bold;">@starting_url</span> = starting_url
    <span style="color:#0066ff; font-weight:bold;">@starting_url_domain</span> = starting_url<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#91;</span>a<span style="color:#006600; font-weight:bold;">-</span>z0<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">9</span><span style="color:#006600; font-weight:bold;">-</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span>\.<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#91;</span>a<span style="color:#006600; font-weight:bold;">-</span>z.<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">/</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;domain: #{@starting_url_domain}&quot;</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@debug</span>
    extract_and_call_urls<span style="color:#006600; font-weight:bold;">&#40;</span>starting_url<span style="color:#006600; font-weight:bold;">&#41;</span>
    generate_sitemap <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@sitemap</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> extract_and_call_urls<span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>            
    <span style="color:#008000; font-style:italic;">#get page</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{@visited_pages.size+1} #{url}&quot;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> <span style="color:#0066ff; font-weight:bold;">@quiet_mode</span>
    <span style="color:#9966CC; font-weight:bold;">begin</span>
      page = <span style="color:#0066ff; font-weight:bold;">@agent</span>.<span style="color:#9900CC;">get</span><span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> exception
      <span style="color:#0066ff; font-weight:bold;">@bad_pages</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> url
      <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;error: #{url}, #{exception.message}&quot;</span>
      <span style="color:#0000FF; font-weight:bold;">return</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#008000; font-style:italic;">#for any content types we may have missed above, exit if content type is not html</span>
    <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#9966CC; font-weight:bold;">if</span> page.<span style="color:#9900CC;">instance_of</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#6666ff; font-weight:bold;">WWW::Mechanize::File</span><span style="color:#006600; font-weight:bold;">&#41;</span> || page.<span style="color:#9900CC;">content_type</span>.<span style="color:#9900CC;">index</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'text/html'</span><span style="color:#006600; font-weight:bold;">&#41;</span> == <span style="color:#0000FF; font-weight:bold;">nil</span>
&nbsp;
    <span style="color:#008000; font-style:italic;">#add to array</span>
    <span style="color:#0066ff; font-weight:bold;">@visited_pages</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> url
&nbsp;
    <span style="color:#008000; font-style:italic;">#get links found on page</span>
    links = page.<span style="color:#9900CC;">links</span>
&nbsp;
    <span style="color:#008000; font-style:italic;">#for each link, call the url if not in history</span>
    links.<span style="color:#9900CC;">each</span><span style="color:#006600; font-weight:bold;">&#123;</span> |link| extract_and_call_urls<span style="color:#006600; font-weight:bold;">&#40;</span>link.<span style="color:#9900CC;">href</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> 
      ignore_url?<span style="color:#006600; font-weight:bold;">&#40;</span>link.<span style="color:#9900CC;">href</span><span style="color:#006600; font-weight:bold;">&#41;</span> || <span style="color:#0066ff; font-weight:bold;">@visited_pages</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>link.<span style="color:#9900CC;">href</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  private
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> ignore_url?<span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">begin</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> ignored = <span style="color:#0000FF; font-weight:bold;">true</span> <span style="color:#9966CC; font-weight:bold;">if</span> url.<span style="color:#0000FF; font-weight:bold;">nil</span>? ||
                       <span style="color:#006600; font-weight:bold;">&#40;</span>url.<span style="color:#9966CC; font-weight:bold;">include</span>? <span style="color:#996600;">'http'</span> <span style="color:#9966CC; font-weight:bold;">and</span> !url.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;webficient.com&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> ||
                       <span style="color:#0066ff; font-weight:bold;">@bad_pages</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span> ||
                       PROTOCOLS_IGNORED.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#123;</span> |prt| url =~ <span style="color:#006600; font-weight:bold;">/</span><span style="color:#008000; font-style:italic;">#{prt}:/ } != nil ||</span>
                       EXTENSIONS_IGNORED.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#123;</span> |ext| url =~ <span style="color:#006600; font-weight:bold;">/</span><span style="color:#008000; font-style:italic;">#{ext}$/ } != nil</span>
    <span style="color:#9966CC; font-weight:bold;">ensure</span>
      <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;ignored: #{url}&quot;</span> <span style="color:#9966CC; font-weight:bold;">if</span> ignored <span style="color:#9966CC; font-weight:bold;">and</span> <span style="color:#0066ff; font-weight:bold;">@debug</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> generate_sitemap
  	xml_str = <span style="color:#996600;">&quot;&quot;</span>
  	xml = <span style="color:#6666ff; font-weight:bold;">Builder::XmlMarkup</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:target</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> xml_str, <span style="color:#ff3333; font-weight:bold;">:indent</span><span style="color:#006600; font-weight:bold;">=&gt;</span><span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
  	xml.<span style="color:#9900CC;">instruct</span>!
  	xml.<span style="color:#9900CC;">urlset</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:xmlns</span><span style="color:#006600; font-weight:bold;">=&gt;</span><span style="color:#996600;">'http://www.sitemaps.org/schemas/sitemap/0.9'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
  		<span style="color:#0066ff; font-weight:bold;">@visited_pages</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> |url|
  		  <span style="color:#9966CC; font-weight:bold;">unless</span> <span style="color:#0066ff; font-weight:bold;">@starting_url</span> == url
    	    xml.<span style="color:#9900CC;">url</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
      	    xml.<span style="color:#9900CC;">loc</span><span style="color:#006600; font-weight:bold;">&#40;</span>@starting_url <span style="color:#006600; font-weight:bold;">+</span> url<span style="color:#006600; font-weight:bold;">&#41;</span>
      			xml.<span style="color:#9900CC;">lastmod</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>.<span style="color:#9900CC;">utc</span>.<span style="color:#9900CC;">strftime</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;%Y-%m-%dT%H:%M:%S+00:00&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      			xml.<span style="color:#9900CC;">changefreq</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'weekly'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
   			  <span style="color:#006600; font-weight:bold;">&#125;</span>
   			<span style="color:#9966CC; font-weight:bold;">end</span>
  		<span style="color:#9966CC; font-weight:bold;">end</span>
  	<span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
  	save_file<span style="color:#006600; font-weight:bold;">&#40;</span>xml_str<span style="color:#006600; font-weight:bold;">&#41;</span>
  	update_google
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
	<span style="color:#008000; font-style:italic;"># Saves the xml file to disc. This could also be used to ping the webmaster tools</span>
	<span style="color:#9966CC; font-weight:bold;">def</span> save_file<span style="color:#006600; font-weight:bold;">&#40;</span>xml<span style="color:#006600; font-weight:bold;">&#41;</span>
		<span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>RAILS_ROOT <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">'/public/sitemap.xml'</span>, <span style="color:#996600;">&quot;w+&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> |f|
			f.<span style="color:#9900CC;">write</span><span style="color:#006600; font-weight:bold;">&#40;</span>xml<span style="color:#006600; font-weight:bold;">&#41;</span>	
		<span style="color:#9966CC; font-weight:bold;">end</span>		
	<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
	<span style="color:#008000; font-style:italic;"># Notify google of the new sitemap</span>
	<span style="color:#9966CC; font-weight:bold;">def</span> update_google
	    sitemap_uri = <span style="color:#0066ff; font-weight:bold;">@starting_url</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">'/sitemap.xml'</span>
	    escaped_sitemap_uri = <span style="color:#CC00FF; font-weight:bold;">URI</span>.<span style="color:#9900CC;">escape</span><span style="color:#006600; font-weight:bold;">&#40;</span>sitemap_uri<span style="color:#006600; font-weight:bold;">&#41;</span>
	    <span style="color:#6666ff; font-weight:bold;">Net::HTTP</span>.<span style="color:#9900CC;">get</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'www.google.com'</span>,
	                  <span style="color:#996600;">'/webmasters/sitemaps/ping?sitemap='</span> <span style="color:#006600; font-weight:bold;">+</span>
	                  escaped_sitemap_uri<span style="color:#006600; font-weight:bold;">&#41;</span>
	<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<h2>What&#8217;s Going On</h2>
<p>As the crawler hits each page, it persists a valid URL into an array:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#0066ff; font-weight:bold;">@visited_pages</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> url</pre></div></div>

<p>Then, we iterate through the array and build the XML:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;">xml.<span style="color:#9900CC;">url</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
  xml.<span style="color:#9900CC;">loc</span><span style="color:#006600; font-weight:bold;">&#40;</span>@starting_url <span style="color:#006600; font-weight:bold;">+</span> url<span style="color:#006600; font-weight:bold;">&#41;</span>
  xml.<span style="color:#9900CC;">lastmod</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>.<span style="color:#9900CC;">utc</span>.<span style="color:#9900CC;">strftime</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;%Y-%m-%dT%H:%M:%S+00:00&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  xml.<span style="color:#9900CC;">changefreq</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'weekly'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p>Note that we are always setting the modification date of every page to the current time and anticipated frequency of page updates to &#8216;weekly.&#8217; Feel free to vary or extrapolate into additional config settings.</p>
<h2>Connecting it Together</h2>
<p>In this iteration, we packaged this up as a Rake task by saving the following task as lib/tasks/admin.rake (inside our Rails application directory). If you want to run this from Capistrano instead, just add the task to config/deploy.rb.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'lib/crawler'</span>
&nbsp;
namespace <span style="color:#ff3333; font-weight:bold;">:admin</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
  desc <span style="color:#996600;">&quot;Crawl pages using the Mechanize gem. Set URL variable as a starting point. Set CREDS as username:password if you are hitting a password protected site. To generate a Google Sitemap in /public/sitemap.xml, set SITEMAP=true. To suppress output and only show errors, set QUIET=true. To show more details during output, set DEBUG=true.&quot;</span>
  task <span style="color:#ff3333; font-weight:bold;">:crawl_pages</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    start_url = ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;URL&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> || <span style="color:#996600;">&quot;http://localhost:3000&quot;</span>
    sitemap = Crawler.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>start_url, <span style="color:#006600; font-weight:bold;">&#40;</span>ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;CREDS&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">if</span> ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;CREDS&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>, ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;QUIET&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> || <span style="color:#0000FF; font-weight:bold;">false</span>, ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;SITEMAP&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> || <span style="color:#0000FF; font-weight:bold;">false</span>, ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;DEBUG&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> || <span style="color:#0000FF; font-weight:bold;">false</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<h2>Sitemap-ilicious!</h2>
<p>Run your new rake task from the command line interface:</p>

<div class="wp_syntax"><div class="code"><pre class="text text" style="font-family:monospace;">rake admin:crawl_pages URL=http://www.webficient.com SITEMAP=true</pre></div></div>

<p>Google is automatically pinged as the final step. A copy of the sitemap is also saved to public/sitemap.xml. You can point Google&#8217;s Webmaster Tools to this URL (http://mywebsite.com/sitemap.xml) to track Google crawler statistics.</p>

<p><a href="http://feeds.feedburner.com/~a/Webficient?a=7BhXGc"><img src="http://feeds.feedburner.com/~a/Webficient?i=7BhXGc" border="0"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Webficient?a=exveL"><img src="http://feeds.feedburner.com/~f/Webficient?i=exveL" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Webficient?a=GrZOL"><img src="http://feeds.feedburner.com/~f/Webficient?i=GrZOL" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Webficient?a=XwgJl"><img src="http://feeds.feedburner.com/~f/Webficient?i=XwgJl" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Webficient/~4/384863660" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.webficient.com/2008/09/06/google-sitemap-ruby-on-rails/feed</wfw:commentRss>
		<feedburner:origLink>http://www.webficient.com/2008/09/06/google-sitemap-ruby-on-rails</feedburner:origLink></item>
		<item>
		<title>Why Amazon is Good for Craigslist</title>
		<link>http://feeds.feedburner.com/~r/Webficient/~3/371066454/amazon-and-craigslist-symbiosis</link>
		<comments>http://www.webficient.com/2008/08/21/amazon-and-craigslist-symbiosis#comments</comments>
		<pubDate>Thu, 21 Aug 2008 16:29:39 +0000</pubDate>
		<dc:creator>Phil Misiowiec</dc:creator>
		
		<category><![CDATA[Commentary]]></category>

		<category><![CDATA[amazon]]></category>

		<category><![CDATA[amazon mechanical turk]]></category>

		<category><![CDATA[craigslist]]></category>

		<category><![CDATA[spam]]></category>

		<guid isPermaLink="false">http://www.webficient.com/?p=315</guid>
		<description><![CDATA[I&#8217;ve always been a fan of craigslist. I&#8217;ve sold tons of furniture, two cars, and even a reptile. I admire Jim Buckmaster, who, incidentally, brought me up to the Bay Area when he hired me as a developer at another startup back in the day.
I recently came across a post which claims Craigslist&#8217;s fight against [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve always been a fan of craigslist. I&#8217;ve sold tons of furniture, two cars, and even a reptile. I admire <a class="snap_shots" href="http://en.wikipedia.org/wiki/Jim_Buckmaster" target="_blank">Jim Buckmaster</a>, who, incidentally, brought me up to the Bay Area when he hired me as a developer at <a href="http://www.redherring.com/Home/2275" target="_blank">another startup</a> back in the day.</p>
<p>I recently came across a <a href="http://www.techdirt.com/articles/20080523/0327151211.shtml" target="_blank">post which claims</a> Craigslist&#8217;s fight against spam is becoming more challenging. New counter-spam techniques are tested, only to be defeated by spammers armed with increasingly sophisticated software and schemes.</p>
<p>Historically, the Craigslist community has been vigilant in keeping listings fair and honest by being able to &#8216;flag&#8217; any post. Everyone can become a virtual watchdog and keep the muck out. But when the &#8216;community&#8217; is infiltrated by bots, the game changes a bit. At some tipping point, it becomes extremely difficult for the good guys to outpace the bad ones. </p>
<p>There are two ways to solve this problem. One involves advanced heuristic algorithms that require a lot of hardware, code, and money - very doable given their <a href="http://news.cnet.com/8301-10784_3-9911097-7.html?hhTest=1" target="_blank">estimated revenue</a>. But the other is likely cheaper and more plausible to work as the cat and mouse games continue to evolve: fight people with people.</p>
<h2>Enter the Turk</h2>
<p><a href="http://www.techcrunch.com/2005/11/04/amazon-finally-shows-itself-as-the-matrix/" target="_blank">A while back</a>, Amazon rolled out a unique Web service known as <a class="snap_shots" href="http://en.wikipedia.org/wiki/Amazon_Mechanical_Turk" target="_blank">Amazon Mechanical Turk</a> (AMT). The idea was simple: take tasks that may be challenging or costly for computers to perform and farm it out to a virtual workforce of people who, in exchange for doing the task, get monetary compensation. </p>
<p>The Mechanical Turk is a great fit for craigslist because in most cases, a human is better at determining whether a listing is spammy. A machine will have the advantage when looking for patterns across listings (e.g. duplicated mass listings with slight variations). But give a person a single page and within seconds a determination will be made.</p>
<p>Any developer can integrate an app with the Mechanical Turk through its API, with clients available for Java, Perl, Ruby, and more. A hypothetical craigslist integration could look like the following illustration:</p>
<p> </p>
<p><a href="http://www.webficient.com/wp-content/uploads/2008/08/craigslist-amazon-mechanical-turk.png"><img class="alignnone size-full wp-image-361" title="craigslist-amazon-mechanical-turk" src="http://www.webficient.com/wp-content/uploads/2008/08/craigslist-amazon-mechanical-turk.png" alt="" width="500" height="326" /></a></p>
<h2>Those Listings Add Up Quick</h2>
<p>Even with a conservative cost of one cent per completed task, given the number of monthly listings (Googling it shows an estimated 30 million), craigslist&#8217;s bill from Amazon would be significant. Perhaps they could limit the use AMT to listings considered suspect based on their existing anti-spam algorithms. But I think Amazon should throw it in for free - well, there&#8217;s a catch of course.</p>
<h2>How Are You Gonna Pay For This</h2>
<p>One of the biggest things missing from craigslist is a payment platform. Low ticket items are usually paid with cash. But as we start getting up there, there&#8217;s definitely an area where cash and checks become a bit of a drag. And as we get further into <a class="snap_shots" href="http://en.wikipedia.org/wiki/Mobile_commerce" target="_blank">m-commerce</a>, being able to complete a transaction with your phone at a local garage sale visit will become the norm. There&#8217;s nothing preventing craigslist users from using PayPal or Google Checkout today but having an integrated option could make things easier.</p>
<p>A payment system can also be used to establish trust and reputation. Sure, there will always be some level of fraud, but it will be the lesser of two evils compared to today&#8217;s world of &#8216;buyers&#8217; offering to pay with wire transfers. And I don&#8217;t believe a payment system will detract from the emphasis on &#8216;local&#8217; community. People will continue to buy from others in their zip code; it&#8217;ll simply be a lot easier to pay for stuff.</p>
<p>Amazon&#8217;s Payment Systems is a relatively new entrant to the space. They are marketing it to developers to help proliferate it. Obviously an endorsement by someone like craigslist would be huge. Since Amazon gets a cut from each transaction, a nice revenue stream would arise if all of a sudden, 1 out of every 10 listings resulted in a payment transaction.  For this reason, Amazon could afford to give away Mechanical Turk for free and even fund the cost of each task payout.</p>
<p>What do you think? Would Amazon&#8217;s services make craigslist a better place?</p>

<p><a href="http://feeds.feedburner.com/~a/Webficient?a=yzwW2i"><img src="http://feeds.feedburner.com/~a/Webficient?i=yzwW2i" border="0"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Webficient?a=DRUEO"><img src="http://feeds.feedburner.com/~f/Webficient?i=DRUEO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Webficient?a=0xarO"><img src="http://feeds.feedburner.com/~f/Webficient?i=0xarO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Webficient?a=EAnSo"><img src="http://feeds.feedburner.com/~f/Webficient?i=EAnSo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Webficient/~4/371066454" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.webficient.com/2008/08/21/amazon-and-craigslist-symbiosis/feed</wfw:commentRss>
		<feedburner:origLink>http://www.webficient.com/2008/08/21/amazon-and-craigslist-symbiosis</feedburner:origLink></item>
		<item>
		<title>SPF Records and Spam</title>
		<link>http://feeds.feedburner.com/~r/Webficient/~3/369650041/spf-records-spam-false-positives</link>
		<comments>http://www.webficient.com/2008/08/19/spf-records-spam-false-positives#comments</comments>
		<pubDate>Wed, 20 Aug 2008 04:38:05 +0000</pubDate>
		<dc:creator>Phil Misiowiec</dc:creator>
		
		<category><![CDATA[Business]]></category>

		<category><![CDATA[Solutions]]></category>

		<category><![CDATA[dns]]></category>

		<category><![CDATA[google apps]]></category>

		<category><![CDATA[sender policy framework]]></category>

		<category><![CDATA[spam]]></category>

		<guid isPermaLink="false">http://www.webficient.com/?p=330</guid>
		<description><![CDATA[Have you ever sent a legitimate email from a corporate email address only to find out from the recipient that it was falsely flagged as spam? You&#8217;re at the mercy of someone else&#8217;s spam filter, but here&#8217;s one solution that can help reduce false positives.
SPF Defined
The Sender Policy Framework (SPF) was created to reduce spam [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever sent a legitimate email from a corporate email address only to find out from the recipient that it was falsely flagged as spam? You&#8217;re at the mercy of someone else&#8217;s spam filter, but here&#8217;s one solution that can help reduce false positives.</p>
<h2>SPF Defined</h2>
<p>The <a class="snap_shots" href="http://en.wikipedia.org/wiki/Sender_Policy_Framework" target="_blank">Sender Policy Framework</a> (SPF) was created to reduce spam by detecting impersonation of domain names. Since anyone can forge a &#8220;from&#8221; email address in a message header, SPF can be used by email servers to verify that the message originates from the domain it claims to be from, or that it was sent from a trusted host.</p>
<h2>Creating a DNS TXT Record</h2>
<p>SPF data is stored in a DNS TXT record, which is supported by <a href="http://www.kitterman.com/spf/txt.html" target="_blank">most domain registrars</a>. Simply go to the DNS management console used by your registrar or Web host and look for a &#8220;TXT&#8221; record option. </p>
<p>Let&#8217;s say you&#8217;re using a third-party service such as Google Apps to handle your corporate email. The TXT record would be</p>

<div class="wp_syntax"><div class="code"><pre class="text text" style="font-family:monospace;">v=spf1 mx include:v=spf1 include:aspmx.googlemail.com ~all</pre></div></div>

<p>But what about if you&#8217;re also sending emails directly from an application server? You&#8217;d want to include the IP address of the machine hosting the SMTP server:</p>

<div class="wp_syntax"><div class="code"><pre class="text text" style="font-family:monospace;">v=spf1 a mx ip4:67.207.129.94 include:v=spf1 include:aspmx.googlemail.com ~all</pre></div></div>

<p>To view a detailed explanation about the above parameters and an easy-to-use wizard for generating SPF-compliant DNS entries, check out the <a href="http://www.openspf.org/" target="_blank">SPF Setup Wizard</a>.</p>
<h2>Before and After</h2>
<p>If you examine your email headers, you can see the impact of creating an SFP record. Here&#8217;s an email sent to a GMail account <em>before</em> the record was added.</p>

<div class="wp_syntax"><div class="code"><pre class="text text" style="font-family:monospace;">Received-Spf: neutral (google.com: 67.207.129.94 is neither permitted nor denied by best guess record for domain of info@webficient.com) client-ip=67.207.129.94;
Authentication-Results: mx.google.com; spf=neutral (google.com: 67.207.129.94 is neither permitted nor denied by best guess record for domain of info@webficient.com) smtp.mail=info@webficient.com</pre></div></div>

<p>Now compare the headers with the SPF record in place:</p>

<div class="wp_syntax"><div class="code"><pre class="text text" style="font-family:monospace;">Received-Spf: pass (google.com: domain of info@webficient.com designates 67.207.129.94 as permitted sender) client-ip=67.207.129.94;
Authentication-Results: mx.google.com; spf=pass (google.com: domain of info@webficient.com designates 67.207.129.94 as permitted sender) smtp.mail=info@webficient.com</pre></div></div>


<p><a href="http://feeds.feedburner.com/~a/Webficient?a=TL8ue5"><img src="http://feeds.feedburner.com/~a/Webficient?i=TL8ue5" border="0"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Webficient?a=2i4mO"><img src="http://feeds.feedburner.com/~f/Webficient?i=2i4mO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Webficient?a=XWNqO"><img src="http://feeds.feedburner.com/~f/Webficient?i=XWNqO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Webficient?a=44uXo"><img src="http://feeds.feedburner.com/~f/Webficient?i=44uXo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Webficient/~4/369650041" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.webficient.com/2008/08/19/spf-records-spam-false-positives/feed</wfw:commentRss>
		<feedburner:origLink>http://www.webficient.com/2008/08/19/spf-records-spam-false-positives</feedburner:origLink></item>
		<item>
		<title>Write for Us, Get Exposure</title>
		<link>http://feeds.feedburner.com/~r/Webficient/~3/368568380/get-exposure</link>
		<comments>http://www.webficient.com/2008/08/18/get-exposure#comments</comments>
		<pubDate>Tue, 19 Aug 2008 00:45:16 +0000</pubDate>
		<dc:creator>Phil Misiowiec</dc:creator>
		
		<category><![CDATA[News]]></category>

		<category><![CDATA[guest contributors]]></category>

		<guid isPermaLink="false">http://www.webficient.com/?p=323</guid>
		<description><![CDATA[We&#8217;re looking for guest contributors to help cover topics such as Web design, system architecture, and Ruby on Rails programming. There&#8217;s no pay involved but we&#8217;d love to feature your profile and send you some traffic. If interested, please send a sample of your writing (or link to an existing blog) to blog@webficient.com.
]]></description>
			<content:encoded><![CDATA[<p>We&#8217;re looking for guest contributors to help cover topics such as Web design, system architecture, and Ruby on Rails programming. There&#8217;s no pay involved but we&#8217;d love to feature your profile and send you some traffic. If interested, please send a sample of your writing (or link to an existing blog) to <a href="mailto:blog@webficient.com">blog@webficient.com</a>.</p>

<p><a href="http://feeds.feedburner.com/~a/Webficient?a=gt3mWc"><img src="http://feeds.feedburner.com/~a/Webficient?i=gt3mWc" border="0"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Webficient?a=GWB4vK"><img src="http://feeds.feedburner.com/~f/Webficient?i=GWB4vK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Webficient?a=uiJ5rK"><img src="http://feeds.feedburner.com/~f/Webficient?i=uiJ5rK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Webficient?a=xF46Vk"><img src="http://feeds.feedburner.com/~f/Webficient?i=xF46Vk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Webficient/~4/368568380" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.webficient.com/2008/08/18/get-exposure/feed</wfw:commentRss>
		<feedburner:origLink>http://www.webficient.com/2008/08/18/get-exposure</feedburner:origLink></item>
		<item>
		<title>Valid XHTML for YouTube Videos</title>
		<link>http://feeds.feedburner.com/~r/Webficient/~3/359850566/valid-xhtml-for-youtube-videos</link>
		<comments>http://www.webficient.com/2008/08/08/valid-xhtml-for-youtube-videos#comments</comments>
		<pubDate>Fri, 08 Aug 2008 23:12:53 +0000</pubDate>
		<dc:creator>Phil Misiowiec</dc:creator>
		
		<category><![CDATA[Design]]></category>

		<category><![CDATA[markup]]></category>

		<category><![CDATA[validation]]></category>

		<category><![CDATA[xhtml]]></category>

		<guid isPermaLink="false">http://www.webficient.com/?p=290</guid>
		<description><![CDATA[If you ever embed YouTube videos in a Web page, you may not realize it but the embed code they provide is not valid XHTML markup. &#8220;Ah come on, why create valid markup in the first place?&#8221; you may be thinking. Let&#8217;s start with the basics&#8230;
Why Validate HTML?
For an introduction to validating your Web site, [...]]]></description>
			<content:encoded><![CDATA[<p>If you ever embed YouTube videos in a Web page, you may not realize it but the embed code they provide is not valid XHTML markup. &#8220;Ah come on, why create valid markup in the first place?&#8221; you may be thinking. Let&#8217;s start with the basics&#8230;</p>
<h2>Why Validate HTML?</h2>
<p>For an introduction to validating your Web site, see the following resources:</p>
<ul>
<li>W3C&#8217;s &#8220;<a href="http://validator.w3.org/docs/why.html" target="_blank">Why Validate?</a>&#8221; covers the practical arguments.</li>
<li>&#8220;<a href="http://www.rsspieces.com/html-validation-the-hidden-key-to-seo" target="_blank">HTML Validation: the hidden key to SEO</a>&#8221; offers economic motives.</li>
</ul>
<p>Convinced? Read on&#8230;</p>
<h2>How to Validate Your Web Site</h2>
<p>There are several ways to validate your Web site. Easiest: enter your Web site address into <a href="http://validator.w3.org/" target="_blank">W3C validator service</a> and see the results immediately.</p>
<p>Or if you&#8217;re a Web developer and want to do this on a regular basis, get the <a href="https://addons.mozilla.org/en-US/firefox/addon/60" target="_blank">&#8220;Web Developer&#8221; add-on</a> for Firefox, and you&#8217;ll find a &#8220;Validate Local HTML&#8221; option in the Tools section.</p>
<p>And for the Ruby on Rails programmers in the house, you can automate the validation process as part of  the test cycle using the nifty <a href="http://code.google.com/p/htmltest/" target="_blank">htmltest plug-in</a>.</p>
<h2>Fixing the Video Embed Code</h2>
<p>Back to our original problem: YouTube video code wraps an <em>EMBED</em> tag inside an <em>OBJECT</em> tag but the former is not part of the XHTML standard. Hence, a Web page run through the validation service will fail. Getting rid of the EMBED tag requires a few changes to the OBJECT tag so that browsers like Firefox display the video properly.</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;object classid=&quot;clsid:d27cdb6e-ae6d-11cf-96b8-444553540000&quot; width=&quot;425&quot; height=&quot;344&quot; codebase=&quot;http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0&quot;&gt;&lt;param name=&quot;src&quot; value=&quot;http://www.youtube.com/SOME_VIDEO_URL&quot; /&gt;&lt;embed type=&quot;application/x-shockwave-flash&quot; width=&quot;425&quot; height=&quot;344&quot; src=&quot;http://www.youtube.com/SOME_VIDEO_URL&quot;&gt;&lt;/embed&gt;&lt;/object&gt;</pre></div></div>

<p>The above code was tested in IE 7, Firefox 3, and Safari 3. Your mileage may vary with older browsers.</p>
<h2>Update</h2>
<p>Nick Pettit shared a <a href="http://validifier.com" target="_blank">delightful tool</a> which solves the above headache and generates valid XHTML 1.0 Strict markup. Check out <a href="http://validifier.com"  target="_blank">http://validifier.com</a>.</p>

<p><a href="http://feeds.feedburner.com/~a/Webficient?a=EHZSq0"><img src="http://feeds.feedburner.com/~a/Webficient?i=EHZSq0" border="0"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Webficient?a=sNVveK"><img src="http://feeds.feedburner.com/~f/Webficient?i=sNVveK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Webficient?a=1wzX2K"><img src="http://feeds.feedburner.com/~f/Webficient?i=1wzX2K" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Webficient?a=FbhhWk"><img src="http://feeds.feedburner.com/~f/Webficient?i=FbhhWk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Webficient/~4/359850566" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.webficient.com/2008/08/08/valid-xhtml-for-youtube-videos/feed</wfw:commentRss>
		<feedburner:origLink>http://www.webficient.com/2008/08/08/valid-xhtml-for-youtube-videos</feedburner:origLink></item>
	</channel>
</rss>
