<?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>Craig Hyatt&#039;s Web Log</title>
	<atom:link href="http://chyatt.ca/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://chyatt.ca/blog</link>
	<description></description>
	<lastBuildDate>Fri, 25 Sep 2009 17:28:50 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Vim Tip #5 – Screen Lines vs. Virtual Lines</title>
		<link>http://chyatt.ca/blog/2009/09/25/vim-tip-5-%e2%80%93-screen-lines-vs-virtual-lines/</link>
		<comments>http://chyatt.ca/blog/2009/09/25/vim-tip-5-%e2%80%93-screen-lines-vs-virtual-lines/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 17:28:50 +0000</pubDate>
		<dc:creator>chyatt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://chyatt.ca/blog/?p=111</guid>
		<description><![CDATA[Life altering.
g j
g k,
g &#60;down arrow&#62;
g &#60;up arrow&#62;
The &#8216;g&#8217; tells vim to move only a screen line instead of a virtual line.
]]></description>
			<content:encoded><![CDATA[<p>Life altering.</p>
<pre>g j</pre>
<pre>g k,</pre>
<pre>g &lt;down arrow&gt;</pre>
<pre>g &lt;up arrow&gt;</pre>
<p>The &#8216;g&#8217; tells vim to move only a screen line instead of a virtual line.</p>
]]></content:encoded>
			<wfw:commentRss>http://chyatt.ca/blog/2009/09/25/vim-tip-5-%e2%80%93-screen-lines-vs-virtual-lines/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Vim Tip #4 &#8211; Moving around on a line</title>
		<link>http://chyatt.ca/blog/2009/02/06/vim-tip-moving-around-on-a-line/</link>
		<comments>http://chyatt.ca/blog/2009/02/06/vim-tip-moving-around-on-a-line/#comments</comments>
		<pubDate>Fri, 06 Feb 2009 21:30:23 +0000</pubDate>
		<dc:creator>chyatt</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://chyatt.ca/blog/?p=30</guid>
		<description><![CDATA[Today I found myself repeatedly wanting to modify the last word of the url in a in a line of code like this:
$base_url = 'http://www.example.com/shared';
For the purposes of this example, say I wanted to replace the word shared with the word sample.
There are probably many ways to achieve this.  Based on last week&#8217;s experience, perhaps this is [...]]]></description>
			<content:encoded><![CDATA[<p>Today I found myself repeatedly wanting to modify the last word of the url in a in a line of code like this:</p>
<pre>$base_url = 'http://www.example.com/shared';</pre>
<p>For the purposes of this example, say I wanted to replace the word <em>shared </em>with the word <em>sample.</em></p>
<p>There are probably many ways to achieve this.  Based on <a href="http://chyatt.ca/blog/2009/01/26/vim-tip-3-search-and-replace-and-keep-it-simple-stupid/">last week&#8217;s experience</a>, perhaps this is most appropriate:</p>
<pre>:s/shared/sample</pre>
<p>But again I found myself automatically wanting to make use of an <a href="http://chyatt.ca/blog/2009/01/12/vim-tip-1-replacing-changing-a-word/">even earlier tip</a>.  I wanted to navigate quickly to that last word and use &#8216;cw&#8217; to change it.  I couldn&#8217;t figure out how to do this quickly so I decided to look it up.  Here are some options:</p>
<pre><span style="font-family: Georgia; line-height: 19px; white-space: normal;">$</span>2bcw</pre>
<pre>$bbcw</pre>
<p>Both of these options move the cursor to the end of the line ($), then back 2 words (2b or bb), then change word (cw).  Of particular interest to me here was the &#8220;b&#8221; command, which complements the &#8220;w&#8221; command nicely.</p>
]]></content:encoded>
			<wfw:commentRss>http://chyatt.ca/blog/2009/02/06/vim-tip-moving-around-on-a-line/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quick and dirty CiviEvent reports in Drupal5</title>
		<link>http://chyatt.ca/blog/2009/02/04/quick-and-dirty-civievent-reports-in-drupal5/</link>
		<comments>http://chyatt.ca/blog/2009/02/04/quick-and-dirty-civievent-reports-in-drupal5/#comments</comments>
		<pubDate>Wed, 04 Feb 2009 16:59:52 +0000</pubDate>
		<dc:creator>chyatt</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Drupal]]></category>
		<category><![CDATA[civicrm]]></category>
		<category><![CDATA[drupal]]></category>

		<guid isPermaLink="false">http://chyatt.ca/blog/?p=52</guid>
		<description><![CDATA[CiviCRM gets you lots of bang for your buck, especially when you integrate it with Drupal.  In fact, we recently released a CiviEvent/Drupal based project at work and were very pleased with the time to market.  However, we missed a few items during the requirments phase that left our client hanging.  Specifically, we needed to deliver [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://civicrm.org/">CiviCRM</a> gets you lots of bang for your buck, especially when you integrate it with <a href="http://drupal.org/">Drupal</a>.  In fact, we recently released a <a href="http://civicrm.org/civievent">CiviEvent</a>/Drupal based project at work and were very pleased with the time to market.  However, we missed a few items during the requirments phase that left our client hanging.  Specifically, we needed to deliver some extra reports that CiviEvent doesn&#8217;t provide out-of-the-box.</p>
<p>Seasoned Drupal hackers will be screaming <a href="http://drupal.org/project/views">Views</a> at this point.  The catch is that CiviEvents are not stored as Drupal nodes, so views won&#8217;t work.  (Note:  If we were using Drupal 6.x, we could use Views 2!)</p>
<p>So I set about researching other solutions.  Here&#8217;s a rundown:</p>
<ul>
<li><a href="http://wiki.civicrm.org/confluence/display/CRMDOC/CiviReport">CiviReport</a> &#8211; This is the solution <a href="http://forum.civicrm.org/index.php/topic,5584.0.html">recommended</a> by the CiviCRM team.  Custom reports are provided to the end-user via the <a href="http://www.eclipse.org/birt/phoenix/">Eclipse BIRT</a> plugin</li>
<li><a href="http://wiki.civicrm.org/confluence/display/CRMDOC/Custom+Search+Components">CiviCRM Custom Search</a> &#8211; Another solution <a href="http://forum.civicrm.org/index.php/topic,4792.0.html">recommended</a> by the CiviCRM team</li>
<li><a href="http://forum.civicrm.org/index.php/topic,4815.0.html">Embedded SQL in a Drupal Page</a></li>
</ul>
<p>I loved the simplicity of the 3rd suggestion.  No need for report viewing software.  Canned reports can just be added as Drupal pages on an ongoing basis.  Access to these reports can be provided via Drupal roles.  It seemed to be in keeping with *the Drupal way*.</p>
<p>Here&#8217;s my approach:</p>
<ol>
<li>Create a new basic Drupal content type &#8220;Canned Report&#8221;</li>
<li>Use the <a href="http://drupal.org/project/content_access">Content Access</a> module to limit access to this content type (View-only for the roles I care about)</li>
<li>Set up a Menu to list each of the &#8220;Canned Reports&#8221; &#8211; display this menu for only the roles I care about</li>
<li>Create content -&gt; Canned Report for each of the reports my customer requires</li>
</ol>
<p>For example:</p>
<h2>1. Participants by Event</h2>
<p>This report is similar to the one you get when you click CiviEvent Summary in CiviCRM.  However, it lists all events instead of the most recent:</p>
<h3>Screenshots:</h3>
<ul>
<li><a href="http://chyatt.ca/blog/?attachment_id=79">Creating the Participants by Event Report</a></li>
<li><a href="http://chyatt.ca/blog/?attachment_id=80">Viewing the Participants by Event Report</a></li>
</ul>
<h3>PHP Code:</h3>
<pre>&lt;?php
$rpt  = "&lt;table class='canned_report'&gt;&lt;tr&gt;";
$rpt .= "&lt;th&gt;Event ID&lt;/th&gt;";
$rpt .= "&lt;th&gt;Title&lt;/th&gt;";
$rpt .= "&lt;th&gt;Start&lt;/th&gt;";
$rpt .= "&lt;th&gt;End&lt;/th&gt;";
$rpt .= "&lt;th&gt;Max. Participants&lt;/th&gt;";
$rpt .= "&lt;th&gt;Total Participants&lt;/th&gt;&lt;/tr&gt;";

$qry  = "select ev.id, ev.title, ev.start_date, ";
$qry .= "ev.end_date, ev.max_participants, ";
$qry .= "count(par.id) 'participants' ";
$qry .= "from civicrm_event as ev ";
$qry .= "left join civicrm_participant as par ";
$qry .= "on ev.id = par.event_id ";
$qry .= "group by ev.id order by ev.start_date";

$rptqry = db_query(db_rewrite_sql($qry));

while ($rptrow = db_fetch_array($rptqry)) {
   $rpt .= "&lt;tr&gt;&lt;td&gt;";
   $rpt .= $rptrow["id"] . "&lt;/td&gt;&lt;td&gt;";
   $rpt .= $rptrow["title"] . "&lt;/td&gt;&lt;td&gt;";
   $rpt .= $rptrow["start_date"] . "&lt;/td&gt;&lt;td&gt;";
   $rpt .= $rptrow["end_date"] . "&lt;/td&gt;&lt;td&gt;";
   $rpt .= $rptrow["max_participants"] . "&lt;/td&gt;&lt;td&gt;";
   $rpt .= $rptrow["participants"] . "&lt;/td&gt;&lt;/tr&gt;";
}
$rpt .= "&lt;/table&gt;";
print $rpt;
?&gt;</pre>
<h2>2. All Events by Start Date</h2>
<p>This report is just a simple list of all CiviEvents ordered by start date.</p>
<h3>Screenshots:</h3>
<ul>
<li><a href="http://chyatt.ca/blog/?attachment_id=69">Creating the All Events by Start Date Report</a></li>
<li><a href="http://chyatt.ca/blog/?attachment_id=70">Viewing the All Events by Start Date Report</a></li>
</ul>
<h3>PHP Code:</h3>
<pre>&lt;?php
$rpt  = "&lt;table class='canned_report'&gt;&lt;tr&gt;";
$rpt .= "&lt;th&gt;Event ID&lt;/th&gt;";
$rpt .= "&lt;th&gt;Title&lt;/th&gt;";
$rpt .= "&lt;th&gt;Start Date&lt;/th&gt;";
$rpt .= "&lt;th&gt;Start Time&lt;/th&gt;&lt;/tr&gt;";

$qry  = "select ev.id, ev.title, ev.start_date ";
$qry .= "from civicrm_event as ev order by ev.start_date";

$rptqry = db_query(db_rewrite_sql($qry));

while ($rptrow = db_fetch_array($rptqry)) {
   $start_date = explode(" ", $rptrow["start_date"]);
   $rpt .= "&lt;tr&gt;&lt;td&gt;";
   $rpt .= $rptrow["id"] . "&lt;/td&gt;&lt;td&gt;";
   $rpt .= $rptrow["title"] . "&lt;/td&gt;&lt;td&gt;";
   $rpt .= $start_date[0]  . "&lt;/td&gt;&lt;td&gt;";
   $rpt .= $start_date[1] . "&lt;/td&gt;&lt;/tr&gt;";
}
$rpt .= "&lt;/table&gt;";
print $rpt;
?&gt;</pre>
<pre></pre>
<p>Notice that I included a class=&#8221;canned_report&#8221; in the table definition in the above examples.  This allows you to easily style the reports using CSS.  For our client, I simply chose to let the current Drupal theme handle the styling.</p>
<p><a href="http://michaelosmith.com/node/5">Hat tip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://chyatt.ca/blog/2009/02/04/quick-and-dirty-civievent-reports-in-drupal5/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Vim Tip #3: Search and Replace (and Keep It Simple Stupid)</title>
		<link>http://chyatt.ca/blog/2009/01/26/vim-tip-3-search-and-replace-and-keep-it-simple-stupid/</link>
		<comments>http://chyatt.ca/blog/2009/01/26/vim-tip-3-search-and-replace-and-keep-it-simple-stupid/#comments</comments>
		<pubDate>Mon, 26 Jan 2009 19:00:20 +0000</pubDate>
		<dc:creator>chyatt</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://chyatt.ca/blog/?p=39</guid>
		<description><![CDATA[The Problem
Today I was hacking some mod_rewrite rules that looked like the following:
  # Ensure user logins occur securely
  RewriteCond %{HTTPS} off
  RewriteRule ^user https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

  # Ensure administration pages are secure
  RewriteCond %{HTTPS} off
  RewriteRule ^admin https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
  ... several more similar lines...
I wanted to replace the %{HTTP_HOST} with www.uoguelph.ca/.
The Solution
In a past life I would have tried a simple substituition.  In [...]]]></description>
			<content:encoded><![CDATA[<h3>The Problem</h3>
<p>Today I was hacking some <a href="http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html">mod_rewrite</a> rules that looked like the following:</p>
<pre>  # Ensure user logins occur securely
  RewriteCond %{HTTPS} off
  RewriteRule ^user https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

  # Ensure administration pages are secure
  RewriteCond %{HTTPS} off
  RewriteRule ^admin https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
  ... several more similar lines...</pre>
<p>I wanted to replace the <em>%{HTTP_HOST}</em> with <em>www.uoguelph.ca/.</em></p>
<h3>The Solution</h3>
<p>In a past life I would have tried a simple substituition.  In this case, I hesitated because I thought the regular expression to match <em>%{HTTP_HOST} </em>was going to be a little hairy.  What I tried to do instead was something like this:</p>
<ol>
<li>Add <em>www.uoguelph.ca/ </em>to the copy buffer</li>
<li>Visually select <em>%{HTTP_HOST}</em></li>
<li>Replace the visual selection with the buffer</li>
</ol>
<p>Since I couldn&#8217;t figure out a way to do so  I ended up doing a bunch of manual text entry.  =(</p>
<h3>The Real Solution</h3>
<p>Coming back to the problem now, I decided to try that simple substitution command:</p>
<p>s/%{HTTP_HOST}/www.uoguelph.ca\//</p>
<p>Turns out the regular expression wasn&#8217;t so bad after all.  =)  Had I tried this in the first place I could&#8217;ve then used the dot command to repeat it on each of the lines I cared about.  </p>
<h3>Learning from the Experience</h3>
<ol>
<li>KISS (Keep It Simple Stupid!)</li>
<li>Recognize the strengths of your tools and let them do what they&#8217;re good at</li>
</ol>
<p> </p>
<p>Note:</p>
<p>Astute readers may notice that I was hard coding the URL in those rewrite rults.  Don&#8217;t ask!  </p>
<p>(If you&#8217;re an expert mod_rewriter, please feel free to give me some pointers.)</p>
]]></content:encoded>
			<wfw:commentRss>http://chyatt.ca/blog/2009/01/26/vim-tip-3-search-and-replace-and-keep-it-simple-stupid/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Vim Tip #2: &#8211; Search for the word the cursor is sitting on</title>
		<link>http://chyatt.ca/blog/2009/01/21/vim-tip-2-search-for-the-word-the-cursor-is-sitting-on/</link>
		<comments>http://chyatt.ca/blog/2009/01/21/vim-tip-2-search-for-the-word-the-cursor-is-sitting-on/#comments</comments>
		<pubDate>Wed, 21 Jan 2009 14:40:08 +0000</pubDate>
		<dc:creator>chyatt</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://chyatt.ca/blog/?p=33</guid>
		<description><![CDATA[When in normal (command) mode, to search for the word that the cursor is sitting on, simply type:
*
So simple.   But that&#8217;s part of the point of this series.  To learn easier ways of accomplishing things I do all the time.  Previously I would have typed:
/the_word_my_cursor_is_sitting_on
Obviously that isn&#8217;t much more complicated, but one character is [...]]]></description>
			<content:encoded><![CDATA[<p>When in normal (command) mode, to search for the word that the cursor is sitting on, simply type:</p>
<p>*</p>
<p>So simple.   But that&#8217;s part of the point of this series.  To learn easier ways of accomplishing things I do all the time.  Previously I would have typed:</p>
<p>/the_word_my_cursor_is_sitting_on</p>
<p>Obviously that isn&#8217;t much more complicated, but one character is better than X characters.  For all X &gt; 1.  =)</p>
]]></content:encoded>
			<wfw:commentRss>http://chyatt.ca/blog/2009/01/21/vim-tip-2-search-for-the-word-the-cursor-is-sitting-on/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Vim Tip #1:  Replacing (changing) a word</title>
		<link>http://chyatt.ca/blog/2009/01/12/vim-tip-1-replacing-changing-a-word/</link>
		<comments>http://chyatt.ca/blog/2009/01/12/vim-tip-1-replacing-changing-a-word/#comments</comments>
		<pubDate>Mon, 12 Jan 2009 16:59:56 +0000</pubDate>
		<dc:creator>chyatt</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://chyatt.ca/blog/?p=26</guid>
		<description><![CDATA[This really isn&#8217;t a new one for me.  In fact, it&#8217;s a keystroke combination I use all the time.  But because it is so useful, I think it is a great way to start the series.
In normal mode (aka command mode), travel to the first character in the word you want to change and type:
cw
This [...]]]></description>
			<content:encoded><![CDATA[<p>This really isn&#8217;t a new one for me.  In fact, it&#8217;s a keystroke combination I use all the time.  But because it is so useful, I think it is a great way to start the series.</p>
<p>In normal mode (aka command mode), travel to the first character in the word you want to change and type:</p>
<p>cw</p>
<p>This will delete the word you&#8217;re sitting on and leave you in insert mode, ready to type in a replacement.</p>
<h3>Variations</h3>
<p>2cw &#8211; replace the next two words, or 6cw for the next six words, etc.</p>
<p>cW &#8211; a typical word is delimited by pucntuation or white space, using a capital W ignores punctuation and counts white space only</p>
]]></content:encoded>
			<wfw:commentRss>http://chyatt.ca/blog/2009/01/12/vim-tip-1-replacing-changing-a-word/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Vim Tip of the Week Series</title>
		<link>http://chyatt.ca/blog/2009/01/11/vim-tip-of-the-week-series/</link>
		<comments>http://chyatt.ca/blog/2009/01/11/vim-tip-of-the-week-series/#comments</comments>
		<pubDate>Sun, 11 Jan 2009 22:09:29 +0000</pubDate>
		<dc:creator>chyatt</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://chyatt.ca/blog/?p=18</guid>
		<description><![CDATA[I&#8217;m pretty average when it comes to vi(m).   To try to improve, I plan to learn and post about new tip or command each week.
I will keep this post updated with links to other posts in the series.  Also look out for the vim and tips tags!
Archive

Replacing (changing) a word
Search for the word the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m pretty average when it comes to vi(m).   To try to improve, I plan to learn and post about new tip or command each week.</p>
<p>I will keep this post updated with links to other posts in the series.  Also look out for the vim and tips tags!</p>
<h2>Archive</h2>
<ol>
<li><a title="Change word" href="http://chyatt.ca/blog/2009/01/12/vim-tip-1-replacing-changing-a-word/">Replacing (changing) a word</a></li>
<li><a href="http://chyatt.ca/blog/2009/01/21/vim-tip-2-search-for-the-word-the-cursor-is-sitting-on/">Search for the word the cursor is sitting on</a></li>
<li><a href="http://chyatt.ca/blog/2009/01/26/vim-tip-3-search-and-replace-and-keep-it-simple-stupid/">Search and replace (and KISS)</a></li>
<li><a href="http://chyatt.ca/blog/2009/02/06/vim-tip-moving-around-on-a-line/">Moving around on a line</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://chyatt.ca/blog/2009/01/11/vim-tip-of-the-week-series/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Web Development Checklist</title>
		<link>http://chyatt.ca/blog/2009/01/11/web-development-checklist/</link>
		<comments>http://chyatt.ca/blog/2009/01/11/web-development-checklist/#comments</comments>
		<pubDate>Sun, 11 Jan 2009 18:44:53 +0000</pubDate>
		<dc:creator>chyatt</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://chyatt.ca/blog/?p=6</guid>
		<description><![CDATA[For awhile now I&#8217;ve been maintaining a text file on my desktop which lists a bunch of to do items for web development.  It seems appropriate to transition that list to this space instead.
Have I missed anything?  Please let me know in the comments section.
Accessibility

I18N
Accessibility

Architecture

Use Design Patterns (when appropriate)
Graceful degradation/Progressive Enhancement
Error checking on both client [...]]]></description>
			<content:encoded><![CDATA[<p>For awhile now I&#8217;ve been maintaining a text file on my desktop which lists a bunch of to do items for web development.  It seems appropriate to transition that list to this space instead.</p>
<p>Have I missed anything?  Please let me know in the comments section.</p>
<h3>Accessibility</h3>
<ul>
<li>I18N</li>
<li>Accessibility</li>
</ul>
<h3>Architecture</h3>
<ul>
<li>Use Design Patterns (when appropriate)</li>
<li>Graceful degradation/Progressive Enhancement</li>
<li>Error checking on both client and server sides</li>
<li>Use XHTML</li>
<li>Logging</li>
<li>API</li>
<li>REST</li>
<li>RSS/Atom</li>
<li>microformats</li>
<li>Test Driven Development</li>
<li>Continuous Integration</li>
<li>Web Hooks</li>
<li><a href="http://googlewebmastercentral.blogspot.com/2009/05/introducing-rich-snippets.html">Rich Snippets</a></li>
</ul>
<h3>Look and Feel</h3>
<ul>
<li>Separate content from design using CSS</li>
<li>Provide stylesheets for various use cases:
<ul>
<li>Screen stylesheet</li>
<li>Print stylesheet</li>
<li>Portable device stylesheet</li>
</ul>
</li>
<li>Include Favicon</li>
<li>Gracefully handle various screen resolutions</li>
</ul>
<h3>Security</h3>
<ul>
<li>Limit # of login attempts to protect against dictionary attacks</li>
<li>Protect against double submits</li>
<li>Protect against XSS
<ul>
<li><a href="http://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet">Some nice strategies</a></li>
</ul>
</li>
<li>Protect against CRSF</li>
<li>OpenID</li>
</ul>
<h3>Performance</h3>
<ul>
<li>Speed (YSlow)</li>
<li>Caching</li>
</ul>
<h3>Search</h3>
<ul>
<li>SEO</li>
<li>Provide a sitemap.xml (iif dynamic)</li>
<li>Statistics, tracking, and Analytics</li>
</ul>
<p><strong>Update:  February 4, 2009 at 14:58</strong></p>
<p>Leonard Lin just posted a thought-provoking, similar-but-different <a href="http://randomfoo.net/2009/01/28/infrastructure-for-modern-web-sites">list of web infrastructure requirements</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://chyatt.ca/blog/2009/01/11/web-development-checklist/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
