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

<channel>
	<title>Jonathan Dean &#187; Code</title>
	<atom:link href="http://www.jonathandean.com/category/code/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jonathandean.com</link>
	<description>Web Development and Design</description>
	<lastBuildDate>Fri, 03 Feb 2012 22:49:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>An introduction to SASS and HAML</title>
		<link>http://www.jonathandean.com/2011/10/an-introduction-to-sass-and-haml/</link>
		<comments>http://www.jonathandean.com/2011/10/an-introduction-to-sass-and-haml/#comments</comments>
		<pubDate>Sat, 08 Oct 2011 17:35:04 +0000</pubDate>
		<dc:creator>Jonathan Dean</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[haml]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[sass]]></category>

		<guid isPermaLink="false">http://www.jonathandean.com/?p=1570</guid>
		<description><![CDATA[From my talk on learning HAML and SASS for Magma Rails 2011. Slides and an HTML reference version below. A sample application with all code examples is at https://github.com/jonathandean/SASS-and-HAML-FTW. The slide content is posted below the embedded slides for easier reading on the web. Sorry for all of the bullets, it just didn&#8217;t seem worth ...]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><h4>From my talk on learning HAML and SASS for <a href="http://magmarails.com">Magma Rails 2011</a>.</h4>
<p>Slides and an HTML reference version below. A sample application with all code examples is at <a href="https://github.com/jonathandean/SASS-and-HAML-FTW">https://github.com/jonathandean/SASS-and-HAML-FTW</a>.</p>
<p><span id="more-1570"></span></p>
<p>The slide content is posted below the embedded slides for easier reading on the web. Sorry for all of the bullets, it just didn&#8217;t seem worth the time to rewrite as paragraphs.</p>
<div style="width:425px" id="__ss_9635015"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/jonathandean/introduction-to-haml-9635015" title="Introduction to HAML" target="_blank">Introduction to HAML</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/9635015" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/jonathandean" target="_blank">jonathandean</a> </div>
</p></div>
<div style="width:425px" id="__ss_9635040"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/jonathandean/introduction-to-sass" title="Introduction to SASS" target="_blank">Introduction to SASS</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/9635040" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/jonathandean" target="_blank">Jon Dean</a> </div>
</p></div>
<h3>An introduction to HAML</h3>
<h4>What is HAML?</h4>
<ul>
<li>A more concise syntax for coding HTML in your Rails app</li>
<li>Uses indentation for nesting markup</li>
<ul>
<li>Reduces code (no closing tags)</li>
<li>Fixes the messy markup problem that often clutters views</li>
</ul>
<li>Uses a CSS-like syntax that is easier to read and compare to your style rules</li>
<li>Makes coding your View layer faster</li>
<ul>
<li>Note: doesn’t affect render time or client-side performance, simply reduces coding efforts and makes the developer more efficient</li>
</ul>
<li>Easy to learn!</li>
</ul>
<h4>Using HAML in Rails</h4>
<ul>
<li>Use it as a replacement for ERB files</li>
<li>If you use Bundler, add this to your Gemfile:</li>
</ul>
<pre class="brush: plain; title: ; notranslate">gem 'haml'</pre>
<ul>
<li>Files named filename.html.haml (instead of filename.html.erb) will be interpreted by HAML instead of ERB</li>
</ul>
<h4>A comparison</h4>
<h6>HTML</h6>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;body&amp;gt;
  &amp;lt;div id='wrapper'&amp;gt;
    &amp;lt;div class='stuff'&amp;gt;
      &amp;lt;a href='#'&amp;gt;Top&amp;lt;/a&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
</pre>
<p><em>7 lines, 78 characters</em></p>
<h6>HAML</h6>
<pre class="brush: xml; title: ; notranslate">
%body
  #wrapper
    .stuff
      %a{:href =&amp;gt; '#'}
</pre>
<p><em>4 lines, 36 characters</em></p>
<h4>Tag names</h4>
<p>Use % and then the name of the tag</p>
<h6>HAML</h6>
<pre class="brush: xml; title: ; notranslate">
%body

%div
</pre>
<h6>HTML</h6>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;body&amp;gt;&amp;lt;/body&amp;gt;

&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;
</pre>
<h4>ID&#8217;s</h4>
<p>ID&#8217;s are just like they are in CSS. They begin with # and are followed by the ID name</p>
<h6>HAML</h6>
<pre class="brush: xml; title: ; notranslate">
%div#mine

%p#yours
</pre>
<h6>HTML</h6>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;div id='mine'&amp;gt;&amp;lt;/div&amp;gt;

&amp;lt;p id='yours'&amp;gt;&amp;lt;/p&amp;gt;
</pre>
<h4>Classes</h4>
<p>Classes are also just like they are in CSS. They being with a . and are followed by the class name</p>
<h6>HAML</h6>
<pre class="brush: xml; title: ; notranslate">
%div.mine

%p.yours
</pre>
<h6>HTML</h6>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;div class='mine'&amp;gt;&amp;lt;/div&amp;gt;

&amp;lt;p class='yours'&amp;gt;&amp;lt;/p&amp;gt;
</pre>
<p>Here&#8217;s one way to have multiple classes. We&#8217;ll go over more options later.</p>
<h6>HAML</h6>
<pre class="brush: xml; title: ; notranslate">
%div.mine.yours
</pre>
<h6>HTML</h6>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;div class='mine yours'&amp;gt;&amp;lt;/div&amp;gt;
</pre>
<h4>div is the default tag name</h4>
<p>If you want to leave out the tag name and just put classes and/or ID&#8217;s, %div is assumed</p>
<h6>HAML</h6>
<pre class="brush: xml; title: ; notranslate">
%div#mine
</pre>
<p>or just</p>
<pre class="brush: xml; title: ; notranslate">
#mine
</pre>
<h6>HTML</h6>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;div id='mine'&amp;gt;&amp;lt;/div&amp;gt;
</pre>
<h4>ID&#8217;s and classes together</h4>
<p>You can put ID&#8217;s and classes together as well</p>
<h6>HAML</h6>
<pre class="brush: xml; title: ; notranslate">
#mine.yours

#mine.yours.his
</pre>
<h6>HTML</h6>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;div class='yours' id='mine'&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div class='yours his' id='mine'&amp;gt;
&amp;lt;/div&amp;gt;
</pre>
<h4>Nesting</h4>
<p>Tags are nested by indentation only. There are no closing tags!</p>
<h6>HAML</h6>
<pre class="brush: xml; title: ; notranslate">
#mine
  %p.yours hi!
</pre>
<h6>HTML</h6>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;div id='mine'&amp;gt;
  &amp;lt;p class='yours'&amp;gt;hi!&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
</pre>
<h4>Text content</h4>
<p>Text can go at the end of the line if there&#8217;s no other content to nest. It can also be nested itself, which is required with other nested content.</p>
<h6>HAML</h6>
<pre class="brush: xml; title: ; notranslate">
#mine
  %p.yours hi!
</pre>
<p>or</p>
<pre class="brush: xml; title: ; notranslate">
#mine
  %p.yours
    hi!
</pre>
<h6>HTML</h6>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;div id='mine'&amp;gt;
  &amp;lt;p class='yours'&amp;gt;hi!&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
</pre>
<p>Another example with text content and a tag</p>
<pre class="brush: xml; title: ; notranslate">
#mine
  %p.yours
    hi!
    %span dude
</pre>
<h6>HTML</h6>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;div id='mine'&amp;gt;
  &amp;lt;p class='yours'&amp;gt;
    hi! &amp;lt;span&amp;gt;dude&amp;lt;/span&amp;gt;
  &amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
</pre>
<p>This will <strong>not</strong> work and will produce an error. You cannot have text content on the same line as its parent tag and also nest other tags within it.</p>
<pre class="brush: xml; title: ; notranslate">
#mine
  %p.yours hi!
    %span dude
</pre>
<h4>Attributes</h4>
<p>Attributes can be added using a Ruby Hash syntax:</p>
<h6>HAML</h6>
<pre class="brush: xml; title: ; notranslate">
%a{:href =&amp;gt; 'http://hi.com'} hi

%input{:type =&amp;gt; 'submit'}
</pre>
<h6>HTML</h6>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;a href='http://hi.com'&amp;gt;hi&amp;lt;/a&amp;gt;

&amp;lt;input type='submit'&amp;gt;
</pre>
<p>Or a more HTML-like syntax:</p>
<h6>HAML</h6>
<pre class="brush: xml; title: ; notranslate">
%a(href='http://hi.com') hi

%input(type='submit')
</pre>
<h6>HTML</h6>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;a href='http://hi.com'&amp;gt;hi&amp;lt;/a&amp;gt;

&amp;lt;input type='submit'&amp;gt;
</pre>
<h4>Boolean attributes</h4>
<p>Use boolean values for attributes such as &#8216;selected&#8217;. To have a value selected, use:</p>
<h6>HAML</h6>
<pre class="brush: xml; title: ; notranslate">
%input{:selected =&amp;gt; true}
</pre>
<p>or</p>
<pre class="brush: xml; title: ; notranslate">
%input(selected=true)
</pre>
<p>or</p>
<pre class="brush: xml; title: ; notranslate">
%input(selected)
</pre>
<h6>HTML</h6>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;input selected&amp;gt;
</pre>
<p>To have a value deselected it&#8217;s the same but with false instead of true. This isn&#8217;t necessary in these examples of course (because you can just leave out the selected attributes) but is useful if you are getting the value from a variable instead of typing in the boolean value directly.</p>
<h6>HAML</h6>
<pre class="brush: xml; title: ; notranslate">
%input{:selected =&amp;gt; false}
</pre>
<p>or</p>
<pre class="brush: xml; title: ; notranslate">
%input(selected=false)
</pre>
<h6>HTML</h6>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;input&amp;gt;
</pre>
<h4>Using an array for ID&#8217;s and Classes</h4>
<p>For the ID attribute it will separate the values by an _ (underscore.) For the Class attribute it will add them as separate classes.</p>
<h6>HAML</h6>
<pre class="brush: xml; title: ; notranslate">
%p{:class =&amp;gt; ['one','two']} hi

%p{:id=&amp;gt; ['one','two']} hi
</pre>
<h6>HTML</h6>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;p class='one two'&amp;gt;hi&amp;lt;/p&amp;gt;

&amp;lt;p id='one_two'&amp;gt;hi&amp;lt;/p&amp;gt;
</pre>
<h4>HTML??</h4>
<p>You can also use regular HTML. This is handy when converting a file over time, using copy and paste with something like a tracking code, or anything else complicated and hard to write as HAML.</p>
<h6>HAML</h6>
<pre class="brush: xml; title: ; notranslate">
#myParagraph
  &amp;lt;p&amp;gt;Hello there!&amp;lt;/p&amp;gt;
</pre>
<h6>HTML</h6>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;div id='myParagraph'&amp;gt;
  &amp;lt;p&amp;gt;Hello there!&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
</pre>
<h4>Adding Ruby code</h4>
<p>Start the line with an = (equals sign) for Ruby code that will output something into the view. Start the line with a &ndash; (dash) for Ruby code that doesn&#8217;t output anything (which should be rare considering this code usually belongs in the controller.)</p>
<h6>HAML</h6>
<pre class="brush: xml; title: ; notranslate">
%p= 'hi '*5
</pre>
<h6>HTML</h6>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;p&amp;gt;hi hi hi hi hi&amp;lt;/p&amp;gt;
</pre>
<p>Note in the following example how the &#8216;end&#8217; isn&#8217;t necessary to close the block. This is done for you based on indentation just like everything else in HAML.</p>
<h6>HAML</h6>
<pre class="brush: xml; title: ; notranslate">
- 5.times do
  %p= 'hi'
</pre>
<h6>HTML</h6>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;p&amp;gt;hi&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;hi&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;hi&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;hi&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;hi&amp;lt;/p&amp;gt;
</pre>
<h4>Ruby interpolation</h4>
<p>Use #{} to interpolate Ruby code</p>
<h6>HAML</h6>
<pre class="brush: xml; title: ; notranslate">
- awesome_guy = 'Jon'
%p Hi #{awesome_guy}
</pre>
<p>is the same as</p>
<pre class="brush: xml; title: ; notranslate">
- awesome_guy = 'Jon'
%p= &amp;quot;Hi #{awesome_guy}&amp;quot;
</pre>
<h6>HTML</h6>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;p&amp;gt;Hi Jon&amp;lt;/p&amp;gt;
</pre>
<h4>Filters</h4>
<p>Filters start with a : (colon) and let you put in indented content to be interpreted in a special way. For example, the :javascript filter wraps some JavaScript in &lt;script&gt; and CDATA tags for inline JavaScript.</p>
<h6>HAML</h6>
<pre class="brush: xml; title: ; notranslate">
:javascript
  alert('Hello there!');
</pre>
<h6>HTML</h6>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;script&amp;gt;
//&amp;lt;![CDATA[
  alert('Hello there!');
//]]&amp;gt;
&amp;lt;/script&amp;gt;
</pre>
<p>The :css filter is similar and wraps some CSS in &lt;style&gt; and CDATA tags for inline CSS.</p>
<h6>HAML</h6>
<pre class="brush: xml; title: ; notranslate">
:css
  .mine{
    color: red;
  }
</pre>
<h6>HTML</h6>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;style&amp;gt;
/*&amp;lt;![CDATA[*/
  .mine{
    color: red;
  }
/*]]&amp;gt;*/
&amp;lt;/style&amp;gt;
</pre>
<p>There are quite a few other filters:</p>
<ul>
<li>
<pre>:plain</pre>
<p> does not parse the content</li>
<li>
<pre>:escaped</pre>
<p> same as plain but HTML-escapes the text</li>
<li>
<pre>:ruby</pre>
<p> pass the content to the normal Ruby interpreter</li>
<li>
<pre>:sass</pre>
<p> parse the content with SASS to produce CSS output</li>
<li>and more! (<a href="http://haml-lang.com/docs/yardoc/file.HAML_REFERENCE.html#filters">see the docs</a>)</li>
</ul>
<p>You can also make custom filters if you have special needs. See the documentation for <a href="http://haml-lang.com/docs/yardoc/Haml/Filters.html">HAML::Filters</a></p>
<h3>An introduction to SASS</h3>
<h4>What is SASS?</h4>
<ul>
<li>Syntactically Awesome Stylesheets</li>
<li>Smarter CSS</li>
<li>Gives you variables and methods (mixins) for CSS</li>
<li>Lets you nest declarations</li>
<li>Provides selector inheritance</li>
<li>Lets you do math with your variable values</li>
<li>Works by compiling .sass or .scss files into normal valid .css</li>
<li>Commonly used in Ruby on Rails applications but can be used in any web project</li>
</ul>
<h4>Two available syntaxes</h4>
<p>Both syntaxes have the same features and produce the same CSS output.</p>
<h6>SASS</h6>
<ul>
<li>HAML-style indentation</li>
<li>No brackets or semi-colons, based on indentation</li>
<li>Less characters to type</li>
<li>Enforced conventions/neatness</li>
</ul>
<h6>SCSS</h6>
<ul>
<li>Semi-colon and bracket syntax</li>
<li>Superset of normal CSS</li>
<li>Normal CSS is also valid SCSS</li>
<li>Newer and recommended</li>
</ul>
<p>A comparison</p>
<h6>SASS</h6>
<pre class="brush: css; title: ; notranslate">
$txt-size: 12px
$txt-color: #333
$link-color: #999

#main
  font-size: $txt-size
  color: $txt-color
  a
    color: $link-color
</pre>
<h6>SCSS</h6>
<pre class="brush: css; title: ; notranslate">
$txt-size: 12px;
$txt-color: #333;
$link-color: #999;

#main{
  font-size: $txt-size;
  color: $txt-color;
  a{
    color: $link-color;
  }
}
</pre>
<p>Both of these compile to:</p>
<h6>CSS</h6>
<pre class="brush: css; title: ; notranslate">
#main{
  font-size: 12px;
  color: #333333;
}
#main a{
  color: #999999;
}
</pre>
<p>In the examples we&#8217;ve already demonstrated how you can assign values to a variable and how basic nesting works. Variables are pretty self-explanatory when you look at the example. They start with a $, are assigned using a : (colon) just like CSS properties (not using an = like in other languages) and output the set value when referenced again without the : following it.</p>
<p>Nesting in SASS/SCSS not only makes you code more readable it saves you a lot of typing. You can see from the example how putting an anchor (a) tag inside of #main causes it to make a rule for &#8216;#main a&#8217; for you without making you type #main again. It&#8217;s also much easier at a glance to see what&#8217;s going on and provides a more direct correlation to the structure of the markup.</p>
<h4>Referencing the parent when nesting</h4>
<p>You can reference the parent selector with &amp; (ampersand)</p>
<h6>SCSS</h6>
<pre class="brush: css; title: ; notranslate">
#content{
  font-size: 12px;
  &amp;amp;, a{
    color: #333;
  }
}
</pre>
<h6>CSS</h6>
<pre class="brush: css; title: ; notranslate">
#content{
  font-size: 12px;
}
#content, #content a{
  color: #333;
}
</pre>
<h4>Selector inheritance</h4>
<p>You can also extend other CSS declarations with @extend</p>
<h6>SCSS</h6>
<pre class="brush: css; title: ; notranslate">
.error{
  color: red;
}
.seriousError{
  @extend .error;
  font-weight: bold;
}
</pre>
<h6>CSS</h6>
<pre class="brush: css; title: ; notranslate">
.error, .seriousError{
  color: red;
}
.seriousError{
  font-weight: bold;
}
</pre>
<h4>Mixins</h4>
<p>Mixins are sets of reusable styles, almost like methods in other languages.</p>
<h6>SCSS</h6>
<pre class="brush: css; title: ; notranslate">
@mixin awesome-text{
  font-size: 24px;
  font-weight: bold;
  color: blue;
}
p{
  @include awesome-text;
}
</pre>
<h6>CSS</h6>
<pre class="brush: css; title: ; notranslate">
p{
  font-size: 24px;
  font-weight: bold;
  color: blue;
}
</pre>
<p>Mixins can also take parameters!</p>
<h6>SCSS</h6>
<pre class="brush: css; title: ; notranslate">
@mixin awesome-text($size){
  font-size: $size;
  font-weight: bold;
  color: blue;
}
p{
  @include awesome-text(24px);
}
li{
  @include awesome-text(18px);
}
</pre>
<h6>CSS</h6>
<pre class="brush: css; title: ; notranslate">
p{
  font-size: 24px;
  font-weight: bold;
  color: blue;
}
li{
  font-size: 18px;
  font-weight: bold;
  color: blue;
}
</pre>
<p>Here&#8217;s a more advanced mixin example that has the common styles necessary for image-replacing a link inside of another element. Assume this is your markup:</p>
<pre class="brush: xml; title: ; notranslate">
&amp;lt;h1&amp;gt;&amp;lt;a href=&amp;quot;/&amp;quot;&amp;gt;Home page&amp;lt;/a&amp;gt;&amp;lt;/h1&amp;gt;
</pre>
<h6>SCSS</h6>
<pre class="brush: css; title: ; notranslate">
@mixin image-replace($image-url){
  &amp;amp;, a{
    display: block;
    background: url($image-url) no-repeat;
  }
  a{
    text-indent: -99999px;
    text-decoration: none;
  }
}
h1{
  @include image-replace('images/header.gif');
  &amp;amp;, a{
    width: 200px;
    height: 30px;
    background-position: 0px -100px;
  }
}
</pre>
<h6>CSS</h6>
<pre class="brush: css; title: ; notranslate">
h1, h1 a{
  display: block;
  background: url(“images/header.gif”) no-repeat;
}
h1 a{
  text-indent: -99999px;
  text-decoration: none;
}
h1, h1 a {
  width: 200px;
  height: 30px;
  background-position: 0px -100px;
}
</pre>
<h4>Mathematic operations</h4>
<p>You can do simple math operations with your variable values, even if they have units</p>
<h6>SCSS</h6>
<pre class="brush: css; title: ; notranslate">
$page-width: 500px;
$sidebar-width: 100px;
$content-width: $page-width - $sidebar-width;

#main{
  width: $page-width;
  #sidebar{
    width: $sidebar-width;
  }
  #content{
    width: $content-width;
  }
}
</pre>
<h6>CSS</h6>
<pre class="brush: css; title: ; notranslate">
#main{
  width: 500px;
}
#main #sidebar{
  width: 100px;
}
#main #content{
  width: 400px;
}
</pre>
<p>The supported mathematic operators are +, -, *, / and %</p>
<p>Because the division operator (/) is also valid in normal CSS, the following is not changed:</p>
<h6>SCSS</h6>
<pre class="brush: css; title: ; notranslate">
font: 10px/8px;
</pre>
<h6>CSS</h6>
<pre class="brush: css; title: ; notranslate">
font: 10px/8px;
</pre>
<p>Therefore, there are only three cases where / is used as division.</p>
<p>1. When one of the values is stored in a variable</p>
<h6>SCSS</h6>
<pre class="brush: css; title: ; notranslate">
$content-width: 500px;
width: $content-width/2;
</pre>
<h6>CSS</h6>
<pre class="brush: css; title: ; notranslate">
width: 250px;
</pre>
<p>2. When surrounded by parenthesis</p>
<h6>SCSS</h6>
<pre class="brush: css; title: ; notranslate">
width: (500px/2);
</pre>
<h6>CSS</h6>
<pre class="brush: css; title: ; notranslate">
width: 250px;
</pre>
<p>3. When part of another math expression</p>
<h6>SCSS</h6>
<pre class="brush: css; title: ; notranslate">
width: 10px + 500px/2;
</pre>
<h6>CSS</h6>
<pre class="brush: css; title: ; notranslate">
width: 260px;
</pre>
<p>To use variables in the CSS version without doing math operations, use #{} interpolation (described in more detail in the next section.)</p>
<h6>SCSS</h6>
<pre class="brush: css; title: ; notranslate">
$some-val: 10px;
$another-val: 8px;
font: #{$some-val}/#{$another-val};
</pre>
<h6>CSS</h6>
<pre class="brush: css; title: ; notranslate">
font: 10px/8px;
</pre>
<h4>Interpolation</h4>
<p>You can use variables in selectors and property declarations using interpolation with #{}</p>
<h6>SCSS</h6>
<pre class="brush: css; title: ; notranslate">
$class-name: wrapper;
$attribute-name: font;
div.#{$class-name}{
  #{$attribute-name}-size: 12px;
}
</pre>
<h6>CSS</h6>
<pre class="brush: css; title: ; notranslate">
div.wrapper{
  font-size: 12px;
}
</pre>
<p><em>Note: If you use RubyMine, it may falsely mark this syntax as invalid.</em></p>
<h4>Control directives</h4>
<h5>@if</h5>
<h6>SCSS</h6>
<pre class="brush: css; title: ; notranslate">
$type: big;
p{
  @if $type == big{
    font-size: 24px;
  }
}
</pre>
<h6>CSS</h6>
<pre class="brush: css; title: ; notranslate">
p{
  font-size: 24px;
}
</pre>
<h5>@if / @eles</h5>
<h6>SCSS</h6>
<pre class="brush: css; title: ; notranslate">
$type: small;
p{
  @if $type == big {
    font-size: 24px;
  } @else if $type == medium{
    font-size: 18px;
  } @else {
  font-size: 16px;
  }
}
</pre>
<h6>CSS</h6>
<pre class="brush: css; title: ; notranslate">
p{
  font-size: 16px;
}
</pre>
<h5>@for</h5>
<h6>SCSS</h6>
<pre class="brush: css; title: ; notranslate">
@for $i from 1 through 3 {
  .item-#{$i} {
    width: 10px * $i;
  }
}
</pre>
<h6>CSS</h6>
<pre class="brush: css; title: ; notranslate">
.item-1{
  width: 10px; }
.item-2{
  width: 20px; }
.item-3{
  width: 30px; }
</pre>
<h5>@each</h5>
<h6>SCSS</h6>
<pre class="brush: css; title: ; notranslate">
@each $item in item1, item2{
  .#{$item}{
    width: 500px;
  }
}
</pre>
<h6>CSS</h6>
<pre class="brush: css; title: ; notranslate">
.item1{
  width: 500px; }
.item2{
  width: 500px; }
</pre>
<h5>@while</h5>
<h6>SCSS</h6>
<pre class="brush: css; title: ; notranslate">
$i: 6;
@while $i &amp;gt; 0 {
  .item-#{$i} {
    width: 10px * $i;
  }
  $i: $i - 2;
}
</pre>
<h6>CSS</h6>
<pre class="brush: css; title: ; notranslate">
.item-6{
  width: 60px; }
.item-4{
  width: 40px; }
.item-2{
  width: 20px; }
</pre>
<h4>Importing other SASS files</h4>
<p>Import other .sass or .scss files using @import</p>
<h6>SCSS</h6>
<pre class="brush: css; title: ; notranslate">
@import &amp;quot;reset&amp;quot;;
</pre>
<p>or with the file extension if you really want</p>
<pre class="brush: css; title: ; notranslate">
@import &amp;quot;reset.css.scss&amp;quot;;
</pre>
<p>You can also create partials that will only be imported to other files and not compiled to .css files themselves. Just name the partial with an underscore in the front, such as _sample.css.scss. Now import the same way:</p>
<pre class="brush: css; title: ; notranslate">
@import &amp;quot;sample&amp;quot;;
</pre>
<p>Partials are handy for organizing styles into multiple files but compiling to only one file for use on the web.</p>
<p><em>Note: when using the Rails 3.1 asset pipeline, name your files with .css.scss or .css.sass extentions instead of just .scss or .sass (otherwise the .css part isn&#8217;t necessary.)</em></p>
<h4>Nested properties</h4>
<p>SASS can simplify the declaration of name-spaced CSS properties:</p>
<h6>SCSS</h6>
<pre class="brush: css; title: ; notranslate">
.sassy{
  font:{
    size: 12px;
    weight: bold;
  }
}
</pre>
<h6>CSS</h6>
<pre class="brush: css; title: ; notranslate">
.sassy{
  font-size: 12px;
  font-weight: bold;
}
</pre>
<h4>Color operations</h4>
<p>You can also do mathematic operations on color values:</p>
<h6>SCSS</h6>
<pre class="brush: css; title: ; notranslate">
color: #010203 + #040506;
</pre>
<h6>CSS</h6>
<pre class="brush: css; title: ; notranslate">
color: #050709;
</pre>
<p>How this is computed:<br />
#<strong>01</strong>02<em>03</em> + #<strong>04</strong>05<em>06</em> = #<strong>05</strong>07<em>09</em><br />
<strong>01</strong> + <strong>04</strong> = <strong>05</strong><br />
02 + 05 = 07<br />
<em>03</em> + <em>06</em> = <em>09</em></p>
<h4>Variable defaults</h4>
<p>Variable defaults will only assign the variable if it hasn&#8217;t been defined yet. This is handy for when you import a partial in some files but not in all of them and want the value from the partial to take precedence if it has already been defined.</p>
<p>In this example, $page-color will have the value of #333 because it was already defined and so the second assignment doesn&#8217;t happen:</p>
<pre class="brush: css; title: ; notranslate">
$page-color: #333;
$page-color: #666 !default;
</pre>
<p>In this example, $section-color is defined as #999 because it hasn&#8217;t already been defined previously:</p>
<pre class="brush: css; title: ; notranslate">
$section-color: #999 !default;
</pre>
<h4>Using SASS without Rails</h4>
<p>SASS can be used for any project you have CSS by installing the gem. Ruby is required to run for SASS to be installed and run, but this can be installed locally and isn&#8217;t required on the server. Once you have the compiled CSS output, just upload those files to the server any way you normally would.</p>
<p>To install the gem (after Ruby is already installed):</p>
<pre class="brush: plain; title: ; notranslate">
gem install sass
</pre>
<p>Then the easiest way is to have SASS watch for changes to the file and auto-compile on each save. This will cause input.scss to compile to output.css automatically:</p>
<pre class="brush: plain; title: ; notranslate">
sass --watch path/to/input.scss:path/to/output.css
</pre>
<h4>Using SASS with Rails 3.1</h4>
<p>The good news is that SASS is included by default with Rails 3.1 for use with the <a href="http://guides.rubyonrails.org/asset_pipeline.html">Asset Pipeline</a>! Just put your filename.css.scss files in app/assets/stylesheets/ and the Asset Pipeline will deal with compiling them for you. See the <a href="https://github.com/jonathandean/SASS-and-HAML-FTW">sample application</a> for an example.</p>
<h4>Using SASS with older versions of Rails</h4>
<p>First, add the following to your Gemfile if you&#8217;re using Bundler:</p>
<pre class="brush: plain; title: ; notranslate">
gem &amp;quot;sass&amp;quot;
</pre>
<p>(If you aren&#8217;t using Bundler then install and configure the gem as you would any other gem.)</p>
<p>You can really put your sass files anywhere, but I would recommend using the new convention introduced by Rails 3.1 for if you upgrade some day. You also don&#8217;t need the .css part of the filename but using filename.css.scss will once again make an upgrade easier later.</p>
<h3>Resources and next steps</h3>
<p>The documentation for <a href="http://haml-lang.com/docs.html">HAML</a> and <a href="http://sass-lang.com/docs.html">SASS</a> are the best places to learn more. They are short, easy reads and have plenty of examples to help you out. Also check out and modify the examples in the <a href="https://github.com/jonathandean/SASS-and-HAML-FTW">sample application</a> to understand more of how they work. Finally, start making your own applications using HAML and SASS. It&#8217;s also really easy to convert your existing applications since CSS is also valid SCSS and HAML also allows plain HTML. So you can really just change your file extensions now and convert as you go!</p>
<div class="shr-publisher-1570"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://www.jonathandean.com/2011/10/an-introduction-to-sass-and-haml/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>delayed_job in Rails 3</title>
		<link>http://www.jonathandean.com/2011/08/delayed_job-in-rails-3/</link>
		<comments>http://www.jonathandean.com/2011/08/delayed_job-in-rails-3/#comments</comments>
		<pubDate>Fri, 05 Aug 2011 15:05:58 +0000</pubDate>
		<dc:creator>Jonathan Dean</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[delayed_job]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://www.jonathandean.com/?p=1505</guid>
		<description><![CDATA[I searched for how to use delayed_job and Rails 3 on Google last night and went down a little rabbit hole I thought I could try to help someone else avoid. I ended up at http://www.dixis.com/?p=335 which provided a great, but out of date, article on how to do this. It recommends using collectiveidea&#8217;s fork ...]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>I searched for how to use delayed_job and Rails 3 on Google last night and went down a little rabbit hole I thought I could try to help someone else avoid. I ended up at <a href="http://www.dixis.com/?p=335">http://www.dixis.com/?p=335</a> which provided a great, but out of date, article on how to do this. It recommends using <a href="https://github.com/collectiveidea/delayed_job">collectiveidea&#8217;s fork of delayed_job</a> in the master branch, but as it turns out the latest in the master branch in  is in flux at the moment. The ActiveRecord backend is currently being abstracted into it&#8217;s own gem (which is a great idea) but that means the generators to make the database tables are no longer there. It also in general seems not ready for prime time.</p>
<p><span id="more-1505"></span></p>
<p>As of today, here&#8217;s what you should do for delayed_job and Rails 3:
<p>In your Gemfile:</a></p>
<pre class="brush: plain; title: ; notranslate">gem &quot;delayed_job&quot;, &quot;~&gt; 2.1.4&quot;</pre>
<p>Create the database migration and run it:</p>
<pre class="brush: plain; title: ; notranslate">$ script/rails generate delayed_job
$ rake db:migrate</pre>
<p>Now get out of here and start writing some code!</p>
<div class="shr-publisher-1505"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://www.jonathandean.com/2011/08/delayed_job-in-rails-3/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>jQuery Plugin: selectAll</title>
		<link>http://www.jonathandean.com/2011/07/jquery-plugin-selectall/</link>
		<comments>http://www.jonathandean.com/2011/07/jquery-plugin-selectall/#comments</comments>
		<pubDate>Tue, 19 Jul 2011 23:46:08 +0000</pubDate>
		<dc:creator>Jonathan Dean</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.jonathandean.com/?p=1499</guid>
		<description><![CDATA[I added a jQuery plugin that I wrote a while ago that turns a checkbox into one that selects or deselects other checkboxes on the page. Example HTML and CSS to follow. Find it at https://github.com/jonathandean/jquery.selectAll]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>I added a jQuery plugin that I wrote a while ago that turns a checkbox into one that selects or deselects other checkboxes on the page. Example HTML and CSS to follow.</p>
<p>Find it at <a href="https://github.com/jonathandean/jquery.selectAll">https://github.com/jonathandean/jquery.selectAll</a></p>
<div class="shr-publisher-1499"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://www.jonathandean.com/2011/07/jquery-plugin-selectall/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New jQuery plugin: Fix on scroll</title>
		<link>http://www.jonathandean.com/2011/07/jquery-plugin-fix-on-scroll/</link>
		<comments>http://www.jonathandean.com/2011/07/jquery-plugin-fix-on-scroll/#comments</comments>
		<pubDate>Tue, 19 Jul 2011 21:13:42 +0000</pubDate>
		<dc:creator>Jonathan Dean</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.jonathandean.com/?p=1495</guid>
		<description><![CDATA[I added a new jQuery plugin that will fix an element to the top of the browser window once you scroll past it, similar to the functionality of the actions bar in the newest gmail UI. Find it at https://github.com/jonathandean/jquery.fixOnScroll Update: The right sidebar (on this page only) should move down as you scroll past ...]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p><script>
jQuery(document).ready(function(){
jQuery('#sidebar').fixOnScroll();
});
</script></p>
<p>I added a new jQuery plugin that will fix an element to the top of the browser window once you scroll past it, similar to the functionality of the actions bar in the newest gmail UI.</p>
<p>Find it at <a href="https://github.com/jonathandean/jquery.fixOnScroll">https://github.com/jonathandean/jquery.fixOnScroll</a></p>
<p><strong>Update:</strong> The right sidebar (on this page only) should move down as you scroll past it in the browser window. Depending on your window size, you may need to shorten the height of your browser to see it. The code for this is simply:</p>
<pre class="brush: jscript; title: ; notranslate">
$(document).ready(function(){
  $('#sidebar').fixOnScroll();
});
</pre>
<p>There are more usage examples on the README page of the <a href="https://github.com/jonathandean/jquery.fixOnScroll">git repository</a></p>
<div class="shr-publisher-1495"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://www.jonathandean.com/2011/07/jquery-plugin-fix-on-scroll/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unlearning and Relearning jQuery: Client-side Performance Optimization</title>
		<link>http://www.jonathandean.com/2010/10/unlearning-and-relearning-jquery-client-side-performance-optimization/</link>
		<comments>http://www.jonathandean.com/2010/10/unlearning-and-relearning-jquery-client-side-performance-optimization/#comments</comments>
		<pubDate>Thu, 14 Oct 2010 00:03:17 +0000</pubDate>
		<dc:creator>Jonathan Dean</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.jonathandean.com/?p=1001</guid>
		<description><![CDATA[Here are my slides from my presentation at Magma Rails. Please feel free to make suggestions, corrections or ask questions via the comments or using the contact page. Unlearning and Relearning jQuery &#8211; Client-side Performance Optimization View more presentations from jonathandean.]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Here are my slides from my presentation at <a href="http://www.magmarails.com/">Magma Rails</a>. Please feel free to make suggestions, corrections or ask questions via the comments or using the <a href="/contact">contact</a> page.</p>
<p><span id="more-1001"></span></p>
<div style="width:425px" id="__ss_5447559"><strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/jonathandean/unlearning-and-relearning-jquery-clientside-performance-optimization" title="Unlearning and Relearning jQuery - Client-side Performance Optimization">Unlearning and Relearning jQuery &#8211; Client-side Performance Optimization</a></strong><object id="__sse5447559" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=unlearningrelearningjquery-101014192813-phpapp01&#038;stripped_title=unlearning-and-relearning-jquery-clientside-performance-optimization&#038;userName=jonathandean" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse5447559" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=unlearningrelearningjquery-101014192813-phpapp01&#038;stripped_title=unlearning-and-relearning-jquery-clientside-performance-optimization&#038;userName=jonathandean" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="padding:5px 0 12px">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/jonathandean">jonathandean</a>.</div>
</div>
<div class="shr-publisher-1001"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://www.jonathandean.com/2010/10/unlearning-and-relearning-jquery-client-side-performance-optimization/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Fixing blank pages after upgrading to WordPress 3</title>
		<link>http://www.jonathandean.com/2010/09/fixing-blank-pages-after-upgrading-to-wordpress-3/</link>
		<comments>http://www.jonathandean.com/2010/09/fixing-blank-pages-after-upgrading-to-wordpress-3/#comments</comments>
		<pubDate>Thu, 09 Sep 2010 20:12:52 +0000</pubDate>
		<dc:creator>Jonathan Dean</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://www.jonathandean.com/?p=875</guid>
		<description><![CDATA[Today I finally clicked the auto-upgrade button to upgrade my WordPress site to the newest version, 3.0.1. I then noticed that I wasn&#8217;t seeing the content of a lot of my pages. I could still see the lists of posts but I wasn&#8217;t getting anything on a single post or normal page. I verified the ...]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Today I finally clicked the auto-upgrade button to upgrade my WordPress site to the newest version, 3.0.1. I then noticed that I wasn&#8217;t seeing the content of a lot of my pages. I could still see the lists of posts but I wasn&#8217;t getting anything on a single post or normal page. I verified the data was in the database.</p>
<p>Here&#8217;s what my page.php looked like:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php get_header(); ?&gt;
&lt;div id=&quot;pageWrapper&quot;&gt;
	&lt;h2&gt;&lt;?php the_title(); ?&gt;&lt;/h2&gt;
	&lt;?php the_content(); ?&gt;
&lt;/div&gt;
&lt;?php get_footer(); ?&gt;
</pre>
<p>This was all fine and dandy for WordPress 2.x but obviously wasn&#8217;t working for 3.0. Turns out the solution is quite simple. I just need to put the_content() back into <a href="http://codex.wordpress.org/The_Loop">&quot;the loop&quot;</a>:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php get_header(); ?&gt;
&lt;div id=&quot;pageWrapper&quot;&gt;
	&lt;?php if (have_posts()) : while (have_posts()) : the_post(); ?&gt;
		&lt;h2&gt;&lt;?php the_title(); ?&gt;&lt;/h2&gt;
		&lt;?php the_content(); ?&gt;
	&lt;?php endwhile; endif; ?&gt;
&lt;/div&gt;
&lt;?php get_footer(); ?&gt;
</pre>
<p>I&#8217;m not sure why the change but I suppose I should have always explicitly used <a href="http://codex.wordpress.org/The_Loop">&quot;the loop&quot;</a>. Maybe I was taking advantage of a bug this whole time? Or maybe this was an intentional change that I should have seen coming. At any rate, if you see your content missing after an upgrade, take a look at your theme and make sure the_content() is always inside <a href="http://codex.wordpress.org/The_Loop">&quot;the loop&quot;</a>.</p>
<div class="shr-publisher-875"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://www.jonathandean.com/2010/09/fixing-blank-pages-after-upgrading-to-wordpress-3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A few good html5 references</title>
		<link>http://www.jonathandean.com/2010/08/a-few-good-html5-references/</link>
		<comments>http://www.jonathandean.com/2010/08/a-few-good-html5-references/#comments</comments>
		<pubDate>Sun, 15 Aug 2010 18:56:43 +0000</pubDate>
		<dc:creator>Jonathan Dean</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[html5]]></category>

		<guid isPermaLink="false">http://www.jonathandean.com/?p=843</guid>
		<description><![CDATA[I started playing with html5 and wanted to share some good resources I&#8217;ve found for anyone trying to get up to speed on the specs, browser support and code samples. For a very detailed overview of everything html5 is (and isn&#8217;t) head over to diveintohtml5.org. The section entitled &#8220;What does it all mean?&#8221; is a ...]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>I started playing with html5 and wanted to share some good resources I&#8217;ve found for anyone trying to get up to speed on the specs, browser support and code samples.</p>
<p>For a very detailed overview of everything html5 is (and isn&#8217;t) head over to <a href="http://diveintohtml5.org/">diveintohtml5.org</a>. The section entitled &#8220;What does it all mean?&#8221; is a great reference for all of the new elements, what they mean and how to use them. The site also has quite a lot of information on browser support, history of the working standard and all of new technologies html5 offers.</p>
<p>If you want to jump straight into some code <a href="http://html5reset.org/">html5reset.org</a> gives you three different zip files to download. A barebones template, &#8220;the kitchen sink&#8221; template and the kitchen sink with very useful comments. I recommend grabbing the kitchen sink with comments, reading through the code and comments and then making your own template from scratch. Don&#8217;t be tempted to include the entire kitchen sink in your code &#8211; remember that less is more! Nonetheless, it&#8217;s a great reference to learn from and should get you up and running with html5 quickly. It&#8217;s also a great spotlight on some of the great scripts available to support html5 elements in older browsers, such as hosted versions of John Resig&#8217;s &quot;<a href="http://ejohn.org/blog/html5-shiv/">HTML5 Shiv</a>&quot;, The <a href="http://www.modernizr.com/">Modernizr</a> script and <a href="http://code.google.com/p/ie7-js/">Dean Edwards&#8217; IE7/8/9 scripts</a>.</p>
<p>If that&#8217;s too much reading for you to understand what browsers are supporting html5 today, jump on over to <a href="http://www.findmebyip.com/litmus">The Web Design Checklist</a> for an excellent chart reference on browser compatibility. Just keep in mind that not seeing your site&#8217;s most popular browser in the compatible list doesn&#8217;t mean you can&#8217;t start using html5 today. There are lots of graceful degradation tricks and scripts out there (as mentioned in the above resources) that can get you looking forward to the future of the web.</p>
<p>Honorable mention goes to <a href="http://www.smashingmagazine.com/2009/08/04/designing-a-html-5-layout-from-scratch/">Coding A HTML 5 Layout From Scratch</a> By <a href="http://www.smashingmagazine.com/author/enrique-ramirez/">Enrique Ramirez</a> on <a href="http://www.smashingmagazine.com/">Smashing Magazine</a> for a quick barebones html5 layout.</p>
<p>I plan on writing an another article on html5 once I get a little farther with what I&#8217;m working on but wanted to share a few of the resources I&#8217;m using myself to get started. (Hopefully) more coming soon.</p>
<div class="shr-publisher-843"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://www.jonathandean.com/2010/08/a-few-good-html5-references/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dividing numbers in Ruby returning zero or an integer unexpectedly?</title>
		<link>http://www.jonathandean.com/2010/05/dividing-numbers-in-ruby-returning-zero-or-an-integer-unexpectedly/</link>
		<comments>http://www.jonathandean.com/2010/05/dividing-numbers-in-ruby-returning-zero-or-an-integer-unexpectedly/#comments</comments>
		<pubDate>Mon, 03 May 2010 15:58:13 +0000</pubDate>
		<dc:creator>Jonathan Dean</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.jonathandean.com/?p=714</guid>
		<description><![CDATA[There&#8217;s a &#8220;quirk&#8221; about Ruby that I often forget when going back to it after a long period of time using other languages. If you divide two integers in Ruby then it&#8217;s going to give you an integer as a result. Consider the following: To fix this you&#8217;ll need to convert your integers to floats ...]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>There&#8217;s a &#8220;quirk&#8221; about Ruby that I often forget when going back to it after a long period of time using other languages. If you divide two integers in Ruby then it&#8217;s going to give you an integer as a result. Consider the following:</p>
<pre class="brush: ruby; title: ; notranslate">
some_int = 3
another_int = 2
answer = some_int / another_int  # answer is going to be 1 here
</pre>
<p>To fix this you&#8217;ll need to convert your integers to floats first. The following will work:</p>
<pre class="brush: ruby; title: ; notranslate">
some_int = 3
another_int = 2
answer = some_int.to_f / another_int.to_f  # answer is going to be 1.5 here
</pre>
<p>the to_f function is going to convert the integers to floats and give you the float (decimal) answer.  </p>
<div class="shr-publisher-714"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://www.jonathandean.com/2010/05/dividing-numbers-in-ruby-returning-zero-or-an-integer-unexpectedly/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Running PHP and MySQL with phpMyAdmin on OS X 10.5</title>
		<link>http://www.jonathandean.com/2009/06/running-php-and-mysql-with-phpmyadmin-on-os-x-105/</link>
		<comments>http://www.jonathandean.com/2009/06/running-php-and-mysql-with-phpmyadmin-on-os-x-105/#comments</comments>
		<pubDate>Wed, 24 Jun 2009 00:32:27 +0000</pubDate>
		<dc:creator>Jonathan Dean</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.jonathandean.com/?p=311</guid>
		<description><![CDATA[Apache already comes pre-installed on OS X but PHP is not enabled by default. To enable PHP we need to edit our Apache config file by opening the Terminal and typing sudo nano /private/etc/apache2/httpd.conf and hitting enter (put in your admin password when it asks.) Type Control+W to bring up the search option and type ...]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Apache already comes pre-installed on OS X but PHP is not enabled by default. To enable PHP we need to edit our Apache config file by opening the Terminal and typing <em>sudo nano /private/etc/apache2/httpd.conf </em>and hitting enter (put in your admin password when it asks.) Type Control+W to bring up the search option and type <em>php5_module</em> and hit enter. Remove the # from the beginning of that line and then type Control+X to exit, Y to save when it asks, and Enter to overwrite the same filename.</p>
<p>Next, we want to create our PHP config file since it isn&#8217;t there by default. In the Terminal type <em>cd /private/etc</em> and hit enter, then type <em>sudo cp php.ini.default php.ini</em> and hit enter. This makes a copy of the default configuration we can use to get started with. We&#8217;ll use that later. Now you can start up Apache by going to System Preferences, Sharing and checking the Web Sharing box. If it was already checked, uncheck it and then recheck it again to restart Apache to accept our changes.</p>
<p>Now you need to install MySQL. Luckily, there&#8217;s already an install package available at <a title="MySQL.com" href="http://mysql.com">MySQL.com</a> so head on over there and download the latest stable version of 5.X. Now extract the zip, open the dmg and run the .pkg installer. I would also recommend double-clicking the .prefPane file for quick access to startup and shutdown commands without needing the Terminal. I don&#8217;t necessarily recommend installing the MySQLStartupItem package unless you really need it. In fact, you really shouldn&#8217;t leave MySQL or your web server running at all when you aren&#8217;t using it.</p>
<p>Once MySQL is installed you need to start it up. If you installed the preference pane (the .prefPane file) you can just go into System Preferences and then click MySQL. From there just click the button to get it started. Now we are going to want to set a password for the root user. To do that just open up the Terminal and type <em>mysql</em> . If it can&#8217;t find the mysql command we can add it to your path by editing your bash profile. Just type <em>sudo nano ~/.bash_profile</em> in the Terminal to edit the file, entering your admin password when it asks. Then add a line that looks like this: <em>export PATH=/usr/local/mysql/bin:$PATH</em> and type Control+X, Y, Enter to quit and save your changes. Then you&#8217;ll need to reload your bash profile by typing <em>source ~/.bash_profile</em></p>
<p>Now you should be able to type <em>mysql</em> in the Terminal from any directory to connect to mysql. From the <em>mysql&gt; </em>prompt type the following, substituting <em>yourpassword</em> with your desired password and then hit enter: <em>set password for &#8216;root&#8217;@'localhost&#8217; = password(&#8216;yourpassword&#8217;);</em> To make sure it was effective, log out by typing <em>exit;</em> and then enter and log back in again but this time we want to supply our credentials. So type the following to show that we want to log in using the root user and a password: <em>mysql -u root -p</em></p>
<p>To make sure PHP can connect we need to edit our php configuration to know where the MySQL socket is located. For this type <em>sudo nano /private/etc/php.ini</em> from the Terminal. When the file opens type Control+W to bring up the search box and type in <em>mysql.default_socket</em> and hit enter. After the equals sign on that line enter <em>/tmp/mysql.sock</em> and and type Control+X, Y, Enter to quit and save your changes. Now we need to restart Apache for the change to take effect by going to System Preferences, Sharing and unchecking then rechecking the Web Sharing box. (Or via command-line if you wish.)</p>
<p>Now to install phpMyAdmin just download the latest and extract it into your Sites folder in your user account (/Users/<em>username</em>/Sites/) or the Apache root (/Library/WebServer/Documents/), whichever you prefer. Browse to that folder in the Terminal and type <em>mkdir config</em> to make the config folder and then <em>chmod o+rw config</em> to make it writable. Then browse to the setup folder in your browser, which would be http://localhost/~<em>user</em>/phpmyadmin/setup/ if you installed it in your user&#8217;s Sites folder or just http://localhost/phpmyadmin/setup/ if you put it in the Apache root. From there click the New Server button and then Save to take the defaults (unless you know other options you need) and then Save again in the Configuration File settings of the Overview page. Now you should be able to log into your server by going to either http://localhost/~<em>user</em>/phpmyadmin/ or http://localhost/phpmyadmin/ and entering your root username and password. It&#8217;s highly recommended that you create another user with fewer privledges to do most of your work, though.</p>
<p>If you also want to be able to use a .htaccess file you&#8217;ll need to go to the Terminal and type <em>sudo nano /private/etc/apache2/httpd.conf</em> to edit your Apache config file. Then type Control+W and search for <em>AllowOverride</em>. Change that option from <em>None</em> to <em>All</em> so that it reads <em>AllowOverride All</em> and then  type Control+X, Y, Enter to quit and save your changes. Now we need to do the same for each user account. Do this by typing <em>sudo nano /private/etc/apache2/users/</em>username<em>.conf</em> and making the same change. If you aren&#8217;t sure what users there are you can type <em>ls /private/etc/apache2/users/ . </em>After you make the changes you&#8217;ll need to restart Apache again.</p>
<p>Some of this I did today and other parts of it I did a while ago so if anyone wants to give it a run through and let me know how it turns out that would be great. I know it could use some screenshots but those will have to come later since I was already done with this when I decided to write the instructions out.</p>
<p>My final word on this is to be mindful of security and make sure no one who shouldn&#8217;t can access any applications that are running. I would recommend shutting down MySQL and Apache when you aren&#8217;t developing to keep risks to a minimum. I&#8217;m not going to go into security since I assume that you know what you&#8217;re doing but it was worth mentioning again that any servers running on your machine are a potential security risk if you don&#8217;t know how to keep it safe.</p>
<p>References:</p>
<p><a title="Foundation PHP" href="http://foundationphp.com/tutorials/php_leopard.php">http://foundationphp.com/tutorials/php_leopard.php</a></p>
<p><a title="MySQL Documentaion Tutorial" href="http://dev.mysql.com/doc/refman/5.1/en/tutorial.html">http://dev.mysql.com/doc/refman/5.1/en/tutorial.html</a></p>
<p><a title="phpMyAdmin Setup Tool" href="http://wiki.phpmyadmin.net/pma/Setup">http://wiki.phpmyadmin.net/pma/Setup</a></p>
<p><a title="Enabling .htaccess in OS X" href="http://www.clagnut.com/blog/350/">http://www.clagnut.com/blog/350/</a>  </p>
<div class="shr-publisher-311"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://www.jonathandean.com/2009/06/running-php-and-mysql-with-phpmyadmin-on-os-x-105/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Apache rewrite rules to force secure/non-secure pages</title>
		<link>http://www.jonathandean.com/2009/03/apache-rewrite-rules-to-force-securenon-secure-pages/</link>
		<comments>http://www.jonathandean.com/2009/03/apache-rewrite-rules-to-force-securenon-secure-pages/#comments</comments>
		<pubDate>Sun, 29 Mar 2009 15:23:40 +0000</pubDate>
		<dc:creator>Jonathan Dean</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[apache]]></category>

		<guid isPermaLink="false">http://www.jonathandean.com/?p=108</guid>
		<description><![CDATA[If you're running an Apache server there's no need to hard code your links to force https/http or write server-side code. A few simple rewrite rules will allow you to redirect your secure pages to https and your non-secure pages back to http.]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>If you&#8217;re running an Apache server there&#8217;s no need to hard code your links to force https/http or write server-side code. A few simple rewrite rules will allow you to redirect your secure pages to https and your non-secure pages back to http. We&#8217;ll just check the server port to see if it&#8217;s using secure port 443 and redirect the page accordingly.</p>
<p>For instance, to redirect the checkout section to use https just use the following in your httpd.conf file (or vhost.conf if using Plesk):</p>
<pre class="brush: xml; title: ; notranslate">
&lt;Directory &quot;/var/www/html&quot;&gt;
RewriteEngine on
Options +FollowSymLinks
Order allow,deny
Allow from all
RewriteCond %{SERVER_PORT} !^443$
RewriteRule \.(gif|jpg|jpeg|jpe|png|css|js)$ - [S=1]
RewriteRule ^checkout(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
&lt;/Directory&gt;
</pre>
<p>Of course, you need to make sure that the directory path is valid for your setup. This will force http://www.example.com/checkout to redirect to https://www.example.com/checkout</p>
<p>If you want multiple pages change the RewriteRule to something like:</p>
<pre class="brush: xml; title: ; notranslate">
RewriteRule ^(checkout|login)(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
</pre>
<p>Just separate the page/folder names you want with the pipe (|) character. Read up on your regular expressions if this doesn&#8217;t make sense to you.</p>
<p>The first 4 lines are necessary Apache options we need to use for this to work properly. You can read the Apache manual for more information on those. The RewriteCond is testing if the server port is not 443, meaning we are not requesting via https. The first RewriteRule will ensure that files loaded within the page such as images, CSS, and JavaScript are loaded using the same protocol as the page itself. It matches on those file extensions and then uses the [S] (skip) flag to skip the next rule. This will help to avoid mixed content warnings in browsers. The list isn&#8217;t comprehensive so be sure to add to it as necessary. The RewriteRule under that uses a regular expression to test if our URI starts with checkout (or login in the second example) and if so it redirects the request to the same URL but this time using SSL.  The [L] flag means that rewrites will end on this rule and the [R] flag means that you redirect the page so that the address changes in the browser. Removing the [R] flag will cause the page to be served via https but the URL to still show http.</p>
<p>This is all well and good but it&#8217;s only half of the equation. Once a user leaves a secure page then we should also be able to forward them back to regular http. To do this we just basically set up the reverse of the RewriteCond and RewriteRule:</p>
<pre class="brush: xml; title: ; notranslate">
RewriteCond %{SERVER_PORT} ^443$
RewriteRule \.(gif|jpg|jpeg|jpe|png|css|js)$ - [S=1]
RewriteRule !^(checkout|login)(.*)$ http://%{SERVER_NAME}%{REQUEST_URI} [L,R]
</pre>
<p>Notice that instead of checking to see if we are <em>not</em> using port 443 in the RewriteCond we are checking to see if we <em>are</em> using it. Then in the RewriteRule we are making all pages that are <em>not</em> checkout or login redirect to http.</p>
<p>I&#8217;m pretty sure if you are using httpd.conf or a .htaccess file you can put these two lines directly below the original ones inside of the &lt;Directory&gt; block but I haven&#8217;t tested that.  Since I&#8217;m using Plesk I needed to put the original block in my vhost.conf file (used for configuration of non-secure pages) and the entire block again but this time with the second set of rules in my vhost_ssl.conf file (used for configuration of secure pages).  Also, if you are using any of the .conf files you will need to restart apache for your changes to take place.</p>
<p>And just as a final note, these steps will not help you in setting up your SSL certificate. You will already need to have that set up and functional before using this.</p>
<p>References:<br />
<a href="http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html" target="_blank">Apache mod_rewrite manual</a><br />
<a href="http://www.askapache.com/htaccess/mod_rewrite-tips-and-tricks.html" target="_blank">Ask Apache rewrite tips</a><br />
<a href="http://www.whoopis.com/howtos/apache-rewrite.html" target="_blank">whoopis.com tutorial</a><br />
<a href="http://stackoverflow.com/questions/257872/-htaccess-require-ssl-for-a-particular-url/693182#693182" target="_blank">My original post with this answer on Stack Overflow</a>  </p>
<div class="shr-publisher-108"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://www.jonathandean.com/2009/03/apache-rewrite-rules-to-force-securenon-secure-pages/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Search engine friendly URLs in PHP and Apache, Take 2</title>
		<link>http://www.jonathandean.com/2008/12/search-engine-friendly-urls-in-php-and-apache-take-2/</link>
		<comments>http://www.jonathandean.com/2008/12/search-engine-friendly-urls-in-php-and-apache-take-2/#comments</comments>
		<pubDate>Wed, 03 Dec 2008 16:53:58 +0000</pubDate>
		<dc:creator>Jonathan Dean</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://jedean.com/?p=71</guid>
		<description><![CDATA[A while back I posted this article about friendly URLs in PHP and Apache. Today I&#8217;d like to update that a little to not only show another method but also to enhance it a bit. When we&#8217;re done we&#8217;ll have search engine friendly URLs that look like the ones that Blogger uses. Why? Because search ...]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>A while back I posted <a href="http://interactivedeveloper.blogspot.com/2008/03/friendly-urls-in-php-and-apache.html">this article about friendly URLs in PHP and Apache</a>. Today I&#8217;d like to update that a little to not only show another method but also to enhance it a bit. When we&#8217;re done we&#8217;ll have search engine friendly URLs that look like the ones that <a href="http://www.blogger.com/">Blogger</a> uses.</p>
<p>Why? Because search engines tend to penalize dynamic URLs in search result rankings so we want ours to appear as static as possible. Now I know that search engines have come a long way in indexing dynamic content but every little bit helps. So as long as the setup is easy (and it is) we may as well put in that tiny bit of extra effort. Why would static URLs get a higher ranking? I assume because creating a static page takes just a little more effort than a dynamic one and therefore you could argue that the content is likely to be of higher quality. Also, the content isn&#8217;t going to be compromised by spam bots that are mass posting or even stupid humans that are (mass) posting.</p>
<p>For an easy example, I&#8217;ve listed 5 URL formats that are common and could likely serve  the same content. They are in order with the most search engine friendly at the top.</p>
<ol>
<li>http://www.example.com/post/title-of-post.html</li>
<li>http://www.example.com/post/title-of-post</li>
<li>http://www.example.com/post/654123</li>
<li>http://www.example.com/post.php?id=654123</li>
</ol>
<p>#3 beats #4 for two reasons. The first is that #4 is obviously dynamic content based on the fact that it is passing a parameter whereas #3 could actually be pointing to the static file post/index.html or post/default.htm. The other reason is that id is considered an especially obvious parameter to dynamic content and is often ignored when indexing. Using post.php?postId=654123 would be slightly better.</p>
<p>#2 is a huge leap over #3 because it actually includes the title of the post in the URL. Of all the things you can do to improve SEO, including your search keywords in the URL is going to give you the best result (and even better if the keyword is in your domain name!) #1 is just a little better still because adding that .html extension really enforces the appearance of being static content. As far as the crawler is concerned there is no way to tell that URL is dynamic.</p>
<p>So how do we make this happen? Well if you&#8217;re using PHP and Apache 2 you have a few options. (Note, Apache 1 will not work here because it doesn&#8217;t support the &#8220;look back&#8221; method that allows Apache to keep looking back in the URL until it finds our file. Without that it would only be able to find /post in the /post/title-of-post/ directory rather than in the root which is where it actually is. That may make more sense later.)</p>
<p>I recently modified Method 3 of <a href="http://www.sitepoint.com/article/search-engine-friendly-urls/3/">this sitepoint article</a> to get set up quickly with the scheme. It&#8217;s not perfect but it is pretty fast and easy to get up and running with for small sites. If you have a lot of dynamic pages then you may want to combine this method with the <a href="http://interactivedeveloper.blogspot.com/2008/03/friendly-urls-in-php-and-apache.html">URL rewrite method</a> I posted about previously so that you don&#8217;t have to create lots of files without extensions and update your Apache configuration for each. I like this method because it&#8217;s easier to mix friendly URL pages with normal directories. I say that because the regex used in the other method requires that you have a file extension for accessing a normal file directly. So it will ignore /somedir/images/img.jpg and /somedir/index.php but it will try to parse /somedir/example/ which can be a bit of a pain. With this method we&#8217;re only going to worry about particular dynamic files and let the rest operate as usual. A drawback of this method is that you can&#8217;t use it on your root directory. For instance you can&#8217;t have http://www.example.com/dynamic-parameter.html. It would have to be something like http://www.example.com/processor/dyanamic-parameter.html.</p>
<p>Now to get down to it. We&#8217;re going to do a few things here:</p>
<ul>
<li>Create or modify our .htaccess file to tell Apache that certain files should be processed as PHP, even without an extension (or you could edit your vhost.conf file if you use Plesk or even your main Apache config if you feel comfortable)</li>
<li>Either remove the .php extension from our dynamic page or create a new file with the same name and no extension and use require_once() to include the .php version</li>
<li>Add some PHP to parse our URI and set variables we can use to load the dynamic content</li>
</ul>
<p>So for the first item we&#8217;re going to open or create a .htaccess in our web root (or whatever folder we want to contain the dynamic pages.) If you only have one dynamic page, say post.php, you&#8217;d do something like this, substituting &#8220;post&#8221; with the name of your dynamic page (minus the .php extension.)</p>
<pre class="brush: xml; title: ; notranslate">
&lt;Files post&gt;
AcceptPathInfo On
ForceType application/x-httpd-php
&lt;/Files&gt;
</pre>
<p>If you have multiple pages then use filesMatch instead of Files and separate each file with a pipe character (|):</p>
<pre class="brush: xml; title: ; notranslate">
&lt;filesMatch &quot;post|blog|login|logout&quot;&gt;
AcceptPathInfo On
ForceType application/x-httpd-php
&lt;/filesMatch&gt;
</pre>
<p>Basically what we&#8217;re doing here with ForceType is telling Apache that these are PHP files and to process them as such. Typically, the .php extension gives it away but we don&#8217;t want that here.</p>
<p>Now like I said above, you can either remove the .php extension from your file or create a new file and include the .php version. If you are converting existing pages to use this method I&#8217;d recommend leaving your .php version in tact in case of bookmarks or indexed pages. So alongside &quot;post.php&quot; you&#8217;d create the file &quot;post&quot; with this in it:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
require_once('post.php');
?&gt;
</pre>
<p>So now we have the option of getting to http://www.example.com/post.php by just using http://www.example.com/post and leaving off the file extension. The next thing we need to do is parse the rest of that URL and do something with it. You can do this a lot of ways but I kind of like options so I wrote a pretty generic function that will just give us some variables to work with. Cutting right to the chase:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

$uriParts = null;
$dirsToRoot = 0;
$pathToRoot = '';
$linkToRoot = '';
$requestURI = '';
$requestParamString = '';
$requestParams = null;
parseRequestURI();

function parseRequestURI()
{
    global $uriParts;
    global $requestURI;
    global $requestParamString;
    global $requestParams;

    $uriParts = explode('?', $_SERVER['REQUEST_URI']);
    if(is_array($uriParts) &amp;amp;&amp;amp; !empty($uriParts[1]))
    {
        $requestParamString = $uriParts[1];
        $requestURI = $uriParts[0];
    }
    else if(is_array($uriParts))
        $requestURI = $uriParts[0];
    else
        $requestURI = $_SERVER['REQUEST_URI'];

    if(!empty($requestParamString))
    {
        $requestParams = array();
        $paramPairs = explode('&amp;amp;', $requestParamString);
        if(is_array($paramPairs))
        {
            foreach($paramPairs as $paramPair)
            {
                $paramParts = explode('=', $paramPair);
                $requestParams[$paramParts[0]] = $paramParts[1];
            }
        }
        else
        {
            $paramParts = explode('=', $paramPairs);
            $requestParams[$paramParts[0]] = $paramParts[1];
        }
    }

    $uriParts = explode('/', $requestURI);
    if(is_array($uriParts))
    {
        if(empty($uriParts[0])) array_shift($uriParts);
        if(empty($uriParts[count($uriParts)-1])) array_pop($uriParts);
    }
    if(substr($uriParts[count($uriParts)-1], -5) === '.html')
        $uriParts[count($uriParts)-1] = substr($uriParts[count($uriParts)-1], 0, -5);

    setPathToRoot();
}

function setPathToRoot()
{
    global $uriParts;
    global $dirsToRoot;
    global $pathToRoot;
    global $linkToRoot;

    $dirsToRoot = count($uriParts)-1;

    for($i=0; $i&lt;$dirsToRoot; $i++)
        $pathToRoot .= '../';

    $linkToRoot = empty($pathToRoot) ? './' : $pathToRoot;
}
?&gt;
</pre>
<p>I think the easiest way to use this is to just define this script as an auto prepend file so that it runs at the beginning of every PHP file. You can do that by adding the following line to your .htaccess file:</p>
<pre class="brush: xml; title: ; notranslate">
php_value auto_prepend_file /path/to/file.php
</pre>
<p>If you&#8217;re going the auto prepend route make sure you have no whitespace characters outside of the &lt;?php and ?&gt; or you could end up with HTML validation issues. You don&#8217;t want whitespace showing up before your DOCTYPE declaration!</p>
<p>Anyway, this will give you access to the following variables on every PHP page:</p>
<ul>
<li>$requestURI (String): The requested URL (without your domain name) not including any request parameters</li>
<li>$requestParamString (String): The full key/value pair request parameter string after the ?</li>
<li>$uriParts (Array): An array of the individual parts of $requestURI. You are mostly going to use this to load your dynamic content. If the last entry has a .html then it will strip it out.</li>
<li>$requestParams (Array): An associative array of the key/value pairs of $requestParamString</li>
<li>$pathToRoot (String): Prepending this to a relative path will help resolve it properly for you. Used for including CSS and other files (see below)</li>
<li>$linkToRoot (String): Just like $pathToRoot but is used for linking to other pages (see below)</li>
<li>dirsToRoot (Integer): The number of directories your browser will think you are from the root</li>
</ul>
<p>Here are a few examples of what those variables will look like for different types of URLs:</p>
<p>http://www.example.com/post/something</p>
<pre class="brush: php; title: ; notranslate">
$requestURI='/post/something'
$requestParamString=''
$uriParts=Array ( [0] =&gt; post [1] =&gt; something )
$requestParams=
$pathToRoot='../../'
$linkToRoot='../../'
$dirsToRoot=2
</pre>
<p>http://www.example.com/post/something.html</p>
<pre class="brush: php; title: ; notranslate">
$requestURI='/post/something.html'
$requestParamString=''
$uriParts=Array ( [0] =&gt; post [1] =&gt; something )
$requestParams=
$pathToRoot='../../'
$linkToRoot='../../'
$dirsToRoot=2
</pre>
<p>http://www.example.com/post/something/more.html?name=jon&#038;city=pittsburgh</p>
<pre class="brush: php; title: ; notranslate">
$requestURI='/post/something/more.html'
$requestParamString='name=jon&amp;amp;amp;city=pittsburgh'
$uriParts=Array ( [0] =&gt; post [1] =&gt; something [2] =&gt; more )
$requestParams=Array ( [name] =&gt; jon [city] =&gt; pittsburgh )
$pathToRoot='../../../'
$linkToRoot='../../../'
$dirsToRoot=3
</pre>
<p>http://www.example.com/help</p>
<pre class="brush: php; title: ; notranslate">
$requestURI='/help'
$requestParamString=''
$uriParts=Array ( [0] =&gt; help )
$requestParams=
$pathToRoot=''
$linkToRoot='./'
$dirsToRoot=0
</pre>
<p>I think you can get the idea but a few things to point out here. First, the .html extension has no effect on the $uriParts string which is what we&#8217;re going to use to get our dynamic variables. Second, you probably would never pass the query string portion after the ? but I added it for completeness. </p>
<p>The purpose of $pathToRoot and $linkToRoot may not be entirely clear at first. It&#8217;s there in order to help with a relative path issue you may run into. The reason being is that the browser has no idea that /post is your PHP file and that your currently directory is actually the root of the site (or /). As far as it&#8217;s concerned, you&#8217;re in the folder /post/something/. So say you had an images folder in your site root alongside post.php. Typically you could just refer to it using just images/imagename.jpg and that relative path would resolve properly for you. However, your browser thinks you are in the /post/something/ directory so it&#8217;s going to think you mean /post/something/images/ rather than /images. Sure, you could just use the path /images/imagename.jpg but that only works if your application is at the site root. What if you want to move the site into a subfolder on another server? Or, like in my case, you want to use the Site Preview function in Plesk for your client but the path contains several subdirectories before your root? All you have to do is change images/imagename.jpg to &lt;?php echo $pathToRoot; ?&gt;images/imagename.jpg it will give you the correct relative path. Sure it can be a pain to print that out everywhere but it was a life saver for me to be able to have that kind of portability. (Of course this is great for including style sheets and JavaScript too.)  The only difference between $pathToRoot and $linkToRoot is that when $pathToRoot would normally be an empty string (see the last example above), $linkToRoot will be &#8220;./&#8221;.  When including CSS the empty string would basically indicate the current directory which is fine. For a link the empty string actually indicates the current <span style="font-style:italic;">page</span> so we need to use &#8220;./&#8221; to explicitly indicate current <span style="font-style:italic;">directory</span> so that the link actually takes us somewhere.</p>
<p>The last part of this puzzle is to do something with those dynamic URLs. Of course, that part is completely up to you. You essentially have two choices as I see it. You can either pass only the parameter values you need and always pass them in a particular order (such as /post/jon/2008-12-04/search-engine-urls) or you can pass your parameters as pairs that come in any order (such as /post/title/search-engine-urls/username/jon/date/2008-12-04). In most cases I prefer the first method but the second can be useful for pages where you don&#8217;t know all of the parameters being passed. In that case the even indexes of $uriParts will always be the parameter names and the odd indexes will always be the values. Or I guess you can do it the other way around too. The point is that this will get the data to you and now you just have to make something meaningful out of it.</p>
<p>This should go without saying but don&#8217;t forget to always escape any values being passed to a page before it interacts with your database. Take all precautions you normally would in a dynamic page!</p>
<p><strong>Update 12/14/2008:</strong> Removed a test for &#8216;/&#8217; as the last character in setPathToRoot(). All URLs are now treated the same way.</p>
<p><strong>Update 1/24/2009:</strong> Added $linkToRoot to solve an issue in some cases where $pathToRoot would be an empty string. This works well for including CSS files but not good for making a link to the home page. $linkToRoot is the same value as $pathToRoot except when $pathToRoot is an empty string.  In that case $linkToRoot will be &#8220;./&#8221;  </p>
<div class="shr-publisher-71"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://www.jonathandean.com/2008/12/search-engine-friendly-urls-in-php-and-apache-take-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Friendly URLs in PHP and Apache</title>
		<link>http://www.jonathandean.com/2008/03/friendly-urls-in-php-and-apache/</link>
		<comments>http://www.jonathandean.com/2008/03/friendly-urls-in-php-and-apache/#comments</comments>
		<pubDate>Mon, 17 Mar 2008 15:39:58 +0000</pubDate>
		<dc:creator>Jonathan Dean</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://jedean.com/?p=27</guid>
		<description><![CDATA[I&#8217;ve tried a few different ways of doing friendly URLs in PHP and all have their advantages and disadvantages. For a good introduction and some other methods that don&#8217;t necessarily require an Apache server, take a look at this sitepoint article. I&#8217;ve used Method 2 there before (.htaccess Error Pages) but I don&#8217;t like what ...]]></description>
			<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>I&#8217;ve tried a few different ways of doing friendly URLs in PHP and all have their advantages and disadvantages.  For a good introduction and some other methods that don&#8217;t necessarily require an Apache server, take a look at <a href="http://www.sitepoint.com/article/search-engine-friendly-urls">this sitepoint article</a>.  I&#8217;ve used Method 2 there before (.htaccess Error Pages) but I don&#8217;t like what that does to your server logs.</p>
<p>For the method I use most often and am describing here, the credit goes to <a href="http://exanimo.com/">ex animo</a>.  He first showed me the .htaccess rewrite rule while we were working on a project at <a href="http://sunkingdigital.com/">sunKING</a> and I have only added a little of my own twist to it.</p>
<p>The basic idea is simple:</p>
<ol>
<li>You create a rewrite rule that redirects all web page requests to a single page
</li>
<li>This page parses the requested URL and determines what page to display</li>
<li>It&#8217;s so simple there is no step 3</li>
</ol>
<p>So let&#8217;s take a look at the .htaccess file you&#8217;ll have to make in order to redirect your web requests:</p>
<pre class="brush: xml; title: ; notranslate">
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?permalink=$1 [QSA,L]
</pre>
<p>If you&#8217;re quick on the uptake you&#8217;ll notice that all requests except those that have a period in them will be redirected to index.php and that it will get the request URI as a parameter.  The reason for not allowing the period is so that we can still access images and other static assets via their actual filename.  You don&#8217;t necessarily have to do this but I think it keeps things cleaner when you don&#8217;t have to parse URIs for images as well.  Not to mention that I can think of no good reason to have a friendly URL to an image or style sheet and can think of plenty of reasons not to.</p>
<p>Anyway, so what do we do with this?  Well, we want to set up index.php to parse the URI being passed in and display the page we want.  You can do this in any number of ways but here&#8217;s how I normally do my setup for most small sites.  My simplified index.php file will look something like this:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
define('INCLUDE_PATH', $_SERVER['DOCUMENT_ROOT'].'/../includes/');
ini_set('include_path', '.:'.INCLUDE_PATH);

// define the homepage
define('DEFAULT_PAGE', 'home');

// get the URI passed in via the .htaccess rewrite
$page = $_REQUEST['permalink'];
// set the page to be the homepage if none is given
$page = empty($page) ? DEFAULT_PAGE : $page;
// if the page doesn't exist, show an error page
$page = file_exists(INCLUDE_PATH.'pages/'.$page.'.php') ? $page : '404';

// I sometimes set page titles here to use a common header, but not necessary
switch($page)
{
    case '404':
        $pageTitle = 'page not found // ';
        break;
    case 'home':
        $pageTitle = 'home // ';
        break;
    case 'about':
        $pageTitle = 'about // ';
        break;
    case 'contact':
        $pageTitle = 'contact // ';
        break;
    case 'another/page':
        $pageTitle = 'another page // ';
        break;
    default:
        $pageTitle = '';
}

require_once('header.php'); // common header
require_once('pages/'.$page.'.php'); // requested page
require_once('footer.php'); // common footer
?&gt;
</pre>
<p>You can surely (and probably should) do a lot more processing here depending on your site&#8217;s needs, security concerns, etc. but this is the basic idea. Obviously, you want make sure those include (or require) statements reference the correct file locations. I usually simplify that by setting the include path as I have above.</p>
<p>Note that in the above example I have my includes directory outside of the public root so that the files aren&#8217;t directly web accessible.  Some servers can&#8217;t do this (such as ones running Plesk) so for those you&#8217;ll have to modify that first line to be like this and put the includes folder in a public directory: </p>
<pre class="brush: php; title: ; notranslate">
define('INCLUDE_PATH', $_SERVER['DOCUMENT_ROOT'].'/includes/');
</pre>
<p>So what&#8217;s left?  Not really anything.  All you have to do now is put your PHP files in the proper locations and you&#8217;re done.  So with the example above you would put the file about.php in your includes/pages folder in order to get to that page via http://example.com/about .  To get to http://example.com/about/me you would just put your me.php file inside of includes/pages/about/me.php .</p>
<p>In fact, in the time it took you to read to the bottom of this article you could have already had your site up.  Not too shabby, eh?</p>
<p>Just to help you get started I&#8217;ve created a zip file that you can just extract an upload to your server.  If you&#8217;re using <a href="http://mediatemple.net">Media Temple</a> or other hosts that work similarly you can just upload the contents to the root folder of the website (so the folder that is named like yourdomain.com).  The html folder in the zip is the public root (where you normally put your index.php or index.html file for your home page.)</p>
<p>If you&#8217;re using Plesk you&#8217;ll want to move things around just a little since it won&#8217;t let you include files out of the public root.  Just put the files in the html folder (index.php and .htaccess) into your httpdocs folder and throw the includes folder in there as well.  Then modify that first line that defines the INCLUDE_PATH constant for the new location as mentioned above.</p>
<p><a href="http://jonathandean.s3.amazonaws.com/code/friendly-urls.zip">Download the example site (.zip)</a>  </p>
<div class="shr-publisher-27"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><!-- End Shareaholic LikeButtonSetBottom Automatic -->]]></content:encoded>
			<wfw:commentRss>http://www.jonathandean.com/2008/03/friendly-urls-in-php-and-apache/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

