<?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/"
	xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule"
>

<channel>
	<title>Will Norris &#187; web</title>
	<atom:link href="http://willnorris.com/tag/web/feed" rel="self" type="application/rss+xml" />
	<link>http://willnorris.com</link>
	<description>there&#039;s more to life than this</description>
	<lastBuildDate>Sun, 05 Feb 2012 17:41:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4-alpha-19719</generator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
		<item>
		<title>delegating focus</title>
		<link>http://willnorris.com/2005/08/delegating-focus</link>
		<comments>http://willnorris.com/2005/08/delegating-focus#comments</comments>
		<pubDate>Tue, 16 Aug 2005 02:14:04 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://willnorris.com/?p=68</guid>
		<description><![CDATA[So here&#8217;s the problem &#8212; you have a web based application that uses multiple forms, often on the same page. Any arbitrary combination or number of forms may appear on the same page at the same time. For example, you may have a small login box as well as a form to subscribe to a [...]]]></description>
			<content:encoded><![CDATA[<p>So here&#8217;s the problem &#8212; you have a web based application that uses multiple forms, often on the same page.  Any arbitrary combination or number of forms may appear on the same page at the same time.  For example, you may have a small login box as well as a form to subscribe to a newsletter, as well as a form to perform a search.  In order to make things easier for the user, you&#8217;d like one of these input boxes to have focus when the page loads, but how do you determine which one to give it to?  If the login form is by itself on the page then it should have focus, but if there is another more dominant or more important form also on the page, then it should have focus instead.</p>

<p><span id="more-68"></span></p>

<p>Here&#8217;s a very simple solution I came up with this evening.  Any input box on the page should be able to &#8220;request focus&#8221; with a certain level of importance.  Whichever input box declares itself to be most important gets focus when the page loads.  First, include the following javascript into your page&#8230;</p>

<pre><code>var topObjectId; var topLevel = 0;
function requestFocus(objectId, level) {
    if (level &gt; topLevel) { topObjectId = objectId; topLevel = level; }
}
function giveFocus() {
    if (topObjectId) { document.getElementById(topObjectId).focus(); }
}
</code></pre>

<p>This sets up a couple of variables to keep track of which object is currently the most important and what its request level is.  It also provides a function for an element to request focus and a function to finally grant focus after all is said and done.  Now in your website, call requestFocus for each element necessary.  It might look something like&#8230;</p>

<pre><code>&lt;form id="loginForm"&gt;
    &lt;input type="text" id="username" /&gt;
    &lt;input type="password" id="password" /&gt;
&lt;/form&gt;
&lt;script&gt;requestFocus("username", 10)&lt;/script&gt;

&lt;!-- ... --&gt;

&lt;form id="searchForm"&gt;
    &lt;input type="input" id="searchTerm" /&gt;
&lt;/form&gt;
&lt;script&gt;requestFocus("searchTerm", 15)&lt;/script&gt;

&lt;!-- ... --&gt;

&lt;script&gt;giveFocus()&lt;/script&gt;
</code></pre>

<p>Here we have two forms, one to login and one to search.  In this case, the search form is more important than the login form (15 > 10) and therefore should have focus when the page loads.  At the very bottom of the page call giveFocus to actually, ya know, <strong>give focus</strong>.  Deciding the appropriate request level is of course up to the developer, and he will have to come up with his own rules as to what constitutes a more important form.</p>

<p>This certainly isn&#8217;t complicated or advanced by any means, but is still nonetheless quite useful.  I don&#8217;t particularly like throwing these little <code>&lt;script&gt;</code> statements all over the place, but apparently <code>onload</code> doesn&#8217;t work for inputs.  If anyone has a suggestion for a less intrusive method, I&#8217;d love to hear it.</p>
]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2005/08/delegating-focus/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Setting up a web development environment</title>
		<link>http://willnorris.com/2005/05/dev_environment</link>
		<comments>http://willnorris.com/2005/05/dev_environment#comments</comments>
		<pubDate>Sat, 07 May 2005 06:52:48 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://willnorris.com/wordpress/?p=5</guid>
		<description><![CDATA[At any given time, there are about a dozen or so websites that I help develop in some form or another. The easiest way to work on a site is to maintain a copy of it on my local machine&#8230; nothing special there. However, what if you want to view the development version of the [...]]]></description>
			<content:encoded><![CDATA[<p>At any given time, there are about a dozen or so websites that I help develop in
some form or another.  The easiest way to work on a site is to maintain a copy
of it on my local machine&#8230; nothing special there.  However, what if you want
to view the development version of the site?  Just fire it up in your web
browser.  What if you use server side scripting like PHP that needs to be run?
OS X has a built-in webserver making this fairly simple by placing the files in
your <code>~/Sites/</code> folder.  But what if your site contains links that are relative
to the site root such as <code>&lt;img src="/images/logo.jpg" /&gt;</code>?  Because you would be
accessing this site as <code>http://localhost/~username/test_site/</code>, your image will
fail do load.  You could setup VirtualHosts for each of your development sites,
and in fact I did this for a long time.  The problem is that this can become a
big annoyance and is an awful lot of work, especially if you have a large number
of sites in development.
<span id="more-5"></span></p>

<p>Apache&#8217;s <a href="http://httpd.apache.org/docs/mod/mod_vhost_alias.html#virtualdocumentroot">VirtualDocumentRoot</a> directive allows you to dynamically set the
document root  based on the host name that was used to request the document.  So
what we want to do is to create a unique host name for each website that we&#8217;re
working on, and have apache find the appropriate document root for that
particular site.  We&#8217;ll start with just one development site - example.com.
First we need a place to store the files for this site.. how about
<code>~/Sites/example/public_html/</code>.  I put everything in a &#8216;public&#95;html&#8217; folder
because I will often intentionally store some files <em>outside</em> of the document
root, such as configuration files that contain passwords and such (for that I
would use <code>~/Sites/example/include/</code> which I would also then add to my php
include&#95;path).</p>

<p>Next we need a unique host name that we can use to access our site.  Apache will
use parts of the hostname to determine what folder to use, so the easiest thing
is to just make them the same&#8230; so we will use &#8220;example&#8221;.  (An important thing
to note here is that you <em>can&#8217;t</em> use a real domain name to access the
development site.  You could however create your own top level domain to use
such as &#8220;example.dev&#8221;, but it&#8217;s certainly not necessary.)  Once you&#8217;ve decided
on a host name, you need to tell your computer that this name should resolve to
the local machine.  Do this by adding an entry to your <code>/etc/hosts</code> file along
the lines of</p>

<pre><code>127.0.0.1   example
</code></pre>

<p>If you have more than one development site, they can all be on one line
seperated by spaces&#8230;</p>

<pre><code>127.0.0.1   example1 example2 example3
</code></pre>

<p>Finally, you need to tell Apache to use virtual document roots.  Based on the
example setup we are using, you&#8217;ll want to add the following line to your apache
configuration file (<code>/etc/httpd/httpd.conf</code>)</p>

<pre><code>VirtualDocumentRoot /Users/username/Sites/%0/public_html/
</code></pre>

<p>In OS X, the virtual host module is not on by default so you will need to
uncomment the following lines</p>

<pre><code># Around Line 205
LoadModule vhost_alias_module libexec/httpd/mod_vhost_alias.so
...
# Around Line 248
AddModule mod_vhost_alias.c
</code></pre>

<p>Additionally, you will need to turn off canonical names</p>

<pre><code># Around Line 503
UseCanonicalNames   Off
</code></pre>

<p>Then just restart apache and you <em>should</em> be on your way.  For each additional
site now, you just need to create a folder in <code>~/Sites/</code> and add an appropriate
entry to <code>/etc/hosts</code>.</p>

<p><strong>Notes:</strong></p>

<ul>
<li><p>the DOCUMENT_ROOT that your scripts see will still be whatever one is
explicitly defined in your Apache config file (something like
<code>/Library/WebServer/Documents/</code>), so you may run into problems if your scripts
rely on this variable.  There is no way that I know of to get around
this.</p></li>
<li><p><strike>it is not possible to have separate cgi-bin directories for each site
that I am aware of.  They will all use the system default one
(<code>/Library/WebServer/CGI-Executables/</code>).</strike></p>

<p>To allow for per-site CGI bins, comment out the ScriptAlias directive
in the main apache config file</p>

<pre><code># Around Line 672
ScriptAlias /cgi-bin/ "/Library/WebServer/CGI-Executables/"
</code></pre>

<p>and create an .htaccess file in each site&#8217;s cgi-bin with the following:</p>

<pre><code>Options +ExecCGI
SetHandler cgi-script
</code></pre></li>
<li><p><strike>reading of .htaccess files seems to be inconsistent.  I thought I had
them working at one time, but they don&#8217;t seem to be right now.</strike></p>

<p>By default, OS X sets <code>AllowOverride None</code> for user sites, so that .htaccess
files are ignored &#8212; update this in <code>/etc/httpd/users/[username].conf</code> (not
in the main apache config file as one might expect).</p></li>
<li><p>these sites will not be accessible from any other machine unless they know to
setup those host names to resolve to your computer&#8217;s IP address.  This may or
may not be what you want &#8212; it prevents someone from stumbling upon your
development site (security by obscurity), but it makes it slightly more
difficult to <em>intentionally</em> show a site to someone else.</p></li>
<li><p>if you still want to run a &#8220;main&#8221; website for your computer, you can create a
virtual host with the name of your machine.  For example, if your machine were
named &#8220;aquinas&#8221; and people would normally get to your machine&#8217;s website by going
to <code>http://aquinas.local/</code>, then you just need to create your site in
<code>~/Sites/aquinas.local/public_html/</code>.  You could even just make this a symlinked
directory back to <code>/Library/WebServer/Documents/</code> if you wish for your &#8220;main&#8221;
site to reside there.</p></li>
<li><p>all of the examples here are referring to file locations and configurations
that come on a stock OS X Tiger box.  Nothing about this is specific to OS X, so
just apply the same principles to whatever OS you have apache running on.</p></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2005/05/dev_environment/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Open links in a new window</title>
		<link>http://willnorris.com/2005/04/open-links-in-a-new-window</link>
		<comments>http://willnorris.com/2005/04/open-links-in-a-new-window#comments</comments>
		<pubDate>Fri, 22 Apr 2005 15:36:10 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://willnorris.com/wordpress/2005/04/open-links-in-a-new-window</guid>
		<description><![CDATA[In the transistion to XHTML, many webmasters are shocked to discover that links with target="_blank" (which would typically cause the link to open in a new window) prevent their page from validating. This is actually part of the behavior of the link, and (to use proper MVC seperation) therefore should be handled by a scripting [...]]]></description>
			<content:encoded><![CDATA[<p>In the transistion to XHTML, many webmasters are shocked to discover that links
with <code>target="_blank"</code> (which would typically cause the link to open in a new
window) prevent their page from validating.  This is actually part of the
<em>behavior</em> of the link, and (to use proper <acronym title="Model View Controller">MVC</acronym> seperation) therefore should be handled by a
scripting language instead of embedded into the markup.  One common approach to
this is to use the relation attribute by setting <code>rel="external"</code>.  A bit of
javascript is then used to walk over your page looking for links with this
&#8220;external&#8221; designation and setting them to open in a new window.</p>

<p>After using this technique for a while, I discovered the links I typically (but
not always) wanted to open in a new window were those that left my site.  I then
alterred my javascript function to allow for this and ended up with&#8230;</p>

<pre><code>function externalLinks() {
    host = (document.location + "").replace(/^(https?:\/\/)([^/]+).*/i, "$2");

    if (!document.getElementsByTagName) return;
    var anchors = document.getElementsByTagName("a");
    for (var i=0; i&lt;anchors .length; i++) {
        var anchor = anchors[i];
        if (anchor.getAttribute("href")) {
            if (anchor.getAttribute("rel") != "local") {
                if (anchor.getAttribute("rel") == "external") {
                    anchor.target = "_blank"; 
                } else {
                    hrefData = anchor.getAttribute("href").match(/^https?:\/\/([^/]+).*/i);
                    if (hrefData &amp;&amp; hrefData[1] != host)
                        anchor.target = "_blank";
                }
            }
        }
    }
}
</code></pre>

<p>Call this function when the page loads by changing your <code>body</code> tag to be <code>&lt;body
onload="externalLinks();"&gt;</code>.  This will implicitly cause all links that go
off-site to open in a new window while still allowing you to explicitly force
any link to open in a new window by using <code>rel="external"</code>.  Additionally, you
can use <code>rel="local"</code> to explicitly force an off-site link to NOT open in a
new window.  For example, if your site were hosted at <code>www.foo.com</code>, then</p>

<pre><code>&lt;a href="http://www.foo.com/"&gt;&lt;/a&gt;
</code></pre>

<p>would open in the same window,</p>

<pre><code>&lt;a href="http://www.foo.com/" rel="external"&gt;&lt;/a&gt;
</code></pre>

<p>would open in a new window,</p>

<pre><code>&lt;a href="http://www.bar.com/"&gt;&lt;/a&gt;
</code></pre>

<p>would open in a new window, and</p>

<pre><code>&lt;a href="http://www.bar.com/" rel="local"&gt;&lt;/a&gt;
</code></pre>

<p>would open in the same window.</p>

<p></anchors></p>
]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2005/04/open-links-in-a-new-window/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fix old broken URLs with mod_rewrite</title>
		<link>http://willnorris.com/2005/01/cooluris</link>
		<comments>http://willnorris.com/2005/01/cooluris#comments</comments>
		<pubDate>Thu, 13 Jan 2005 20:03:57 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[modrewrite]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://willnorris.com/wordpress/2005/01/fix-old-broken-urls-with-mod_rewrite</guid>
		<description><![CDATA[&#8220;Despite the tons of examples and docs, mod_rewrite is voodoo. Damned cool voodoo, but still voodoo.&#8221; &#8212; Brian Moore I&#8217;ve been using mod&#95;rewrite for some time now for various things, but just recently I&#8217;ve really started diving into it in order to make cool URIs for skillet.com. The document root is presently a mess, and [...]]]></description>
			<content:encoded><![CDATA[<blockquote>
  <p>&#8220;Despite the tons of examples and docs, mod_rewrite is voodoo. Damned cool
  voodoo, but still voodoo.&#8221; &#8212; Brian Moore</p>
</blockquote>

<p>I&#8217;ve been using <a href="http://httpd.apache.org/docs/mod/mod_rewrite.html">mod&#95;rewrite</a> for some time now for various
things, but just recently I&#8217;ve really started diving into it in order to make
<a href="http://www.w3.org/Provider/Style/URI.html">cool URIs</a> for skillet.com.  The document root is presently a mess, and I
want to clean that up for so many reasons, but at the same time I can&#8217;t risk
breaking existing URLs.  It took a good little bit of reading and
experimenting, but I finally got mod_rewrite to do what I want.</p>

<!-- more -->

<p>What I was trying to do was pretty simple&#8230; I simply wanted to provide a list
of old URLs and have them be redirected to a list of new URLs.  This is
precisely what <a href="http://httpd.apache.org/docs/mod/mod_rewrite.html#RewriteMap">RewriteMap</a>s are for, but it took me a little while to really
get the hang of them.  To save anyone else who is working on this a little
time, allow me to explain what I did.</p>

<p>I first created a map file that contained a list of file replacements &#8212; first
the old file, then some whitespace, then the new file&#8230;</p>

<pre><code>#/home/skillet/domains/skillet.com/rewrite-map.txt

/news2/westwood_jan_05.html     /news2/westwood
/news2/grammy-nomination.html   /news2/grammy
/skilletnews.gif                /images/titles/news.gif
/skillet-chat.gif               /images/titles/chat.gif
/skillet-photos.gif             /images/titles/photos.gif
/skillet-pics.gif               /images/titles/pics.gif
/skillet-press.gif              /images/titles/press.gif
/skillet-promo.gif              /images/titles/promo.gif
/skillet-tour.gif               /images/titles/tour.gif
/skillet-video.gif              /images/titles/video.gif
</code></pre>

<p>I then added a new <a href="http://httpd.apache.org/docs/mod/mod_rewrite.html#RewriteMap">RewriteMap</a>, which I chose to name &#8220;rewrite-map&#8221; (but
you can name it anything you want), inside of the skillet VirtualHost.  This
is the only thing you might have trouble with if you use a shared hosting
provider, most of the time you don&#8217;t have access to the httpd.conf file, just
your .htaccess.  (RewriteMaps <strong>have</strong> to be defined inside the server config
or virtual host, though they can actually be used elsewhere)</p>

<pre><code>&lt;virtualhost&gt;
    ...

    RewriteEngine On
    RewriteMap rewrite-map txt:/home/skillet/domains/skillet.com/rewrite-map.txt

    ...
&lt;/virtualhost&gt;
</code></pre>

<p>Finally, I added the RewriteRule to the .htaccess.</p>

<pre><code>#/home/skillet/domains/skillet.com/public_html/.htaccess

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .* - [L]

RewriteCond ${rewrite-map:%{REQUEST_URI}} (.+)
RewriteRule .* %1 [L,R]
</code></pre>

<p>Now this doesn&#8217;t make quite as much sense, so let&#8217;s analyze what we&#8217;re doing
here.  The first rewrite condition checks to see if the requested file exists
on the file system.  If it does, then we simply exit with no changes (that&#8217;s
what the RewriteRule does) &#8212; no sense in looking through the rewrite-map if
we don&#8217;t have to right?  The next RewriteCond takes the requested URI and
looks it up in the rewrite-map.  If the result is non-null, we continue on;
without this RewriteCond, we&#8217;d go into a nasty infinite loop of rewrites.
Finally, the last RewriteRule replaces the entire URI with the result of the
lookup we just performed in the RewriteCond and redirects the user.  If the
requested file doesn&#8217;t exist on the filesystem and there is no entry for it in
the rewrite-map, a 404 Error is returned.</p>

<p>If you have a lot of entries in your map, you might consider using a hash
file.  It provides quicker lookups, but the downside is that you have to
rebuild the hash anytime you add new entries.  With the plain text map, you
can add entries at any time and they&#8217;ll automatically be grabbed by apache.
If you&#8217;re interested in hash files, search <a href="http://httpd.apache.org/docs/mod/mod_rewrite.html">here</a> for &#8220;hash file&#8221;.</p>

<p>So does it work?  Try going to <a href="http://www.skillet.com/skilletnews.gif">http://www.skillet.com/skilletnews.gif</a> and
you should be redirected to <a href="http://www.skillet.com/images/titles/news.gif">http://www.skillet.com/images/titles/news.gif</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2005/01/cooluris/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

