<?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>Webmonkey &#187; tutorial</title>
    <atom:link href="http://www.webmonkey.com/tag/tutorial/feed/" rel="self" type="application/rss+xml" />
    <link>http://www.webmonkey.com</link>
    <description>The Web Developer&#039;s Resource</description>
    <lastBuildDate>Mon, 06 May 2013 17:29:19 +0000</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <generator>http://wordpress.org/?v=3.4.2</generator>
    
    <item>
        <title>Learn to Code by Watching Others Write It</title>
        <link>http://www.webmonkey.com/2012/05/learn-to-code-by-watching-others-write-it/</link>
        <comments>http://www.webmonkey.com/2012/05/learn-to-code-by-watching-others-write-it/#comments</comments>
        <pubDate>Thu, 31 May 2012 15:52:09 +0000</pubDate>

                <dc:creator>Scott Gilbertson</dc:creator>

        <guid isPermaLink="false">http://www.webmonkey.com/?p=56955</guid>
        		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web Basics]]></category>
		<category><![CDATA[tutorial]]></category>
            <enclosure url="http://www.webmonkey.com/wp-content/uploads/2012/05/stopwatch-200x100.jpg" type="image/jpeg" length="48000" />
                    <description><![CDATA[<div class="rss_thumbnail"><img src="http://www.webmonkey.com/wp-content/uploads/2012/05/stopwatch.jpg" alt="Learn to Code by Watching Others Write It" /></div>Learning to code can be difficult, so sometimes it helps to watch someone else do it first. That's exactly what Code Player does -- show you the code as it’s written.]]></description>

            <content:encoded><![CDATA[<p><!-- wpautop enabled -->
<p><div id="attachment_56972" class="wp-caption aligncenter" style="width: 590px"><a href="http://www.webmonkey.com/wp-content/uploads/2012/05/stopwatch.jpg"><img src="http://www.webmonkey.com/wp-content/uploads/2012/05/stopwatch.jpg" alt="" title="stopwatch" width="580" height="305" class="size-full wp-image-56972" /></a><p class="wp-caption-text">Stopwatch in CSS 3, no JavaScript necessary. <em>Image: Screenshot/Webmonkey</em></p></div>Five years ago the hotness in web development was showing what you could create without resorting to Flash. Now it seems the same is true of JavaScript. While we&#8217;ve nothing against JavaScript, the increasingly powerful tools in CSS 3 mean that JavaScript is no longer a necessity for building cool stuff on the web.</p>
<p>The latest JavaScript-free demo we&#8217;ve run across is this <a href="http://thecodeplayer.com/walkthrough/make-a-stopwatch-using-css3-without-images-or-javascript">very cool stopwatch demo</a> made using only CSS 3, no images or JavaScript necessary. Now before you dive into the code and get all <a href="https://twitter.com/KarlVanHoet">Karl Van Hœt</a> on us, yes, there is a script used to handle CSS prefixing, but the actual stopwatch doesn&#8217;t require it to work. </p>
<p>But what caught our eye even more than the JavaScript-free stopwatch demo is the tutorial that accompanies it. The tutorial &#8212; which is one part screencast and one part code dump &#8212; is part of <a href="http://thecodeplayer.com/">Code Player</a>, which helps you learn how to do things by showing you the code as it&#8217;s written. It&#8217;s an interesting tutorial method, one we haven&#8217;t seen before. </p>
<p>Watching code being written isn&#8217;t for everyone, especially beginners who might not be able to easily follow what&#8217;s happening, but it&#8217;s well suited to those that already understand the basics and just want to see how some particular function was written. It also provides an interesting look at how other developers work, which in turn might teach you a new trick or two. </p>
<p>The Code Player offers a variety of playback speeds depending on how fast you want to run through the tutorial, and there&#8217;s a timeline scrubber for pausing and rewinding any bits you miss. Our only complaint is that Code Player forces focus in the browser; when you try to click another tab or do something in the background Code Player steals focus back immediately.</p>
<p>If learning something new by watching someone else type sounds intriguing, head on over to the <a href="http://thecodeplayer.com/">Code Player</a> site. And don&#8217;t worry if the stopwatch demo has no appeal for you, there are plenty of other tutorials to choose from. </p>
<div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2012/05/learn-to-code-by-watching-others-write-it/feed/</wfw:commentRss>
        <slash:comments>0</slash:comments>

        
    </item>
    
    <item>
        <title>Microdata: HTML5&#8242;s Best-Kept Secret</title>
        <link>http://www.webmonkey.com/2010/09/microdata-html5s-best-kept-secret/</link>
        <comments>http://www.webmonkey.com/2010/09/microdata-html5s-best-kept-secret/#comments</comments>
        <pubDate>Fri, 10 Sep 2010 17:46:24 +0000</pubDate>

                <dc:creator>Scott Gilbertson</dc:creator>

        <guid isPermaLink="false">http://www.webmonkey.com/?p=48655</guid>
        		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web Basics]]></category>
		<category><![CDATA[Web Standards]]></category>
		<category><![CDATA[Microdata]]></category>
		<category><![CDATA[microformats]]></category>
		<category><![CDATA[RDFa]]></category>
		<category><![CDATA[tutorial]]></category>
            <enclosure url="http://www.webmonkey.com/wp-content/uploads/2010/09/moleskine.jpg" type="image/jpeg" length="48000" />
                    <description><![CDATA[<div class="rss_thumbnail"><img src="http://www.webmonkey.com/wp-content/uploads/2010/09/moleskine.jpg" alt="Microdata: HTML5&#8242;s Best-Kept Secret" /></div>Given the amount of industry noise about native video and scripted animations, you&#8217;d be forgiven if you had never heard of the new microdata specification included in HTML5. Similar to outside efforts like Microformats, HTML5&#8242;s microdata offers a way of extend HTML by adding custom vocabularies to your pages. The easiest way to understand it [...]]]></description>

            <content:encoded><![CDATA[<p><!-- wpautop enabled --><a href="http://www.webmonkey.com/wp-content/uploads/2010/09/moleskine.jpg"><img src="http://www.webmonkey.com/wp-content/uploads/2010/09/moleskine.jpg" alt="" title="moleskine" width="200" /></a>
<p>Given the amount of industry noise about native video and scripted animations, you&#8217;d be forgiven if you had never heard of the new microdata specification included in HTML5.</p>
<p>Similar to outside efforts like Microformats, HTML5&#8242;s microdata offers a way of extend HTML by adding custom vocabularies to your pages.</p>
<p>The easiest way to understand it is to consider a common use case. Let&#8217;s say you want list details about a business on your page &#8212; the name, address, telephone number and so on. To do that you&#8217;ll need to use some vocabulary in addition to HTML, since there is no <code>&lt;business></code> tag.</p>
<p>Using microdata, you can create your own custom name/value pairs to define a vocabulary that describes a business listing.</p>
<p>When a search engine spider comes along, it will know that not only is your data a business listing, but it can discover the address, the phone number, or even the precise geo-coordinates if you want to include them.</p>
<p>Given that HTML5 is still a draft at this point, why bother?</p>
<p>Actually, despite its lack of publicity and HTML5&#8242;s still-incomplete status, microdata is already being used by Google, which has started adding information gleaned from microdata markup to its search result snippets.</p>
<p><span id="more-48655"></span></p>
<p>Microdata is useful today, but what about <a href="http://www.webmonkey.com/2007/12/microformats_are_awesome__now_put_them_to_work_for_your_site/">Microformats</a> or more complex tools like RDFa? The answer is that all three will work (and Google, in most cases, understands all of them). </p>
<p>In the end, the differences between the three are primarily in the syntax, and each has its advantages and disadvantages. But given that the Microdata specification will very likely become an official recommended web standard as part of HTML5, it seems the most future-proof of the three options.</p>
<p>So how do we add Microdata to a web page? Consider the following basic HTML markup, which might be used to describe my local coffee shop:</p>
<p><pre class="brush: js">
&lt;div>
    &lt;h1>Hendershot's Coffee Bar&lt;/h1>
    &lt;p>1560 Oglethorpe Ave, Athens, GA&lt;/p>
&lt;/div>
</pre>
<p>This markup gets the basic information on the page and humans can read it, but search engine spiders aren&#8217;t going to get much out of it. While it&#8217;s true that even Google says you should design for humans first and robots second, we can improve this code without making it any less human readable.</p>
<h3>Microdata</h3>
<p>To rewrite this business listing using HTML5&#8242;s microdata syntax, we would do something like this:</p>
<p><pre class="brush: js">
&lt;div itemscope itemtype="http://data-vocabulary.org/Organization"> 
    &lt;h1 itemprop="name">Hendershot's Coffee Bar&lt;/h1>
    &lt;p itemprop="address" itemscope itemtype="http://data-vocabulary.org/Address">
      &lt;span itemprop="street-address">1560 Oglethorpe Ave&lt;/span>, 
      &lt;span itemprop="locality">Athens&lt;/span>, 
      &lt;span itemprop="region">GA&lt;/span>.
    &lt;/p>
&lt;/div>
</pre>
<p>The Microdata markup adds a couple attributes you may not have seen before, <code>itemscope</code>, <code>itemtype</code> and <code>itemprop</code>. The first is essentially just a top level marker, it tells the search engine spider that you&#8217;re about to define something in the following nested tags. The <code>itemtype</code> attribute tells the spider what you&#8217;re defining &#8212; in this case, an organization.</p>
<p>The rest of the markup should look pretty familiar if you&#8217;ve used Microformats. The main change is the <code>itemprop</code> attribute (short for item property) to define what each element is. Because our address is all one paragraph, we&#8217;ve added some span tags to define each element of the address separately &#8212; street address, locality and so on. If we wanted, we could add other properties like a phone number (<code>itemprop="tel"</code>), a URL (<code>itemprop="url"</code>) or even geodata (<code>itemprop="geo"</code>).</p>
<p>So where did we get these <code>itemprop</code> vocabularies from? Well, as the URL in the <code>itemtype</code> attribute indicates, they come from <a href="http://www.data-vocabulary.org/">data-vocabulary.org</a>. Of course you can make up your own itemprop syntax, but if you want search engine spiders to understand your microdata, you&#8217;re going to have to document what you&#8217;re doing. Since the definitions at data-vocabulary.org cover a number of common use cases &#8212; events, organizations, people, products, recipes, reviews &#8212; it makes a good starting point.</p>
<h3>Microformats and RDFa</h3>
<p>So how does Microdata fit with <a href="http://microformats.org/">Microformats</a> and <a href="http://www.w3.org/TR/xhtml-rdfa-primer/">RDFa</a>? Well, the <a href="http://www.whatwg.org/">WHAT-WG</a>, which helps to develop the HTML5 spec, decided the flame wars provoked by the debate over whether to use Microformats or RDFa lacked sufficient vehemence, so they added a third definition of their own.</p>
<p>Actually, the reasoning seems to have been something like this: Microformats are a really good idea, but essentially a hack. Because Microformats rely only on the <code>class</code> and <code>rel</code> attributes, writing parsers to read them is complicated.</p>
<p>At the same time, RDFa was designed to work with the now-defunct XHTML 2.0 spec. Although RDFa is being ported to work with HTML5, it can be overly complex for many use cases. RDFa is a bit like asking what time it is and having someone tell you how to build a watch. Yes, RDFa can do the same things HTML5 microdata and Microformats do (and more), but if the history of the web teaches us a lesson, it&#8217;s that simpler solutions almost always win.</p>
<h3>Further Reading</h3>
<p>Before you dive into microdata, be sure to check out all the options. Google has a nice <a href="http://www.google.com/support/webmasters/bin/topic.py?topic=21997">overview on adding microdata to your page</a>, and offers examples using all three markup syntaxes. Mark Pilgrim&#8217;s Dive Into HTML5 also devotes <a href="http://diveintohtml5.org/extensibility.html">a chapter to microdata</a> with more detail on how microdata parsers read your markup.</p>
<p>Also, keep in mind that it isn&#8217;t just search engines that stand to benefit from microdata on your pages. The HTML5 spec also defines a set of <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#microdata-dom-api">DOM APIs for web browsers to read and manipulate microdata</a> on your pages. At the moment, no browser supports the API, but most probably will eventually.</p>
<p>The more information you can give the web, the more it can do with that information. Eventually, search engines could use microdata to find your friends on the web (like <a href="http://hueniverse.com/xrd/">XRD</a> and <a href="http://code.google.com/p/webfinger/">WebFinger</a>) and browsers could use it to connect you with those friends no matter what flavor-of-the-month social site they might be using.</p>
<p><strong>See Also:</strong><br/></p>
<ul>
<li><a href="http://www.webmonkey.com/2010/09/using-microformats-in-html5/">Using Microformats in HTML5</a></li>
<li><a href="http://www.webmonkey.com/2010/05/where-on-the-web-is-html5/">Where on the Web Is HTML5?</a></li>
<li><a href="http://www.webmonkey.com/2010/02/Add_Semantic_Value_to_Your_Pages_With_HTML_5/">Add Semantic Value to Your Pages With HTML 5</a></li>
<li><a href="http://www.webmonkey.com/2007/12/microformats_are_awesome__now_put_them_to_work_for_your_site/">Microformats are Awesome, Now Put Them to Work for Your Site</a></li>
</ul>
<div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/09/microdata-html5s-best-kept-secret/feed/</wfw:commentRss>
        <slash:comments>16</slash:comments>

        
    </item>
    
    <item>
        <title>Embed Videos In Your Web Pages Using HTML5</title>
        <link>http://www.webmonkey.com/2010/05/embed-videos-in-your-web-pages-using-html5/</link>
        <comments>http://www.webmonkey.com/2010/05/embed-videos-in-your-web-pages-using-html5/#comments</comments>
        <pubDate>Mon, 10 May 2010 22:34:59 +0000</pubDate>

                <dc:creator>Scott Gilbertson</dc:creator>

        <guid isPermaLink="false">http://www.webmonkey.com/?p=47343</guid>
        		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Multimedia]]></category>
		<category><![CDATA[Web Standards]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[video]]></category>
        <description><![CDATA[HTML5 video is taking the web by storm. Not only has a very public (and contentious) debate unfolded on the web about the efficacy of presenting videos using HTML5 instead of Flash, but momentum is gathering behind the nascent web standard. From giant video sites like YouTube to Wikipedia, everyone it seems wants to get [...]]]></description>

            <content:encoded><![CDATA[<p><!-- wpautop enabled -->HTML5 video is taking the web by storm.</p>
<p>Not only has a very public (<a href="http://www.webmonkey.com/2010/05/who-needs-flash/">and contentious</a>) debate unfolded on the web about the efficacy of presenting videos using HTML5 instead of Flash, but momentum is gathering behind the nascent web standard.</p>
<p>From giant video sites like YouTube to Wikipedia, everyone it seems wants to get their video out of Flash and into native web formats. With Microsoft recently announcing it will support the HTML5 video tag in the coming Internet Explorer 9, expect even more sites to abandon Flash for native video.</p>
<p>So, you want in on the fun? Do you want to use some HTML5 video tags on your site right now? No problem. Fasten your seat belts, as we&#8217;re about to take a tour of the wonderful world of HTML5 video.</p>
<p><span id="more-47343"></span></p>
<h2>Browser Support for HTML5</h2>
<p>First, let&#8217;s deal with some very basic stuff, like where this will work and where it won&#8217;t. As you can see in the table below, only the latest versions of most browsers support native video playback using HTML5&#8242;s &lt;video&gt; tag.</p>
<table style="text-align: center; margin: 20px 0;" border="0">
<caption style="font-size: 14px; font-weight: bold; text-align: left; margin: 6px 0;">HTML5 &lt;video&gt; support by browser:</caption>
<thead>
<tr style="margin: 6px 0;">
<th style="width: 80px;" title="Firefox 3.0">Fx 3.0</th>
<th style="width: 80px;" title="Firefox 3.5">Fx 3.5</th>
<th style="width: 80px;" title="Internet Explorer 7">IE7</th>
<th style="width: 80px;" title="Internet Explorer 8">IE8</th>
<th style="width: 80px;" title="Internet Explorer 9">IE9</th>
<th style="width: 80px;" title="Safari 3">Safari 3</th>
<th style="width: 80px;" title="Safari 4">Safari 4</th>
<th style="width: 80px;" title="Google Chrome 3+">Chrome 3+</th>
<th style="width: 80px;" title="Opera 10.5">Opera 10.5</th>
</tr>
</thead>
<tbody>
<tr style="margin: 6px 0;">
<td>·</td>
<td>✓</td>
<td>·</td>
<td>·</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
</tbody>
</table>
<p>Since Firefox 3.0 and IE 7 &amp; 8 lack any support for HTML5 video, you&#8217;ll have to come up with a fallback plan for serving video to those users. Depending on what you want to do you, could fallback first to Quicktime and then, failing that, to Flash. That&#8217;s the strategy used in <a href="http://camendesign.com/code/video_for_everybody">Video for Everyone</a> (note that as of v0.4, Video for everyone no longer falls back to QuickTime).</p>
<p>To keep things simple we&#8217;re just going to fall straight from HTML5 to Flash.</p>
<h2>Formats, Codecs and Technicalities</h2>
<p>The next thing you need to understand is what is actually happening when you load and play a video file in your web browser. You&#8217;re probably used to thinking of video as .mp4 or .mov files, but unfortunately it&#8217;s not that simple. The actual file formats are just containers. Think of them as a bit like a .zip file &#8212; they hold other stuff inside.</p>
<p>Each container holds at minimum one video track and, most likely, one audio track. When you watch a movie online, your video player (most likely Flash) decodes both the audio and video and sends the information to your screen and speakers.</p>
<p>Why does this matter? Well, because the process of decoding what&#8217;s inside the video container file varies. To know how to decode a movie, the player (which is your web browser in the case of HTML5 video) has to know which codec the movie was encoded with.</p>
<p>When it comes to web video there are two codecs to worry about: <strong>H.264</strong> and <strong>Theora</strong>.</p>
<p>There&#8217;s a <a href="http://www.webmonkey.com/2010/02/royalty_deadline_extended__but_hdot264_is_still_bad_for_the_web/">huge debate right now</a> among <a href="http://www.webmonkey.com/2010/02/can_google_save_free__open_web_video_with_vp8_/">web developers</a>, <a href="http://www.webmonkey.com/2010/02/opera_cto_sees_open__plug-in-free_video_in_web_s_future/">browser makers</a> and just about everyone else as to which codec is right for the web. We believe that a free, open codec without patent and licensing restrictions is the best solution for the web. Sadly, neither codec exactly fulfills that dream, so for now, let&#8217;s just skip the whole argument and be practical &#8212; we&#8217;re going to use both codecs.</p>
<p>Why? Well, have a look at the table below, which shows which codecs work where and you&#8217;ll quickly see that there is no one-size-fits-all-browsers solution. Only Google Chrome can play both H.264 and Theora.</p>
<table style="text-align: center" border="0">
<caption style="font-size: 14px; font-weight: bold; text-align: left; margin: 6px 0;">Codec support by browser/platform:</caption>
<thead>
<tr style="margin: 8px 0;">
<th></th>
<th style="width: 80px;">Firefox</th>
<th style="width: 80px;">Opera</th>
<th style="width: 80px;">Chrome</th>
<th style="width: 80px;">Safari</th>
<th style="width: 80px;">IE 9</th>
<th style="width: 80px;">iPhone</th>
<th style="width: 80px;">Android</th>
</tr>
</thead>
<tbody>
<tr style="margin: 20px 0;">
<th style="text-align: left;">Ogg Theora</th>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>·</td>
<td>·</td>
<td>·</td>
</tr>
<tr style="margin: 8px 0;">
<th style="text-align: left;">H.264</th>
<td>·</td>
<td>·</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
</tbody>
</table>
<p>So, you may be thinking &#8230; if HTML5 video doesn&#8217;t work in IE7 or IE8 and it means I&#8217;m going to have to encode my videos twice, then why bother at all? Well, the best answer is simple: mobile users. If you want iPhone and Android users to be able to see your video, HTML5 is the only way to do it &#8212; Flash support is coming to Android sooner or later but for now HTML5 is the only option, and we all know Flash doesn&#8217;t run on the iPhone or the iPad.</p>
<h2>The HTML5 Code</h2>
<p>Here&#8217;s how to actually embed your videos. First, we encode video in both .ogv and .mp4 containers. Encoding video is beyond the scope of this article, so instead we suggest you check out Mark Pilgrim&#8217;s online book <a href="http://diveintohtml5.org/">Dive Into HTML5</a>, which has a whole chapter devoted to <a href="http://diveintohtml5.org/video.html">understanding video encoding</a>. Pilgrim&#8217;s encoding suggestions use free software to get the job done, and in the end you&#8217;ll have two files &#8212; one .mp4 and one .ogv.</p>
<p>Now it&#8217;s time to unleash those movies in pure HTML glory. Here&#8217;s the code:</p>
<pre class="brush: js">&lt;video width="560" height="340" controls&gt;
  &lt;source src="path/to/myvideo.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'&gt;
&lt;source src="path/to/myvideo.ogv" type='video/ogg; codecs="theora, vorbis"'&gt;
&lt;/video&gt;</pre>
<p>Yes, that&#8217;s it. What we&#8217;ve done here is use the <code>&lt;video&gt;</code> tag to specify the dimensions of our video, and to denote that we want to use the browser&#8217;s default controls. Then, within the video tag, we&#8217;ve added two <code>&lt;source&gt;</code> elements which link to our video files.</p>
<p>The &#8220;type&#8221; attribute of the <code>&lt;source&gt;</code> tag helps the browser understand which file it should load. It&#8217;s a bit of an ugly chunk of code that needs to specify the container format, the video codec and the audio codec.</p>
<p>In this case we&#8217;ve assumed standard .ogv and baseline encoded H.264 video as per Pilgrim&#8217;s tutorial. See the <a href="http://wiki.whatwg.org/wiki/Video_type_parameters">WHATWG wiki</a> for more information on which video types you can specify.</p>
<p>And there you have it &#8212; native web video, no plugins required.</p>
<h2>Dealing With Everyone Else</h2>
<p>What about IE7, IE8 and older versions of just about any other browser? Well, for those users, we&#8217;ll fall back on Flash. To do that, we just use an <code>&lt;embed&gt;</code> tag within our video tag:</p>
<pre class="brush: js">&lt;video width="560" height="340" controls&gt;
  &lt;source src="path/to/myvideo.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'&gt;  
&lt;source src="path/to/myvideo.ogv" type='video/ogg; codecs="theora, vorbis"'&gt;
  &lt;object width="640" height="384" type="application/x-shockwave-flash"
		data="path/to/swf/player.swf?image=placeholder.jpg&amp;file=path/to/myvideo.mp4"&gt;
		&lt;param name="movie" value="path/to/swf/player.swf?image=placeholder.jpg&amp;file=path/to/myvideo.mp4" /&gt;
	&lt;/object&gt;
&lt;/video&gt;</pre>
<p>Now any browser that doesn&#8217;t understand the HTML5 video tag will just continue on its way until it hits the object tag, which it should understand (note that the order, mp4 before ogv, is important for iPad support &#8212; Apple requires that mp4 be the first video file).</p>
<p>Of course for this to work you need a Flash video container. <a href="http://www.longtailvideo.com/players/jw-flv-player/">JW Player</a> is one popular example, or you can roll your own using Adobe&#8217;s tools. Also remember that we still haven&#8217;t handled the case of an older version of Firefox with no Flash plugin installed (maybe your users are surfing your tubes with an outdated Linux machine). You can always add good old text-based links to the video files as a catch-all fix for anyone who can&#8217;t, for whatever reason, see either the HTML5 or Flash versions.</p>
<h2>Conclusion</h2>
<p>Embedding HTML5 video isn&#8217;t significantly more difficult than using Flash, especially if you&#8217;ve been using H.264 video files in your Flash player &#8212; which is exactly what YouTube has done with its HTML5 beta.</p>
<p>While we&#8217;re concerned about the licensing and patent requirements of H.264, it isn&#8217;t hard to notice that if you skip Theora and make all non-H.264 fall back to Flash, you&#8217;ve still saved yourself a considerable encoding headache. In fact, that&#8217;s probably the best practical argument against Mozilla and Opera&#8217;s refusal to support H.264.</p>
<p>If you&#8217;d like to use some of the more advanced aspects of HTML5 video, be sure to check the <a href="http://jilion.com/sublime/video">SublimeVideo player</a>, which offers very nice JavaScript-powered set of custom controls. Also be sure to have a look at <a href="http://camendesign.com/code/video_for_everybody">Video for Everybody</a>, which makes for more complex code but handles just about every use case you could imagine. And there&#8217;s a <a href="http://open.pages.kevinwiliarty.com/external-video-for-everybody/">handy Video for Everybody WordPress plugin</a> as well.</p>
<p><strong>See Also:</strong></p>
<ul>
<li><a href="http://www.webmonkey.com/2010/02/building_web_pages_with_html_5/">Building Web Pages With HTML5</a></li>
<li><a href="http://www.webmonkey.com/2010/02/Add_Semantic_Value_to_Your_Pages_With_HTML_5/">Add Semantic Value to Your Pages With HTML5</a></li>
<li><a href="http://www.webmonkey.com/2010/05/who-needs-flash/">Who Needs Flash?</a></li>
</ul>
<div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/05/embed-videos-in-your-web-pages-using-html5/feed/</wfw:commentRss>
        <slash:comments>52</slash:comments>

        
    </item>
    
    <item>
        <title>Ajax for Beginners</title>
        <link>http://www.webmonkey.com/2010/02/ajax_for_beginners/</link>
        <comments>http://www.webmonkey.com/2010/02/ajax_for_beginners/#comments</comments>
        <pubDate>Wed, 17 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=775</guid>
        		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[JavaScript has had the XMLHttpRequest object for almost a decade now, but it really only started getting wide attention in 2004. All this attention was mostly due to some showoff web applications that made every developer who saw them think, &#8220;I want my site to do that!&#8221; But it also has to do with the [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --></p><p>JavaScript has had the XMLHttpRequest object for almost a decade now, but it really only started getting wide attention in 2004. All this attention was mostly due to some showoff web applications that made every developer who saw them think, &#8220;I want my site to do that!&#8221; But it also has to do with the spiffy, spiffy name given to it by the folks at AdaptivePath, who named this asynchronized application <a href="http://www.adaptivepath.com/publications/essays/archives/000385.php" class="external text" title="http://www.adaptivepath.com/publications/essays/archives/000385.php" rel="nofollow">Ajax</a>. Maybe you&#8217;ve heard of it?

</p><p>A few high-profile Google applications in particular made a splash with Ajax: <a href="http://maps.google.com/" class="external text" title="http://maps.google.com/" rel="nofollow">Maps</a> and <a href="http://gmail.google.com/gmail" class="external text" title="http://gmail.google.com/gmail" rel="nofollow">Gmail</a> were first. It also powers some of the core functionality in the user interface of the ever-so-popular photo sharing site <a href="http://www.flickr.com" class="external text" title="http://www.flickr.com" rel="nofollow">Flickr</a>. By now, Ajax has become integral to the fabric of the web, especially in the era of real-time applications like <a href="http://www.twitter.com">Twitter</a>, <a href="http://www.google.com/buzz">Buzz</a> and <a href="http://www.google.com/wave">Wave</a> (all of which use Ajax extensively in their webapp front ends, for the record). Ajax may also lay claim to being the first JavaScript object with its own <a href="http://www.ajaxian.com/" class="external text" title="http://www.ajaxian.com/" rel="nofollow">fan website</a>. Date.com doesn&#8217;t count, although I did have a scintillating chat with a lady there once about the getTimeZoneoffset method.



</p><span id="more-775"></span><p><br />

</p>

<a name="What_is_Ajax.3F"></a><h3> <span class="mw-headline">What is Ajax?</span></h3>

<p>So what is this fancy object that everybody wants a piece of? In brief, it&#8217;s a solution to one of the big annoyances of web interfaces. Generally, the user inputs some data or makes a choice, and clicks a button that sends the data to the server. The server takes a look at the data and sends back a whole new web page, which is loaded into the browser. Reloading a page every time you want to do something is annoying, disjunctive and time-consuming for the user. XMLHttpRequest moves that browser-server interaction to behind the scenes, so the user can just keep on playing with the same page, even while elements on the page are talking to the server! Go take a look at <a href="http://www.google.com/webhp?complete=1" class="external text" title="http://www.google.com/webhp?complete=1" rel="nofollow">Google Suggest</a> if I&#8217;ve lost you &#8212; it&#8217;s a nice, eloquent example of this.

</p><p>JavaScript has always been able to sneakily trigger a server-side script without anything happening in the browser by using a few classic tricks. This one, for example:<tt>onSubmit='runascript = new Image(); runascript.src="<a href="http://www.wired.com/images/archiveyscript.php" class="external free" title="http://www.wired.com/images/archiveyscript.php" rel="nofollow">http://www.wired.com/images/archiveyscript.php</a>?" + this.value'</tt>. That sort of chicanery is good, maybe, for caching form data to a file on the server, but it doesn&#8217;t return any information to the JavaScript that calls it, so its usefulness is limited. Ajax, on the other hand, can get a full parcel of data back from the script it calls. Hence the &#8220;XML&#8221; part of the name  &#8211;  which really is just there for looks, kind of like the &#8220;Java&#8221; part of JavaScript, because the returned data can be plain text or whatever you like, if XML is overkill or just not your cup of tea.

</p><p>This opens up millions of exciting possibilities. Every form submission, every JavaScript event, and heaven knows what else, can now interact with server-side databases and processing power. Data retrieval, password authentication, image generation &#8211;  you name it, Ajax can trigger it.

</p>

<a name="Making_Your_Own"></a><h3> <span class="mw-headline">Making Your Own</span></h3>



<p>The potential of Ajax-enhanced web apps is limited only by your imagination &#8211;  and by browser support. Mozilla-based browsers can do it, and Safari, and newer versions of Explorer, and Opera 8 but not Opera 7. It&#8217;s best to incorporate a fallback way of doing things for users who aren&#8217;t as cutting edge as you&#8217;d like them to be. Also, Explorer does things somewhat differently (of course) from all the other browsers, so it&#8217;s necessary to fork the code to account for the irritating little 80-odd percent of the population who use IE.

</p><p>Let&#8217;s build a simple application that accepts input from the user, passes it to some PHP on the server that checks it against a database, and returns the result to the browser. It comes in three parts. First, we need an HTML form. This you&#8217;ve seen before:

</p><p><br />

</p>

 <pre class="brush: js">&lt;html&gt;

 &lt;head&gt;

 &lt;title&gt;Report&lt;/title&gt;

 &lt;script type='text/javascript' src='xhr.js'&gt;&lt;/script&gt; &lt;/head&gt; &lt;body&gt; &lt;form action="fallbackpage.php" method="post"&gt;



 &lt;p&gt;Welcome, student. Please enter your essay here:&lt;textarea name="essay" id="essay"&gt;

 &lt;/textarea&gt; &lt;input type="submit" name="submit" value="Submit" onClick="return

 grade(this.form.essay.value);"&gt;

 &lt;/p&gt;

 &lt;/form&gt;

 &lt;/body&gt;



 &lt;/html&gt;

</pre>

<p><br />

Note that, for users without support for our script (named xhr.js), the form will just submit to the fallback page at fallbackpage.php.

</p><p>Next comes the JavaScript. This is the exciting part, so we&#8217;ll take it slow.

</p>

 <pre class="brush: js"> function grade(essay) {

 </pre>

<p>First, we initialize the object. We have to do it two ways, for different browsers.

</p><p><br />

</p>

 <pre class="brush: js">    // Mozilla version

    if (window.XMLHttpRequest) {

        xhr = new XMLHttpRequest();

    }

    // IE version

    else if (window.ActiveXObject) {

        xhr = new ActiveXObject("Microsoft.XMLHTTP");

    }

 </pre>



<p>Then, we escape the user input to make it URL-safe:

</p>

 <pre class="brush: js">    essay=encodeURIComponent(essay);

 </pre>

<p>and use the <tt>open</tt> method of the object to open a connection to the PHP script:

</p>

 <pre class="brush: js">    xhr.open("POST","grade.php");

 </pre>

<p>The method requires two arguments:first, the HTTP method (GET or POST); second, the URL of the script.

</p><p>A quick HTTP header prepares the script for what it&#8217;s getting, and then the <tt>send</tt> method transmits the actual request:



</p>

 <pre class="brush: js"> xhr.setRequestHeader(

      'Content-Type',

      'application/x-www-form-urlencoded; charset=UTF-8'); xhr.send(essay); </pre>

<p>This last step isn&#8217;t necessary for GET requests, wherein all the data can be contained in the query string of the URL.

</p><p><br />

</p>

<a name="Getting_Results"></a><h3> <span class="mw-headline">Getting Results</span></h3>

<p>Now we&#8217;re ready to see if the HTTP request worked. The <tt>readyState</tt> property counts up from zero during the request, and shows 4 when the server page has loaded successfully.

</p>

 <pre class="brush: js"> xhr.onreadystatechange=function() {

      if (xhr.readyState==4) {

 </pre>



<p>If the request worked, then we can get the output of the server-side script by querying the <tt>responseText</tt> property, which contains a string. For more complex server script output, a <tt>responseXML</tt> property, which can hold a full document object of XML data, is also available.

</p>

 <pre class="brush: js">      grade = xhr.responseText;

      alert ("Nice essay. Your grade is " + grade);

    }

    return false;

 }

 </pre>

<p>Want to see all that in a pastable block? Here it is in a <a href="http://www.wired.com/wired/webmonkey/stuff/Ajax_for_Beginners_code1.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/Ajax_for_Beginners_code1.html" rel="nofollow">separate file</a>.

</p><p>Finally, the third component is the PHP script, which lives on the server and waits patiently for the JavaScript to pass it some juicy data. This example uses PHP, but any language you like &#8212; Ruby, Perl, C, ASP &#8212; can do as well. The core of this example script is a natural-language function called <tt>grade_essay()</tt> that grades student essays from 1 to 100, but I will redact that part to conserve space.



</p>

 <pre class="brush: js"> &lt;?php

 function grade_essay($essay) {

      return strlen($essay);

 }

 $essay = urldecode(implode(file('php://input')));

 $grade = grade_essay($essay);

 echo $grade;

 ?&gt;



 </pre>

<p>The <tt>php://input</tt> grabs the POST data, which gets put into a string, decoded and passed to the ingenious grading algorithm. The algorithm returns a numeric grade. Lastly, we just output the grade with <tt>echo</tt>  &#8211;  ordinarily, this would display in the browser, but since the PHP script is running &#8220;behind the scenes,&#8221; the string output is simply returned to the JavaScript that called it. If you need structured data, an XML document would be output with an <tt>echo</tt> statement in just the same way, but the content-type of the output page must be set to <tt>text/xml</tt>.



</p><p>What the user sees is this:She types her essay into the text area in the browser, clicks Submit, and within instants an alert box pops up giving her a final grade on the essay. Invisibly, the essay has been sent to the server, read and evaluated by a team of PHP gnomes, and returned with a grade, without ever reloading the page. The user can modify her essay and resubmit it endlessly.

</p><p>And that&#8217;s the gist of the almost magical XMLHttpRequest object! The example is simple, but the uses of the object can be elaborately, multifariously clever. If you need further inspiration and edification, a burgeoning number of examples are dotted around the Web:

</p>

<ul><li> Ajax-powered start pages like <a href="http://www.google.com/ig" class="external text" title="http://www.google.com/ig" rel="nofollow">iGoogle</a>, <a href="http://www.pageflakes.com/" class="external text" title="http://www.pageflakes.com/" rel="nofollow">Pageflakes</a> and <a href="http://www.netvibes.com/" class="external text" title="http://www.netvibes.com/" rel="nofollow">Netvibes</a>

</li></ul>

<ul><li> Social news site <a href="http://digg.com" class="external text" title="http://digg.com" rel="nofollow">Digg</a>



</li></ul>

<ul><li> Movie rentals site <a href="http://www.netflix.com" class="external text" title="http://www.netflix.com" rel="nofollow">Netflix</a>

</li></ul>

<p><br />

But what data you send and receive with Ajax is up to you.

</p><p><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/ajax_for_beginners/feed/</wfw:commentRss>
        <slash:comments>8</slash:comments>

        
    </item>
    
    <item>
        <title>Mulders Stylesheets Tutorial &#8211; Lesson 3</title>
        <link>http://www.webmonkey.com/2010/02/mulders_stylesheets_tutorial_-_lesson_3/</link>
        <comments>http://www.webmonkey.com/2010/02/mulders_stylesheets_tutorial_-_lesson_3/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=614</guid>
        		<category><![CDATA[CSS]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Lesson 2 of our stylesheets tutorial was all about fonts and controlling text. This lesson is about how those words and lines can be spaced relative to one another. These stylesheets properties give us power over the space between words and letters, the leading (vertical spacing) between lines of text, and the alignment of text, [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p><a href="/2010/02/Mulders_Stylesheets_Tutorial_-_Lesson_2" title="Tutorial:Mulders Stylesheets Tutorial - Lesson 2"> Lesson 2</a> of our stylesheets tutorial was all about fonts and controlling text. This lesson is about how those words and lines can be spaced relative to one another. These stylesheets properties give us power over the space between words and letters, the leading (vertical spacing) between lines of text, and the alignment of text, margins and padding, borders, and floating elements.

</p><p>Here&#8217;s what we&#8217;ll be covering:

</p>

<ul><li> <tt>word-spacing</tt>

</li><li> <tt>letter-spacing</tt>



</li><li> <tt>line-height</tt>

</li><li> <tt>text-align</tt>

</li><li> <tt>vertical-align</tt>

</li><li> <tt>text-indent</tt>

</li><li> <tt>margin-top</tt>, <tt>margin-left</tt>, etc.



</li><li> <tt>padding-top</tt>, <tt>padding-left</tt>, etc.

</li><li> <tt>border-width</tt>, <tt>border-color</tt>, <tt>border-style</tt>, etc.

</li><li> <tt>float</tt>

</li><li> <tt>clear</tt>



</li></ul>

<p><br />

Obviously we have a lot to do in this lesson, so we&#8217;re going to speed up a bit. Let&#8217;s go!

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

<table id="toc" class="toc" summary="Contents"><tbody><tr><td><div id="toctitle"><h2>Contents</h2> </div>

<ol>

<li><a href="#Spacing_Words_and_Letters">Spacing Words and Letters</a></li>

<li><a href="#Spacing_Between_Lines">Spacing Between Lines</a></li>



<li><a href="#Aligning_and_Indenting_Text">Aligning and Indenting Text</a></li>

<li><a href="#Margins_and_Padding">Margins and Padding</a></li>

<li><a href="#Borders">Borders</a></li>

<li><a href="#You_can_apply_borders_to_replaced_elements_as_well_as_to_text_elements._Fun.2C_eh.3F">You can apply borders to replaced elements as well as to text elements. Fun, eh?</a></li>

<li><a href="#Floating_Stuff">Floating Stuff</a></li>



<li><a href="#Lesson_3_Exercise">Lesson 3 Exercise</a></li>

<li><a href="#Review_of_Lesson_3">Review of Lesson 3</a></li>

</ol>

</td></tr></tbody></table>

<a name="Spacing_Words_and_Letters"></a><h4> <span class="mw-headline">Spacing Words and Letters</span></h4>

<p>First up is a pair of properties that enables you to do things you can&#8217;t do with HTML tags:control the spacing between words and the spacing between individual characters.

</p><p><b>word-spacing</b>



</p><p>With the <tt>word-spacing</tt> property, you can add additional space between words:

</p>

<pre class="brush: js">H3 { word-spacing:1em }</pre>

<p>The value you specify will be added to whatever default value the browser already uses. You can use any of the length units we talked about in Lesson 2 when looking at <tt>font-size</tt>:

</p>

<ul><li> <tt>in</tt> (inches)

</li><li> <tt>cm</tt> (centimeters)



</li><li> <tt>mm</tt> (millimeters)

</li><li> <tt>pt</tt> (points)

</li><li> <tt>pc</tt> (picas)

</li><li> <tt>em</tt> (ems)

</li><li> <tt>ex</tt> (x-height)



</li><li> <tt>px</tt> (pixels)

</li></ul>

<p><br />

Here&#8217;s <span style="word-spacing: 1em;">word-spacing</span> in action:

</p><p><span style="word-spacing: 1.5em;">Behold the power of cheese.</span>

</p><p>Don&#8217;t see anything different? That&#8217;s probably because your browser doesn&#8217;t support this property. Only the Mac version of IE 4 likes <tt>word-spacing</tt>.

</p><p><b>letter-spacing</b>



</p><p>We have better luck with <tt>letter-spacing</tt>, which affects the kerning between characters and works in IE 4 and 5 (but not in Communicator, alas).

</p>

<pre class="brush: js">H3 { letter-spacing:10px } </pre>

<p>The functionality is similar to <tt>word-spacing</tt>:Values are added to the default browser spacing. And you can use any of the same units listed above.

</p><p>If you&#8217;re using IE 4 or 5, here&#8217;s an example:

</p><p><span style="letter-spacing: 10px;">Behold the power of cheese.</span>

</p><p>For both of these properties, you can also use a value of <tt>normal</tt>, which will ensure that the default browser spacing is used instead of any inherited word or letter spacing.

</p><p>Don&#8217;t be too discouraged! There are a lot of stylesheets properties that <i>do</i> work in both of the major browsers. One example is coming up next.



</p>

<a name="Spacing_Between_Lines"></a><h4> <span class="mw-headline">Spacing Between Lines</span></h4>

<p>The common term for the spacing between lines is leading. The common term that Web designers scream when they find out they can now control leading is, &#8220;Wheee!&#8221;

</p><p><b>line-height</b>

</p><p><tt>line-height</tt> is a godsend. With it, we can achieve control over the vertical spacing between lines of text:

</p>

<pre class="brush: js">B { line-height:16pt }  </pre>

<p>Whatever value you use is the amount of space between the baselines of two adjacent lines of text (the baseline is what characters without descenders — &#8220;x&#8221; but not &#8220;y,&#8221; for example &#8211; sit on). Note that your value totally replaces the default browser value.

</p><p>Netscape Communicator and Internet Explorer add the <tt>line-height</tt> value <i>before</i> the line. Thus, if you specify a value of <tt>10px</tt>, then the browsers will display the first line of text 10 pixels down.



</p><p>There are three different ways to give a value to <tt>line-height</tt>:

</p>

<ul><li> by number,

</li><li> by length unit, and

</li><li> by percentage.

</li></ul>

<p><b>Leading by Number</b>

</p>

<pre class="brush: js">B { font-size:12pt; line-height:2 }  </pre>

<p>When you specify <tt>line-height</tt> with a number, the browser uses <tt>font-size</tt> to obtain the leading:It multiplies <tt>font-size</tt> by the number. So in this example, the <tt>line-height</tt> is 24 points, like so:



</p><p><span style="font-size: 12pt; line-height: 24pt;">Four score and seven years ago, the Web wasn&#8217;t yet a glimmer in anyone&#8217;s eye. No one needed it, no one missed it. Eighty-seven years from now, what will people laugh at us for lacking?</span>

</p><p>By the way, you can also use nonintegers (such as 2.3) as values.

</p><p>(You should know that IE 3 doesn&#8217;t support number values. More often than not, using number values with IE 3 will result in a big mess of overlapping text.)

</p><p><b>Leading by Length Unit</b>

</p>

<pre class="brush: js">B { font-size:12pt; line-height:11pt } </pre>

<p>Another way to define <tt>line-height</tt> is by using any of the length units we reviewed on the previous page (<tt>em</tt> and <tt>pt</tt> are most commonly used). Here&#8217;s the above stylesheet rule in action:



</p><p><span style="font-size: 12pt;">Four score and seven years ago, the Web wasn&#8217;t yet a glimmer in anyone&#8217;s eye. No one needed it, no one missed it. Eighty-seven years from now, what will people laugh at us for lacking?</span>

</p><p>Note that you can make lines of text closer together just as easily as you can separate them. It&#8217;s easy with stylesheets!

</p><p><b>Leading by Percentage</b>

</p>

<pre class="brush: js">B { font-size:10pt; line-height:140% }  </pre>

<p>If you want yet another way to use <tt>line-height</tt>, try percentage values. In the above example, the leading is 140 percent of 10 points or 14 points. You get the idea. &lt;/tt&gt;

</p><p><b>Overlapping Text</b>

</p><p>You might have already asked yourself this question:What happens when <tt>line-height</tt> is so small that the lines of text overlap?



</p><p>Well, they overlap, that&#8217;s what. Check out this code:

</p>

<pre class="brush: js">B { font-size:28pt; line-height:2pt }  </pre>

<p>Here&#8217;s what you get:

</p>

<p style="font-size: 28pt; line-height: 2pt;">Whoa<br />

Cool.</p>

<p>&#8220;Whoa&#8221; uses the browser&#8217;s default <tt>line-height</tt>, but &#8220;Cool&#8221; has so little <tt>line-height</tt> that it lies on top of the first line.

</p><p>(Communicator and Internet Explorer interpret <tt>line-height</tt> differently. In Communicator, the text above is overlapped quite a bit. In IE 5, it&#8217;s not overlapped at all.)



</p><p>If you want to overlap elements on your page, <tt>line-height</tt> isn&#8217;t the best way to do it because of browser inconsistencies. In Lesson 5, we&#8217;ll look at the <strong class="selflink">  best ways</strong> to layer text, images, and so on.

</p><p>Now that we can control the spacing of lines of text, let&#8217;s move on and talk about the alignment of entire paragraphs.

</p>

<a name="Aligning_and_Indenting_Text"></a><h4> <span class="mw-headline">Aligning and Indenting Text</span></h4>

<p>The following attributes deal with aligning text and images and adding indentation.

</p><p><b>text-align</b>

</p><p>With the <tt>text-align</tt> property, you can control the horizontal alignment of paragraphs:



</p>

<pre class="brush: js">H4 { text-align:center } </pre>

<p>This property works only on block-level elements, which are tags that define new paragraphs on their own, such as <tt>&nbsp;P&gt;</tt>, <tt>&nbsp;H1&gt;</tt>-<tt>&nbsp;H6&gt;</tt>, <tt>&nbsp;BLOCKQUOTE&gt;</tt>, and <tt>&lt;UL&gt;</tt>.

</p><p>Here are your options:

</p><p>A value of <tt>left</tt> means the element will be left-aligned.



</p><p>A value of <tt>right</tt> means the element will be right-aligned.

</p><p>A value of <tt>center</tt> means the element will be centered.

</p><p>And finally, a value of <tt>justify</tt> means the element will be justified. This is difficult to see without multiple lines of text, so I&#8217;ll add some text here. Note that <tt>justify</tt> works in Communicator (both platforms) and IE 4 and 5 (Windows) but not in IE 3 or 4 (Mac).

</p><p>Until now, we&#8217;ve been talking only about applying stylesheets to text. But many properties can also be used on replaced elements. (A replaced element is any object that is replaced by other content. Graphics are the most common replaced elements, but Java applets and QuickTime movies are also frequently replaced.)

</p><p>So we can also right-align an image, like so:



</p><p><span style="text-align: right;"><a href="http://www.tsdesign.com/mulder/maze/index.html" class="external text" title="http://www.tsdesign.com/mulder/maze/index.html" rel="nofollow"><img src="http://www.wired.com/wired/webmonkey/stuff/enter.gif" alt="enter.gif"></a></span>

</p><p>(Communicator sometimes doesn&#8217;t like it if you apply CSS properties directly to the <tt>&lt;img&gt;</tt> tag. A work-around is to surround <tt>&lt;img&gt;</tt> with <tt>&nbsp;SPAN&gt;</tt> or <tt>&lt;DIV&gt;</tt> and then apply the stylesheet to the <tt>&lt;SPAN&gt;</tt> or <tt>&lt;DIV&gt;</tt> tag instead. <tt>&lt;DIV&gt;</tt> is better, because IE for Windows sometimes has problems associating a style with <tt>&lt;SPAN&gt;</tt>.)



</p><p><b>vertical-align</b>

</p><p>Let me say right off the bat that browser support for <tt>vertical-align</tt> is almost zero. But I will state the basics here, in the hope that later browsers will support it.

</p>

<pre class="brush: js">H4 { vertical-align:top }</pre>

<p>The <tt>vertical-align</tt> attribute enables you to control the vertical placement of text or replaced elements (e.g., images) relative to a parent element. For example, if you <tt>vertical-align</tt> as <tt>top</tt> a 2-by-2-pixel GIF and its parent is <tt>&lt;H1&gt;</tt> text, then that GIF will appear at the top of that line of text.



</p><p>Here are all the possible values for <tt>vertical-align</tt>:

</p>

<ul><li> <tt>top</tt> aligns the top of the element with the tallest parent element on the line.

</li><li> <tt>bottom</tt> aligns the bottom of the element with the lowest parent element on the line.

</li><li> <tt>text-top</tt> aligns the top of the element with the top of the font of the parent element.

</li><li> <tt>text-bottom</tt> aligns the bottom of the element with the bottom of the font of the parent element.



</li><li> <tt>baseline</tt> aligns the baseline of the element with the baseline of the parent element.

</li><li> <tt>middle</tt> aligns the midpoint of the element with the middle of the parent element.

</li><li> <tt>sub</tt> puts the element in subscript.

</li><li> <tt>super</tt> puts the element in superscript.

</li></ul>



<p>The only current browser support for any of this comes from IE 4 and 5, which support the last two values. That&#8217;s it for now.

</p><p><b>text-indent</b>

</p><p>Want to give a paragraph an indent? (After living on the Internet for a while, you may have forgotten what an indent is!) Use the <tt>text-indent</tt> property:

</p>

<pre class="brush: js">P { text-indent:2em }  </pre>

<p>Here you can see the above rule applied. The property works only on block-level elements (as defined earlier on this page). You can specify <tt>text-indent</tt> using any of the familiar length units.&lt;/tt&gt;

</p><p>You can also use percentage values. For example, this paragraph has an indent of 40 percent, which means the first line is indented 40 percent from where it would normally begin. (IE 4 for Windows assumes the percentage refers to the entire browser window, not just the width of the paragraph.)



</p><p>Finally, if you give your <tt>text-indent</tt> a negative value, then you get a so-called hanging indent, in which the first line actually begins left of where it normally would. This paragraph has a <tt>text-indent</tt> of -10 pixels. IE 4 and 5 are a little buggy:They might not display the first few letters.

</p><p>Use your indenting power well, young Jedi knight.

</p><p>Indents are nice, but what about genuine margins? You got it.

</p>

<a name="Margins_and_Padding"></a><h4> <span class="mw-headline">Margins and Padding</span></h4>

<p>As we know, to make a margin using HTML, you have to use tables. But not any more. Stylesheets to the rescue &#8230;

</p><p><b>Some Quick Definitions</b>

</p><p>First, we need to understand the terminology of the stylesheets language. Every single block-level element or replaced element is contained in what the cascading stylesheets creators call a box. That box consists of:



</p>

<ul><li> the element itself,

</li><li> the padding around the element,

</li><li> the border around the padding, and

</li><li> the margin around the border.

</li></ul>

<p>An illustration might help:

</p>

<center><img src="http://www.wired.com/wired/webmonkey/stuff/box.gif" alt="box.gif"></center>

<p>You can control the padding, border, and margin separately, as we&#8217;re about to see.

</p><p><b>margin-top, margin-bottom, margin-left, margin-right</b>

</p><p>These four properties enable you to control the margin around each side of an element, like so:



</p>

<pre class="brush: js">H4 { margin-top:20px; margin-bottom:5px; margin-left:100px; margin-right:55px }  </pre>

<p>As you can see, each margin can be set differently. Or you can choose to set just one margin side and let the browser use its default margin sizes for the other sides. You can apply margins to replaced elements (e.g., graphics) as well as to text.

</p><p>The most obvious way to set margin values is through the length units we discussed previously:<tt>px</tt> (pixels), <tt>pt</tt> (points), and so on. But you can also set margins using percentage values.

</p><p>Let&#8217;s look at a few examples:

</p>

<ul><li> <a href="http://www.wired.com/wired/webmonkey/stuff/margin-top.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/margin-top.html" rel="nofollow"><tt>margin-top</tt> in action</a>



</li><li> <a href="http://www.wired.com/wired/webmonkey/stuff/margin-bottom.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/margin-bottom.html" rel="nofollow"><tt>margin-bottom</tt> in action</a>

</li><li> <a href="http://www.wired.com/wired/webmonkey/stuff/margin-leftright.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/margin-leftright.html" rel="nofollow"><tt>margin-left</tt> and <tt>margin-right</tt> in action</a>

</li></ul>

<p>When two margins meet, the browser adds the margins together. Thus, if this paragraph has a <tt>margin-bottom</tt> of 10 pixels &#8230;



</p><p>&#8230; and if this paragraph has a <tt>margin-top</tt> of 30 pixels, then the paragraphs should be separated by 40 pixels.

</p><p>Can you overlap elements by using negative margin values? You betcha. Once again, this isn&#8217;t the ideal way to layer elements on a page, but it is possible:

</p><p><font face="times, serif"><font size="30">Books</font></font>

</p><p><font face="arial, sans-serif"><b><font size="24"><font color="green">are mind food.</font></font></b><font size="24"><font color="green"></font></font>

</font></p><p><font face="arial, sans-serif">Above, &#8220;are mind food&#8221; has a top margin of -55 pixels and a right margin of 60 pixels.

</font></p><p><font face="arial, sans-serif">A big drawback of using negative margins to overlap elements is that browsers handle margin sizes differently. For instance, when displaying the example above, each of the four main 4.0 browsers (Communicator for PC, Communicator for Mac, IE for PC, IE for Mac) overlaps the text a different amount. (Communicator for PC doesn&#8217;t overlap the text at all!)

</font></p><p><font face="arial, sans-serif">Another drawback is that you can&#8217;t completely control what gets layered on top. Again, different browsers behave differently. Communicator, for example, always places graphics on top of text. IE seems to display elements in the order they are loaded into the browser window.

</font></p><p><font face="arial, sans-serif">In other words, if you want to layer elements, don&#8217;t use negative margins. The Lesson 5 installment of this tutorial will cover how to <a href="/2010/02/Mulders_Stylesheets_Tutorial_-_Lesson_5" title="Tutorial:Mulders Stylesheets Tutorial - Lesson 5">  layer elements</a>.

</font></p><p><font face="arial, sans-serif">Here are some other notes about browser support:



</font></p>

<ul><font face="arial, sans-serif"><li> IE 3 will sometimes display extra space when you use ruler units (e.g., inches and centimeters) for <tt>margin-bottom</tt>. Also, some HTML tags work with <tt>margin-bottom</tt>, but many don&#8217;t.

</li><li> IE 4 sometimes has problems giving left margins to replaced elements such as graphics. Try wrapping the image in a <tt>&lt;DIV&gt;</tt> and styling the <tt>&lt;DIV&gt;</tt>.

</li></font></ul>

<p><font face="arial, sans-serif"><b>padding-top, padding-bottom, padding-left, padding-right</b>



</font></p><p><font face="arial, sans-serif">Padding (the space between the element and its border) works just like margin control. You can define padding size for the top, bottom, left, and right sides of an element.

</font></p>

<pre class="brush: js"><font face="arial, sans-serif">H4 { padding-top:20px; padding-bottom:5px; padding-left:100px; padding-right:55px } </font></pre>

<p><font face="arial, sans-serif">Just as with margins, you can use any length units or percentage values. We won&#8217;t bother to go into detailed examples, since these properties work so similarly to the margin properties. You should know, however, that you can&#8217;t use negative values for padding as you can for margins. (Also, I&#8217;m sorry to report that IE 3 doesn&#8217;t support the padding properties.)

</font></p><p><font face="arial, sans-serif">Now let&#8217;s talk about what&#8217;s between margins and padding:borders.

</font></p>

<font face="arial, sans-serif"><a name="Borders"></a></font><h4><font face="arial, sans-serif"> <span class="mw-headline">Borders</span></font></h4>

<p><font face="arial, sans-serif">Quite a few different stylesheets properties relate to putting a border around an element on a Web page.

</font></p><p><font face="arial, sans-serif">(Red alert! IE 3 doesn&#8217;t support any of the border properties discussed on this page — just so you know.)

</font></p><p><font face="arial, sans-serif"><b>border-top-width, border-bottom-width, border-left-width, border-right-width</b>

</font></p><p><font face="arial, sans-serif">The first thing you can control is the width of the border, and you can control each side separately:

</font></p>

<pre class="brush: js"><font face="arial, sans-serif">H4 { border-top-width:2px; border-bottom-width:5px; border-left-width:1px; border-right-width:1px }  </font></pre>



<p><font face="arial, sans-serif">Here&#8217;s the result of the above CSS rule:

</font></p>

<font face="arial, sans-serif"><a name="You_can_apply_borders_to_replaced_elements_as_well_as_to_text_elements._Fun.2C_eh.3F"></a></font><h4 style="border-style: solid; border-width: 2px 1px 5px;"><font face="arial, sans-serif"> <span class="mw-headline">You can apply borders to replaced elements as well as to text elements. Fun, eh?</span></font></h4>

<p><font face="arial, sans-serif"><br />

</font></p>

<p style="border-style: solid; border-width: 0px 0px 0px 10px;"><font face="arial, sans-serif">You don&#8217;t necessarily have to define a border for all sides of an element. If you want, you can put a border on just one side, as seen to the left of this paragraph. (In IE 4 and 5, you need to define the other sides as 0 or else the browser will give them its own idea of size.)</font></p>

<p><font face="arial, sans-serif">For specifying width, you can use any of the same length values we&#8217;ve seen before. You can also use some built-in keywords:

</font></p>

<p style="border-style: solid; border-width: thin 0px 0px;"><font face="arial, sans-serif">The border above this text has a value of <tt><font color="#009900" size="3">thin</font></tt>.</font></p>

<p style="border-style: solid; border-width: medium 0px 0px;"><font face="arial, sans-serif">The border above this text has a value of <tt><font color="#009900" size="3">medium</font></tt>.</font></p>



<p style="border-style: solid; border-width: thick 0px 0px;"><font face="arial, sans-serif">The border above this text has a value of <tt><font color="#009900" size="3">thick</font></tt>.</font></p>

<p><font face="arial, sans-serif">Do you want all sides of your border to be the same width? Simply use the shortcut <tt>border-width</tt> tag. The following stylesheets rule would put an even 1-inch border all the way around the graphic:

</font></p>

<pre class="brush: js"><font face="arial, sans-serif">img { border-width:1in }

</font></pre>

<p><font face="arial, sans-serif"><b>border-color</b>

</font></p><p><font face="arial, sans-serif">The second aspect of borders that is under your control is color.

</font></p><p><font face="arial, sans-serif">P { border-color:green; border-width:3px }

</font></p>

<p style="border: 3px solid green;"><font face="arial, sans-serif">This paragraph shows the above code in action.</font></p>



<p><font face="arial, sans-serif">You can use the color names browsers already recognize or, better yet, you can use hexadecimal values, like so:

</font></p>

<pre class="brush: js"><font face="arial, sans-serif">H4 { border-color:#FF0033; border-width:thick }  </font></pre>

<p><font face="arial, sans-serif">If you want each side of your border to be a different color, you can make it so by listing each color:

</font></p>

<pre class="brush: js"><font face="arial, sans-serif">P { border-color:#666699 #FF0033 #000000 #FFFF99; border-width:3px }  </font></pre>

<p><font face="arial, sans-serif">The browser uses the first color value for the top side, the second for the right side, the third for the bottom, and the fourth for the left.

</font></p>

<p style="border-style: solid; border-color: rgb(102, 102, 153) rgb(255, 0, 51) rgb(0, 0, 0) rgb(255, 255, 153); border-width: 3px;"><font face="arial, sans-serif">This paragraph shows the above code in action.</font></p>

<p><font face="arial, sans-serif">Note:Communicator doesn&#8217;t recognize multiple colors, so you&#8217;re stuck with just one. (When multiple colors are used, Communicator often uses blue for the whole border. We have no idea why.)

</font></p><p><font face="arial, sans-serif">By the way, if <tt>border-color</tt> isn&#8217;t used, then the border will take on the color of the element itself.



</font></p><p><font face="arial, sans-serif"><b>border-style</b>

</font></p><p><font face="arial, sans-serif">Finally, you can specify the style of the border line:

</font></p>

<pre class="brush: js"><font face="arial, sans-serif">P { border-style:double; border-width:3px } </font></pre>

<p><font face="arial, sans-serif">The possible keywords are:

</font></p>

<p style="border: 4px solid green;"><font face="arial, sans-serif">solid</font></p>

<p style="border: 4px double green;"><font face="arial, sans-serif">double</font></p>

<p style="border: 4px dotted green;"><font face="arial, sans-serif">dotted</font></p>

<p style="border: 4px dashed green;"><font face="arial, sans-serif">dashed</font></p>

<p style="border: 4px groove green;"><font face="arial, sans-serif">groove</font></p>



<p style="border: 4px ridge green;"><font face="arial, sans-serif">ridge</font></p>

<p style="border: 4px inset green;"><font face="arial, sans-serif">inset</font></p>

<p style="border: 4px outset green;"><font face="arial, sans-serif">outset</font></p>

<p><font face="arial, sans-serif">Note:You <i>have</i> to use <tt>border-style</tt> with IE 4 and 5, or they won&#8217;t display any border at all.

</font></p><p><font face="arial, sans-serif">IE 4.x for the Mac is the only browser to support <tt>dotted</tt> and <tt>dashed</tt>.



</font></p><p><font face="arial, sans-serif">Another thing you might notice is that IE gives a border to the entire width of the area, whereas Navigator gives a border only to the word itself.

</font></p><p><font face="arial, sans-serif">If you so desire, you can also set border styles individually for each side (though I have no idea why you&#8217;d want to do so). As with <tt>border-color</tt>, you declare the values in this order:top side, right side, bottom side, left side.

</font></p><p><font face="arial, sans-serif">And that about does it for borders. We have one more topic to look at in this lesson:floating elements.

</font></p>

<font face="arial, sans-serif"><a name="Floating_Stuff"></a></font><h4><font face="arial, sans-serif"> <span class="mw-headline">Floating Stuff</span></font></h4>

<p><font face="arial, sans-serif">We&#8217;re already used to seeing floating images and tables on Web pages. Simply use the <tt>ALIGN=left</tt> attribute on an <tt>&lt;img&gt;</tt> tag, for example, and text will flow around the right side of the floating image. Stylesheets have a somewhat more flexible syntax for floating elements, which is what this page is all about.

</font></p><p><font face="arial, sans-serif">(I&#8217;m sorry to report that Internet Explorer 3 doesn&#8217;t support anything on this page. IE 4 and 5 can be a bit buggy too.)



</font></p><p><font face="arial, sans-serif"><b>float</b>

</font></p><p><font face="arial, sans-serif">The <tt>float</tt> property enables you to flow text around an element, including not just images but any block-level text as well.

</font></p>

<pre class="brush: js"><font face="arial, sans-serif">H4 { float:left }  </font></pre>

<div style="float: left;"><font face="arial, sans-serif">This text is floating left.</font></div><font face="arial, sans-serif"> </font><div><font face="arial, sans-serif">To the left you can see this CSS rule applied to some <tt>&lt;H4&gt;</tt> text. This paragraph simply wraps around it, much like you&#8217;d expect text to wrap around an image aligned left. Of course, you can also use a value of <tt>right</tt>.</font></div>



<p><font face="arial, sans-serif">If the floating element has too little space around it, you can add padding with one of the properties we discussed earlier in this lesson. (For some reason, using margins seems to cause trouble.)

</font></p><p><font face="arial, sans-serif"><b>clear</b>

</font></p><p><font face="arial, sans-serif">What if you want to wrap one paragraph around a floating element but make sure the next paragraph doesn&#8217;t wrap? Use the <tt>clear</tt> property, much like you&#8217;d use the <tt>CLEAR</tt> attribute in HTML (for example:<tt>CLEAR=right</tt>).

</font></p>

<pre class="brush: js"><font face="arial, sans-serif">P { clear:left }  </font></pre>

<p><font face="arial, sans-serif">Let&#8217;s look at a quick example:

</font></p><p><span style="float: left;"><font face="arial, sans-serif"><img src="http://cache.valleywag.com/images/thumbs/b2a4c852b28b930d6f2a590e7a7821aa.jpg" alt="b2a4c852b28b930d6f2a590e7a7821aa.jpg"></font></span><font face="arial, sans-serif"> This is one paragraph that is wrapping around an image that&#8217;s floating left.



</font></p><p><font face="arial, sans-serif">This is another paragraph. Without any <tt>clear</tt> property, it also wraps, as you can see.<br clear="all">

</font></p><p><font face="arial, sans-serif">And here&#8217;s what happens if we use <tt>clear</tt>

</font></p><p><span style="clear: left;"><font face="arial, sans-serif"><img src="http://cache.valleywag.com/images/thumbs/b2a4c852b28b930d6f2a590e7a7821aa.jpg" alt="b2a4c852b28b930d6f2a590e7a7821aa.jpg"></font></span><font face="arial, sans-serif"> This is one paragraph that is wrapping around an image that&#8217;s floating left.

</font></p><p><font face="arial, sans-serif">This is another paragraph. Now I&#8217;ve set <tt>clear:left</tt>, so the browser makes sure that the left side is clear of all floating elements before it displays the paragraph.

</font></p><p><font face="arial, sans-serif">You can also use values of <tt>right</tt> and <tt>both</tt>.



</font></p><p><font face="arial, sans-serif">Congrats, you&#8217;ve made it through the bulk of Lesson 3. Let&#8217;s walk the walk.

</font></p>

<font face="arial, sans-serif"><a name="Lesson_3_Exercise"></a></font><h4><font face="arial, sans-serif"> <span class="mw-headline">Lesson 3 Exercise</span></font></h4>

<p><font face="arial, sans-serif"><a href="http://www.wired.com/wired/webmonkey/stuff/3-exercise.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/3-exercise.html" rel="nofollow">Look at this page</a> and try to rebuild it yourself without looking at the code. Remember that you must have at least a 4.0 browser for the examples to work correctly. It uses several of the stylesheets properties we&#8217;ve discussed in this lesson (as well as a few from <a href="/2010/02/Mulders_Stylesheets_Tutorial_-_Lesson_2" title="Tutorial:Mulders Stylesheets Tutorial - Lesson 2"> Lesson 2</a>). There&#8217;s only one image on the page — the rest is HTML and cascading stylesheets.

</font></p><p><font face="arial, sans-serif">(Note:Because different browsers behave differently, the example page will look different from browser to browser.)

</font></p><p><font face="arial, sans-serif">Bonus Question:How can you make a drop-shadow effect using just CSS and HTML, with no GIFs whatsoever? Tune in for the answer tomorrow.

</font></p><p><font face="arial, sans-serif">Before we end this lesson, let&#8217;s review.

</font></p>

<font face="arial, sans-serif"><a name="Review_of_Lesson_3"></a></font><h4><font face="arial, sans-serif"> <span class="mw-headline">Review of Lesson 3</span></font></h4>



<p><font face="arial, sans-serif">This lesson was a good one. We expanded our cascading stylesheets toolbox to include the realm of typography and layout, where the spacing and alignment of text and images are under our control. It&#8217;s a wondrous land, because in it we can do things that simply aren&#8217;t possible now with plain ol&#8217; HTML tags.

</font></p><p><font face="arial, sans-serif">Here are the stylesheets properties we covered:

</font></p>

<ul><font face="arial, sans-serif"><li> <tt>word-spacing</tt> defines the space between words.

</li><li> <tt>letter-spacing</tt> controls the kerning or space between individual characters.

</li><li> <tt>line-height</tt> is the key to leading, the vertical space between lines of text.

</li><li> <tt>text-align</tt> enables you to left-align, right-align, center, or justify paragraphs.



</li><li> <tt>vertical-align</tt> is for vertically aligning text.

</li><li> <tt>text-indent</tt> can give indents to paragraphs.

</li><li> All the <tt>margin</tt> properties specify margins surrounding text blocks, images, and so on.

</li><li> And the <tt>padding</tt> properties are for padding.



</li><li> The <tt>border</tt> properties define the width, color, and style of borders.

</li><li> <tt>float</tt> and <tt>clear</tt> are for controlling how elements wrap around one another.

</li></font></ul>

<p><font face="arial, sans-serif">Mulder, can there be more to salivate over in this magical realm of cascading stylesheets? Yes indeed. In Lesson 4, we&#8217;ll examine the power stylesheets give us over colors and backgrounds. Don&#8217;t miss it. <span id="title_name_el" class="wm_hidden_meta_class" title="Mulder's Stylesheets Tutorial  Lesson 3" style="visibility: hidden;"> <span id="page_path_el" class="wm_hidden_meta_class" title="http://www.wired.com/wired/webmonkey/stuff/Mulder/" style="visibility: hidden;"> <span id="author_el" class="wm_hidden_meta_class" title="mulder" style="visibility: hidden;"> <span id="creation_date_el" class="wm_hidden_meta_class" title="1999-09-15T24:00:00Z" style="visibility: hidden;"> </span></span></span></span>



</font></p>

<div id="series">

<div class="series_hdr"><font face="arial, sans-serif">From the series</font></div>

<table style="background: rgb(229, 249, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" width="620">

<tbody><tr>

<td>

<p><a href="/2010/02/Mulders_Stylesheets_Tutorial" title="Tutorial:Mulders Stylesheets Tutorial">Tutorial:Mulders Stylesheets Tutorial</a><br />

<a href="/2010/02/Mulders_Stylesheets_Tutorial_-_Lesson_1" title="Tutorial:Mulders Stylesheets Tutorial - Lesson 1">Tutorial:Mulders Stylesheets Tutorial &#8211; Lesson 1</a><br />

<a href="/2010/02/Mulders_Stylesheets_Tutorial_-_Lesson_2" title="Tutorial:Mulders Stylesheets Tutorial - Lesson 2">Tutorial:Mulders Stylesheets Tutorial &#8211; Lesson 2</a><br />

<strong class="selflink">Tutorial:Mulders Stylesheets Tutorial &#8211; Lesson 3</strong><br />

<a href="/2010/02/Mulders_Stylesheets_Tutorial_-_Lesson_4" title="Tutorial:Mulders Stylesheets Tutorial - Lesson 4">Tutorial:Mulders Stylesheets Tutorial &#8211; Lesson 4</a><br />



<a href="/2010/02/Mulders_Stylesheets_Tutorial_-_Lesson_5" title="Tutorial:Mulders Stylesheets Tutorial - Lesson 5">Tutorial:Mulders Stylesheets Tutorial &#8211; Lesson 5</a><br />

</p>

</td></tr></tbody></table>

</div><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/mulders_stylesheets_tutorial_-_lesson_3/feed/</wfw:commentRss>
        <slash:comments>0</slash:comments>

        
    </item>
    
    <item>
        <title>JavaScript Tutorial &#8211; Lesson 1</title>
        <link>http://www.webmonkey.com/2010/02/javascript_tutorial_-_lesson_1/</link>
        <comments>http://www.webmonkey.com/2010/02/javascript_tutorial_-_lesson_1/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=707</guid>
        		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Multimedia]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Interactivity, shminteractivity. Most web pages that claim interactivity really mean you can click on hyperlinks to go to new pages. Even web pages that have CGI scripts behind them don&#8217;t really seem all that interactive: Fill out a form, hit the Submit button, and wait. It&#8217;s more like throwing bottles into an ocean and hoping [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>Interactivity, shminteractivity. Most web pages that claim interactivity really mean you can click on hyperlinks to go to new pages. Even web pages that have CGI scripts behind them don&#8217;t really seem all that interactive: Fill out a form, hit the Submit button, and wait. It&#8217;s more like throwing bottles into an ocean and hoping for a meaningful reply.

</p><p>Happily, we have JavaScript. With JavaScript, images can <a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/image_swap.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/image_swap.html" rel="nofollow">swap</a> when you move a cursor over them, form elements can <a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/form_fun.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/form_fun.html" rel="nofollow">influence each other</a> on the fly, and <a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/calculations.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/calculations.html" rel="nofollow">calculations</a> can be made without having to resort to a CGI script. There&#8217;s none of this submit-and-wait stuff &#8212; everything happens on your web page while you&#8217;re playing with it.



</p><p>One of the best things about JavaScript is that you can do a great deal with very little programming. You don&#8217;t need a fancy computer, you don&#8217;t need any software other than a word processor and a web browser, and you don&#8217;t need access to a web server; you can do all your work right on your own computer.

</p><p>Even though it&#8217;s simple to work with, JavaScript is a complete programming language, so as you learn more complicated JavaScript, you&#8217;re also learning the basics of computer programming. If you want to move on to other programming languages, like Perl, C, C++, or Java, JavaScript is a great introduction.

</p><p>Enough hype about JavaScript. On to hype about this tutorial.

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

<a name="All_About_This_Tutorial"></a><h3> <span class="mw-headline">All About This Tutorial</span></h3>

<p>This five-part tutorial aims to get you writing useful JavaScripts immediately. And not just silly JavaScripts &#8212; this tutorial will teach you how to build the browser of your dreams. As we go through the examples in the course, you will build a fancier and fancier browser that you can tweak to your heart&#8217;s content. Tweaking is the Webmonkey way, after all.

</p><p>Here&#8217;s a brief outline of what you will learn each day, with an example of what you&#8217;ll be able to do by the end of that lesson.

</p>

<ul><li> Day 1: Introductions, some examples, and your first JavaScript (<a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/JST_homework1.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/JST_homework1.html" rel="nofollow">example</a>)

</li><li> Day 2: Variables, if-then branching, link events, and image swaps

</li><li> Day 3: Windows, frames, and the Document Object Model



</li><li> Day 4: Loops, arrays, and functions

</li><li> Day 5: Forms, forms, and more forms

</li></ul>

<p><br />

Before we jump in, here are few important things to note about JavaScript and this tutorial.

</p><p>First, JavaScript is not <a href="http://www.sun.com/java" class="external text" title="http://www.sun.com/java" rel="nofollow">Java</a>.

</p><p>Second, sometimes JavaScript isn&#8217;t JavaScript! It turns out that different browsers deal with JavaScript differently. In fact, different versions of the <i>same</i> browser handle JavaScript differently. So always double-check your JavaScripted pages on as many different browsers (or even platforms) as possible.

</p><p>Third, this tutorial is not a substitute for a good reference book. JavaScript is very rich, and although you&#8217;ll learn most of the grammar of JavaScript here, you won&#8217;t learn the entire language. So, if you like what you&#8217;ve learned here and are serious about writing your own JavaScripts, go out and get a book. Whatever book you get should have an extensive reference section. I suggest <i><a href="http://www.oreilly.com/catalog/9780596000486/" class="external text" title="http://www.oreilly.com/catalog/9780596000486/" rel="nofollow">JavaScript: The Definitive Guide</a></i> by David Flanagan, or, ahem, Dave Thau&#8217;s <i><a href="http://nostarch.com/frameset.php?startat=js" class="external text" title="http://nostarch.com/frameset.php?startat=js" rel="nofollow">The Book of Javascript: A Practical Guide to Interactive Web Pages</a>.</i>



</p><p>Fourth, view source! The best way to learn JavaScript is to look at scripts other people have written. JavaScript, just like HTML, can be viewed by selecting View Source on your browser. Do it frequently!

</p><p>Finally, as with HTML, the best way to learn JavaScript is to experiment freely and often. At several places in this tutorial, you&#8217;ll be given the opportunity to try things out. Don&#8217;t be afraid to expand beyond the exercise to try new things.

</p><p>All right, enough with the disclaimers. Let&#8217;s write some JavaScript.

</p>

<a name="Down_to_Business"></a><h3> <span class="mw-headline">Down to Business</span></h3>

<p><a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/firstexample.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/firstexample.html" rel="nofollow">Click here</a> to see an example of JavaScript in action!

</p><p>If you view source, you&#8217;ll see something that looks like this:

</p>

<pre class="brush: js">&lt;html&gt;

&lt;head&gt;

&lt;title&gt;



Thau's JavaScript Tutorial

&lt;/title&gt;



&lt;script language="JavaScript"&gt;



// put up an alert box, to show how they work



alert("Soon, I will rebuild my browser!");

&lt;/script&gt;



&lt;/head&gt;

</pre>

<p>Here are the key things to notice:JavaScript usually goes between the &lt;/title&gt; tag and the &lt;/head&gt; tag. Like HTML, JavaScript is just text that can be typed into a word processor. It goes right into the HTML that describes your page. (Although I&#8217;ve only shown JavaScript in the header of the HTML page, you can also put JavaScript in the body. You&#8217;ll see an example of this in the next lesson.)



</p><p>The beginning of a bit of JavaScript begins with <code>&lt;script language="JavaScript"&gt;</code>

</p><p>Right now, you don&#8217;t really have to put the <code>language="JavaScript"</code> element in there because JavaScript is the default script language for all browsers. However, this could change, so it&#8217;s a good idea to include the language element.

</p><p>Everything between <code>//</code> and the end of a line is a comment and will be ignored.

</p><p>Comment, comment, comment! A basic rule of good programming style is that you should always think about the next person who has to look at your script. It might be a friend, a co-worker, an employer, or it could be you in three months.

The easiest way to make sure you&#8217;ll understand your own script in three months is to comment freely and often. If you want to comment a huge block of text, you can put it between <code>/*</code> and <code>*/</code> like this:



</p>

<pre class="brush: js">/* this is



a huge block



of text that I've



commented out */

</pre>

<p><code>alert("Soon, I will rebuild my browser!");</code> calls up a simple dialog box with the words &#8220;Soon, I will rebuild my browser!&#8221; inside.

</p><p>Here&#8217;s your first piece of JavaScript:the alert method. You&#8217;ll learn more about how this line works in the next lesson. For now, you just need to know that you should end it with a semicolon, and put the text you want in the alert box between quotes.

</p><p>The beginning of a bit of JavaScript begins with &lt;script language=&#8221;JavaScript&#8221;&gt; tag. No rocket science here. Easy as HTML. Simple, right? Well &#8230; actually, there&#8217;s one complication.

</p>

<a name="Hiding_JavaScript"></a><h3> <span class="mw-headline">Hiding JavaScript</span></h3>

<p><em>The following discussion on hiding JavaScript is obsolete since all modern browsers understand the <code>&lt;script&gt;</code> tag.  Further, using this technique to hide a script is NOT XHTML compliant.  It is, however, an interesting (historical) hack that&#8217;s worth a read.</em>



</p><p>The problem with the last example is that some old browsers don&#8217;t understand the <code>&lt;script&gt;</code> tag. These browsers will treat your JavaScript just like HTML, so the page will come out like this:

</p>

<pre class="brush: js">//put up an alert box, to show how they work



alert("Soon, I will rebuild my browser!");



'''Congratulations!'''

</pre>

<p>Which isn&#8217;t great. Luckily, there&#8217;s a trick involving HTML comments:

</p>

<pre class="brush: js">&lt;html&gt;



&lt;head&gt;



&lt;title&gt; blah blah blah &lt;/title&gt;



&lt;script language="JavaScript"&gt;



&lt;!-- hide this stuff from other browsers



YOUR SCRIPT HERE



// end the hiding comment --&gt;



&lt;/script&gt;



&lt;/head&gt;



&lt;body&gt;



etc., etc., etc.



</pre>

<p>The reasons why this trick works evaded me for a while, and you can use it without understanding why it works. However, if you really want to know, <a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/comment_trick.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/comment_trick.html" rel="nofollow">here&#8217;s why the comment trick works</a>.

</p><p>OK, believe it or not, you&#8217;re ready for your <a href="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/JST_homework1.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/javascript_tutorial_files/JST_homework1.html" rel="nofollow">first JavaScript exercise</a>.

</p><p>Once you&#8217;ve conquered that assignment, take a minute to read our review of Lesson 1.

</p><p>OK! You&#8217;re well on your way to understanding JavaScript. Here&#8217;s a quick review of what was covered today:

</p>

<ul><li> The greatness of JavaScript

</li><li> Browser-compatibility problems

</li><li> Other ways to learn JavaScript

</li><li> Where JavaScript goes on a page



</li><li> How to comment (freely and often!)

</li><li> Hiding your JavaScript from unsavvy browsers

</li><li> How alert boxes work

</li></ul>

<p><br />

Today was just an introduction to give you a feel for how things work. Next time we&#8217;ll start getting serious.

</p><p>Topics for next time:

</p>

<ul><li> What sorts of information JavaScript knows about

</li><li> How JavaScript stores that information

</li><li> How JavaScript decides what to do



</li><li> How to do those nifty image swaps

</li></ul>

<p><br />

Ready? Then on to <a href="/2010/02/JavaScript_Tutorial_-_Lesson_2" title="Tutorial:JavaScript Tutorial - Lesson 2">

 Lesson 2</a>!

</p><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/javascript_tutorial_-_lesson_1/feed/</wfw:commentRss>
        <slash:comments>5</slash:comments>

        
    </item>
    
    <item>
        <title>Set Up IMAP on Your Mail Server</title>
        <link>http://www.webmonkey.com/2010/02/set_up_imap_on_your_mail_server/</link>
        <comments>http://www.webmonkey.com/2010/02/set_up_imap_on_your_mail_server/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=802</guid>
        		<category><![CDATA[Programming]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[My friend remarked the other day that if a life can be said to have a killer app, peer-to-peer file sharing is his. Well, e-mail is mine. It is the key conduit for my work, entertainment, hobbies, relations with family and friends, and all sorts of other activities. But as I come to rely on [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>My friend remarked the other day that if a life can be said to have a killer app, peer-to-peer file sharing is his. Well, e-mail is mine. It is the key conduit for my work, entertainment, hobbies, relations with family and friends, and all sorts of other activities. But as I come to rely on it more and more, its shortcomings are magnified, and my patience for them diminished.

</p><p>I am endlessly irritated by the inelegances of POP e-mail. When I&#8217;m forced to use other people&#8217;s computers, or just when I switch from one laptop to another, I want all my e-mail, fifteen years&#8217; worth, received as well as sent, to be right there at my fingertips, neatly categorized. If I have to stop in at a public web terminal and send an urgent message to my date for the evening, I want the message I send to be archived with the rest of my sent mail.

</p><p>A year or so ago, I decided I had had enough. The old method of checking e-mail with a POP client at home, and stopping in to use <a href="http://mail2web.com/" class="external text" title="http://mail2web.com/" rel="nofollow">Mail2Web</a> or another public, on-the-road interface just wasn&#8217;t doing it for me. I wanted a central repository for all my e-mail, accessible easily from anywhere. After a perusal of the services that were available, I reached the conclusion that the amount of storage space and the functionality I desired would incur too high monthly cost. I took matters into my own hands.

</p><p>Using an old Pentium box I had lying around, I tried out a few different configurations and possibilities, and eventually wound up with the system I wanted. Now, with that machine (which I named Potto) as a mail drop, I can access my e-mail &#8212; all my e-mail through history &#8212; from anywhere, using any mail client I like. There is also a handy web interface for checking e-mail from public terminals like the <a href="http://www.apple.com/retail/" class="external text" title="http://www.apple.com/retail/" rel="nofollow">Apple store</a>. And I even hacked together a hybrid interface so I can call up and have a Stephen-Hawking-a-like <i>read</i> me my e-mail over the phone! But that&#8217;s another story, and shall be told another time.



</p><p>What follows is the story of how I changed my e-mail life, and the e-mail lives of several friends, by hosting my own e-mail, and theirs, at home. In a broom closet! And how you can do the same.

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

<table id="toc" class="toc" summary="Contents"><tbody><tr><td><div id="toctitle"><h2>Contents</h2> </div>

<ol>

<li><a href="#The_Basics_of_Mail_Hosting">The Basics of Mail Hosting</a></li>

<li><a href="#Getting_the_Mail">Getting the Mail</a></li>



<li><a href="#POP_Versus_IMAP">POP Versus IMAP</a>

<ol>

<li><a href="#List_of_IMAP_Server_Software">List of IMAP Server Software</a></li>

</ol>

</li>

<li><a href="#Installing_UW_IMAP">Installing UW IMAP</a></li>

<li><a href="#Set_Up_a_Web_Interface">Set Up a Web Interface</a></li>



</ol>

</td></tr></tbody></table>

<a name="The_Basics_of_Mail_Hosting"></a><h3> <span class="mw-headline">The Basics of Mail Hosting</span></h3>

<p>You don&#8217;t need a particularly powerful machine to handle e-mail. Unless you are planning to support hundreds of users &#8212; or you yourself get hundreds of users&#8217; worth of e-mail &#8212; an old Pentium should be fine, speedwise. You&#8217;ll want plenty of hard drive space, but that&#8217;s cheap these days; RAM is very nice to have as well. Since you are going to be leaving this machine running constantly, you will want it to have powerful yet quiet fans installed. I learned that the hard way.

</p><p>A basic install of Linux and a web server is a good place to start. You may already have one. If not, whatever are you waiting for?

</p><p>When you&#8217;re setting it up, make sure to allot plenty of hard drive space for the <tt>/var</tt> partition, and plenty more for the <tt>/home</tt> partition. This is where all that e-mail is going to live.

</p><p>What you will be doing is running a machine at home (or at another location of your choice) that is connected to the internet, presumably over your DSL or other high-speed connection. Unless you want to restrict your user base to people on your home network and never talk to the outside world, people will be accessing this machine remotely. This raises a few issues.

</p><p><b>One:</b> To resolve a domain name to your box, the box will need an IP address. You can either get a static IP address, which some ISPs charge a bit extra for, but which makes life easy; or you can use so-called dynamic DNS. This involves running a little program on your server that detects what its current IP address is, and, every time the address changes, notifying the DNS server. <a href="http://www.technopagan.org/dynamic/" class="external text" title="http://www.technopagan.org/dynamic/" rel="nofollow">Technopagan</a> has an excellent explanation of dynamic DNS, with listings and ratings of providers.



</p><p><b>Two:</b> Technically speaking, you are &#8220;running a server,&#8221; which some ISPs frown upon. However, since you are limiting access to a handful of friends and relatives, it&#8217;s not really a big drain on their bandwidth, so unless you have a truly draconian ISP and you flaunt the fact that you are occasionally connecting to ports 143 and 80 from outside, you shouldn&#8217;t anticipate any problems.

</p><p><b>Three:</b> Security is an issue. Lock down your box. In brief, don&#8217;t open any ports you don&#8217;t have to, don&#8217;t run any daemons you don&#8217;t have to, and keep everything up to date. <a href="http://www.linuxsecurity.com/docs/" class="external text" title="http://www.linuxsecurity.com/docs/" rel="nofollow">Linux Security</a> is a good security tutorial site.

</p><p>If these obstacles seem large to you, you always have the option of paying someone else to host a machine remotely. That&#8217;s an excellent option if you are willing to trade money for the absence of headaches.

</p><p>Anyway. Once you&#8217;ve got the machine up, running, and connected, with that lovely Apache test page, you are ready to proceed. Read any of the excellent guides to Linux out there if you are feeling lost.

</p>

<a name="Getting_the_Mail"></a><h3> <span class="mw-headline">Getting the Mail</span></h3>

<p>Now then, a proper mail server has a relatively high-profile net presence:It runs Sendmail or Qmail or Postfix, has a proper DNS MX entry, and receives mail that is sent to its domain. That&#8217;s more than most people want to shoulder, in terms of configuration, maintenance, and server horsepower. I already have an ISP that receives my incoming e-mail and stores it briefly. Doubtless you do too. I also receive mail at a couple of other POP-accessible accounts. I wanted to set up my machine Potto to get the mail from the ISP and the other accounts and store it all locally. My ISP has a lot more man- and server power than I can muster, and they do what they do very well. I take the e-mail off their hands and make up for their front-end shortcomings with my flexible, customized system. (Another advantage to this setup is that if Potto ever goes down, all the new incoming mail will just stay on the ISP&#8217;s server, instead of bouncing or getting lost in the ether.)

</p><p>The mail is downloaded from the ISP with <a href="http://fetchmail.berlios.de/" class="external text" title="http://fetchmail.berlios.de/" rel="nofollow">Fetchmail</a>. This is an elegant little piece of software that comes with every Linux distribution and does just what its name implies. Every couple of minutes, Fetchmail polls the various ISPs where the new mail comes in. It retrieves that mail and removes it from the server. For each user on Potto, there is a line in my /etc/fetchmailrc config file that looks like this:



</p>

<pre class="brush: js">poll mail.server.net with proto auto

 user "username" there with password "p@55w3rd" is username here

</pre>

<p>This is an instruction that tells Fetchmail, every time it runs, to poll the specified server, automatically detecting the protocol, and get all mail for &#8220;username&#8221;. That mail is then placed in the local mail spool for the specified user on Potto. I also include the line <tt>set daemon 120</tt>, which tells Fetchmail to run every 120 seconds.

</p><p>OK, so now all this mail&#8217;s sitting on the mail drop machine. What next?

</p><p>Well, in the simplest case, users can connect to the server using <a href="http://www.openssh.com/" class="external text" title="http://www.openssh.com/" rel="nofollow">SSH</a> or telnet, and access their mail via a terminal with <a href="http://www.washington.edu/pine/" class="external text" title="http://www.washington.edu/pine/" rel="nofollow">Pine</a> or <a href="http://www.mutt.org/" class="external text" title="http://www.mutt.org/" rel="nofollow">Mutt</a> or another such console-based client. These clients have very clean interfaces and powerful, streamlined features. And indeed they are popular with a certain geeky cross-section of Potto users. But even Mutt&#8217;s free keybinding and regex support weren&#8217;t enough to convince my dad to switch from Eudora. I needed an easier way to access the mail. Fortunately, what I required was invented many years ago.



</p>

<a name="POP_Versus_IMAP"></a><h3> <span class="mw-headline">POP Versus IMAP</span></h3>

<p>Mail clients like Eudora communicate with a mail host via one of two protocols:POP and IMAP. Therefore, to support such mail clients, a mail host has to be able to speak at least one of these.

</p><p>POP, the Post Office Protocol, is the most widespread protocol by which mail clients retrieve e-mail from a server. It uses the so-called offline operation model &#8212; it makes a quick connection to the server, downloads the messages that are waiting, and typically removes them from the server, then disconnects. The messages are then on the client for good.

</p><p>This method is what gives rise to all the things I was complaining about in the introduction. When you offload e-mail from the server to your local machine, you lose flexibility. I wanted all the e-mail to live on Potto, and be readable from anywhere at any time. IMAP was the answer.

</p><p>IMAP, the Internet Message Access Protocol, was designed to solve some of the issues that POP leaves unaddressed. Although IMAP allows for offline-style operation, its specialty is accessing messages that live permanently on a server. It supports multiple server folders, flags reflecting the New/Read/Answered, etc. status of messages, and a host of other features that place it far above POP, in terms of pretty much everything except popularity. Although IMAP has been around since 1986, POP is the de facto standard, and enjoys much more widespread use than IMAP. Rock-solid proof &#8212; as if we needed more &#8212; that the majority choice is not always the best choice. The differences between IMAP and POP &#8212; from an admittedly pro-IMAP standpoint, though I don&#8217;t know of anyone espousing the other view &#8212; are enumerated at <a href="http://www.imap.org/imap.vs.pop.html" class="external text" title="http://www.imap.org/imap.vs.pop.html" rel="nofollow">imap.org</a>.

</p>

<a name="List_of_IMAP_Server_Software"></a><h4> <span class="mw-headline">List of IMAP Server Software</span></h4>

<p>So yeah, IMAP. There&#8217;s a bit of a choice when it comes to which free UNIX IMAP server to use:

</p>

<ul><li> The University of Washington folks who brought you Pine distribute the <a href="http://www.washington.edu/imap/" class="external text" title="http://www.washington.edu/imap/" rel="nofollow">UW IMAP</a> server



</li></ul>

<ul><li> Carnegie Mellon distributes the <a href="http://asg.web.cmu.edu/cyrus/imapd/" class="external text" title="http://asg.web.cmu.edu/cyrus/imapd/" rel="nofollow">Cyrus</a> server

</li></ul>

<ul><li> There&#8217;s <a href="http://www.courier-mta.org/" class="external text" title="http://www.courier-mta.org/" rel="nofollow">Courier</a> too

</li></ul>

<ul><li> And I&#8217;m assured that <a href="http://dovecot.procontrol.fi/" class="external text" title="http://dovecot.procontrol.fi/" rel="nofollow">Dovecot</a> and <a href="http://www.dbox.handshake.de/dkimap4/" class="external text" title="http://www.dbox.handshake.de/dkimap4/" rel="nofollow">DKIMAP4</a> are excellent in their own right, though my testing was limited.



</li></ul>

<p>I chose UW IMAP to use on Potto, because it supports Unix mbox-style folders, which is the format in which my decade-plus of saved mail happens to be archived; and because it is pretty fast, stable, and secure. Cyrus and Courier may have their advantages when it comes to speed, configuration, and authentication, but both servers prefer alternate ways of storing mail. You can choose the server that best meets your needs &#8212; and I may yet switch &#8212; but for now UW IMAP is doing a fine job.

</p>

<a name="Installing_UW_IMAP"></a><h3> <span class="mw-headline">Installing UW IMAP</span></h3>

<p>To install it, I downloaded the <a href="ftp://ftp.cac.washington.edu/mail/imap.tar.Z" class="external text" title="ftp://ftp.cac.washington.edu/mail/imap.tar.Z" rel="nofollow">source code</a> and unzipped it. The software requires, somewhat inflexibly, that configuration settings be set before compiling, but in the vast majority of cases the default settings are fine and nothing needs to be touched. So, following the onboard <a href="http://www.washington.edu/imap/documentation/BUILD.html" class="external text" title="http://www.washington.edu/imap/documentation/BUILD.html" rel="nofollow">instructions</a>, I simply typed &#8220;make lnp&#8221; and then copied the resulting file, imapd, into the /usr/sbin directory where it would run.

</p><p>After installing the IMAP server software, it is necessary to configure inetd or xinetd, which is the daemon that handles internet traffic for services (like IMAP servers) that need it. In the version of Linux that Potto runs, <a href="http://www.xinetd.org/" class="external text" title="http://www.xinetd.org/" rel="nofollow">xinetd</a> is the order of the day, and its services are configured in the /etc/xinetd.d directory. In a config file called imap in this directory, I specified the following:

</p>



<pre class="brush: js">service imap { socket_type = stream wait = no user = root disable = no server = /usr/sbin/imapd }

</pre>

<p><tt> disable = no</tt> turns on the service, and <tt> server = /usr/sbin/imapd</tt> indicates where the server program lives. Plenty of other configuration options are available here, involving security, logging, and other behavior, which you may customize for your needs.

</p><p>Add the following line to /etc/hosts.allow (this can be modified later to restrict access):

</p>

<pre class="brush: js">imapd&nbsp;:ALL&nbsp;:ALLOW

</pre>

<p>Now restart inetd.



</p><p>After restarting your inetd, you should find that the IMAP server is listening on port 143. (If you have a firewall blocking this port, unblock it.) Running <tt>telnet localhost 143</tt> on the server machine should put you in contact with your IMAP server:

</p>

<pre class="brush: js"> $ telnet localhost 143

 Trying 127.0.0.1...

 Connected to localhost.localdomain (127.0.0.1).

 Escape character is '^]'.

 * OK [CAPABILITY IMAP4REV1 LOGIN-REFERRALS STARTTLS AUTH=LOGIN] localhost.localdomain IMAP4rev1

</pre>

<p>If this doesn&#8217;t work, make sure that the inetd settings are correct, and restart inetd.

</p><p>You can use <tt>/etc/hosts.allow</tt> and <tt>/etc/hosts.deny</tt> to control access to your glistening new IMAP server.

</p><p>Users can now configure their mail clients to talk to the IMAP server. They just need to specify the server name. Via the client, they can create new folders on the server, sort mail, and so forth.



</p><p><b>Tip:</b> UW IMAP keeps each user&#8217;s INBOX in their mail spool file &#8212; typically /var/spool/mail/username. This is where incoming mail goes by default. In addition to this main INBOX, users can create any number of other mail folders in their home directories, for sorting mail into categories. <a href="http://www.procmail.org/" class="external text" title="http://www.procmail.org/" rel="nofollow">Procmail</a> is extremely useful for automatic mail sorting.)

</p><p><b>Tip:</b> <a href="http://www.mulberrymail.com/" class="external text" title="http://www.mulberrymail.com/" rel="nofollow">Mulberry</a> is a terrific mail client that&#8217;s designed to work with IMAP.

</p><p>But the grand plan isn&#8217;t complete yet. Mulberry and Eudora are all well and good when you&#8217;re at home or at work, but what about when you&#8217;re on the road? A web interface is a must.

</p>

<a name="Set_Up_a_Web_Interface"></a><h3> <span class="mw-headline">Set Up a Web Interface</span></h3>

<p>If you forgot to print out the directions to that party, just pull over at a public web terminal and look up the old e-mail!



</p><p>There are several different ways to implement a web mail interface, but the easiest I&#8217;ve found is <a href="http://squirrelmail.org/index.php" class="external text" title="http://squirrelmail.org/index.php" rel="nofollow">SquirrelMail</a>, a PHP-based package that is fairly flexible but requires little setup. It works off an IMAP backend, which you have, and needs only Apache and PHP to run. Apache comes pre-packaged with most Linux distributions. <a href="http://php.net/" class="external text" title="http://php.net/" rel="nofollow">PHP</a> does too.

</p><p>When you&#8217;ve got the requirements squared away, download the SquirrelMail package. Uncompress it in your web server directory. On Potto, this is /var/www/html. This will create a new subdirectory called squirrelmail-<i>version</i>, where &#8220;version&#8221; is the version number of SquirrelMail. Clear?

</p><p>Create the attachments directory (which for some reason isn&#8217;t there by default):

</p>

<pre class="brush: js">mkdir squirrelmail-version/attachments

</pre>.

<p>Fix the ownership and permissions, for security&#8217;s sake:

</p>

<pre class="brush: js"> chown -R root.apache squirrelmail-version

 chown -R apache.apache data

 chown apache.apache attachments

 chmod 730 attachments

 chmod 730 data



</pre>

<p>Did I mention that you need Perl as well? Well, you don&#8217;t strictly need it to <i>run</i> SquirrelMail, but the configuration program runs in Perl. Type

</p>

<pre class="brush: js"> cd squirrelmail-version ./configure

</pre>

<p>This will launch the configuration program. If you really don&#8217;t have Perl on your system, it&#8217;s easy enough to edit the config file by hand:it&#8217;s located at squirrelmail-version/config/config.php.

</p><p>What you need to set to get the program running is the following:In Server Settings:

</p>

<pre class="brush: js"> 1. Domain&nbsp;:''your domain name''

 2. IMAP Server&nbsp;:localhost

 3. IMAP Port&nbsp;:143



</pre>

<p>If you have an ISP through which you typically send your e-mail, it reduces overhead to use them as your SMTP server:

</p>

<pre class="brush: js"> 4. Use Sendmail/SMTP&nbsp;:SMTP

 6. SMTP Server&nbsp;:mail.yourisp.net

 7. SMTP Port&nbsp;:25



 10. Server&nbsp;:uw

</pre>

<p>Next, in General Options:

</p>

<pre class="brush: js"> 2. Data Directory&nbsp;:../data/

 3. Attachment Directory&nbsp;:../attachments/

</pre>



<p>Those are the essentials &#8212; the rest is customization. You can even use your own CSS files to get it looking exactly the way you want.

</p><p>Now try it out! Browse to <a href="http://yourdomainname.net/squirrelmail-version/" class="external free" title="http://yourdomainname.net/squirrelmail-version/" rel="nofollow">http://yourdomainname.net/squirrelmail-version/</a> and you should see the login screen. Even better, you should be able to log in successfully and see your e-mail folders!

</p><p>Congratulations. You are free of POP tyranny. You&#8217;ve never been so hands-on before. Your friends will love your hosting service, and &#8212; yes! &#8212; that&#8217;s <i>your e-mail</i> purring in the next room.

</p><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/set_up_imap_on_your_mail_server/feed/</wfw:commentRss>
        <slash:comments>1</slash:comments>

        
    </item>
    
    <item>
        <title>Build a Microblog with Django</title>
        <link>http://www.webmonkey.com/2010/02/build_a_microblog_with_django/</link>
        <comments>http://www.webmonkey.com/2010/02/build_a_microblog_with_django/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=931</guid>
        		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Thus far in our introductory Django tutorial, we&#8217;ve installed the open-source Django framework, set up a blog and beefed it up by adding some extras like semantic content tags, some handy template tags and a list of our bookmarks from delicious.com. If you haven&#8217;t been following along, now would be a good time to go [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>Thus far in our introductory Django tutorial, we&#8217;ve <a href="/2010/02/Install_Django_and_Build_Your_First_App" title="Tutorial:Install Django and Build Your First App"> installed the open-source Django framework</a>, set up a blog and beefed it up by adding some extras like <a href="/2010/02/Use_URL_Patterns_and_Views_in_Django" title="Tutorial:Use URL Patterns and Views in Django"> semantic content tags</a>, some handy <a href="/2010/02/Use_Templates_in_Django" title="Tutorial:Use Templates in Django"> template tags</a> and <a href="/2010/02/Integrate_Web_APIs_into_Your_Django_Site" title="Tutorial:Integrate Web APIs into Your Django Site"> a list of our bookmarks from delicious.com</a>. If you haven&#8217;t been following along, now would be a good time to go back to <a href="/2010/02/Get_Started_With_Django" title="Tutorial:Get Started With Django"> Lesson 1</a> and catch up.



</p><p>However, what we&#8217;ve created is not much different than what one could do with WordPress or another out-of-the-box blogging tool. That&#8217;s OK for a learning project. But now we&#8217;re getting close to being experts, we are going to explore some territory beyond what we can do with pre-built tools.

</p><p>Let&#8217;s build something a little more advanced. Let&#8217;s build a microblog.

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

<table id="toc" class="toc" summary="Contents"><tbody><tr><td><div id="toctitle"><h2>Contents</h2> </div>

<ol>

<li><a href="#Let.27s_get_ready_to_Tumble">Let&#8217;s get ready to Tumble</a></li>



<li><a href="#Laying_the_groundwork">Laying the groundwork</a></li>

<li><a href="#How_it_works">How it works</a></li>

<li><a href="#Listen_for_the_Signals">Listen for the Signals</a></li>

<li><a href="#Writing_the_URLs_and_views">Writing the URLs and views</a></li>

<li><a href="#Where_do_we_go_from_here.3F">Where do we go from here?</a></li>



<li><a href="#RSS_feeds">RSS feeds</a></li>

<li><a href="#Conclusion">Conclusion</a></li>

</ol>

</td></tr></tbody></table>



<a name="Let.27s_get_ready_to_Tumble"></a><h2> <span class="mw-headline">Let&#8217;s get ready to Tumble</span></h2>

<p>These days, many of us follow our friends on services like FriendFeed or Facebook, where the concept of a &#8220;blog post&#8221; is much looser, smaller and faster.

</p><p>Whether you want to call it a newsfeed, lifestream, microblog, tumblelog or a dozen other clever portmanteaus or neologisms, the concept is the same: a site to log snippets of your life and its discoveries in one place.

</p><p>FriendFeed is a favorite. The service combines tweets from Twitter, photos from Flickr, links from Delicious, updates from Facebook and other sundry data and displays them all on one page. The page itself also has an RSS feed, giving you (or any of your many fans) a way to follow your every move.



</p><p>Let&#8217;s build a version of Friendfeed using Django.  We&#8217;ll build a page displaying both our links and blog posts together in a single, time-based &#8220;river.&#8221; As a bonus we&#8217;ll add in some RSS sugar so our friends can follow along without having to visit the site.

</p>

<a name="Laying_the_groundwork"></a><h2> <span class="mw-headline"> Laying the groundwork </span></h2>

<p>Before we get started, let&#8217;s think for a bit about what needs to be done. We will post data two separate using two models: the blog Entry model and the Link model. We need to query them both at the same time and then sort the feed into reverse chronological order.

</p><p>The key to making it work is by creating a way to normalize our data. The database table for each of these models are significantly different. Instead of querying both models, wouldn&#8217;t it be better if we just query against one table?

</p><p>Let&#8217;s do it.

</p>

<a name="How_it_works"></a><h2> <span class="mw-headline"> How it works </span></h2>

<p>There&#8217;s one thing all models will have in common: a publication date. What we&#8217;re going to do is create a kind of meta model which stores the date as well as what kind of data it is (i.e. blog entry, link, etc).

</p><p>Django ships with two tools which actually make it very easy to build our meta model. The first is the <a href="http://www.djangoproject.com/documentation/contenttypes/" class="external text" title="http://www.djangoproject.com/documentation/contenttypes/" rel="nofollow">content types framework</a>. As the docs explain, &#8220;instances of ContentType represent and store information about the models installed in your project, and new instances of ContentType are automatically created whenever new models are installed.&#8221;



</p><p>Huh? Basically, what the Django Project is telling us is just by referencing the content type, we will always know what type of content we&#8217;re storing. Storing the content type is half the battle.

</p><p>The other half of the battle will be won by using a built-in field known as a <a href="http://www.djangoproject.com/documentation/contenttypes/#generic-relations" class="external text" title="http://www.djangoproject.com/documentation/contenttypes/#generic-relations" rel="nofollow">GenericForeignKey</a>. You may have noticed a ForeignKey field in the Django docs. ForeignKey is similar to what we&#8217;re going to use. Where ForeignKey refers to a single model, our GenericForeignKey can refer to any model by referencing the content_type instead.

</p><p>If that sounds confusing, don&#8217;t worry. It&#8217;ll make more sense when you see it in action.

</p><p>Let&#8217;s start writing some code. I&#8217;m going to store our meta app in a folder named &#8220;tumblelog&#8221; so create the folder and create a new <code>models.py</code> file inside it (don&#8217;t forget the <code>__init__.py</code> file as well, Python&#8217;s never-ending &#8220;gotcha&#8221;). Open up <code>models.py</code> in your text editor and paste in this code:

</p>

<pre class="brush: js">from django.db import models

from django.contrib.contenttypes import generic



class TumbleItem(models.Model):

    content_type = models.ForeignKey(ContentType)

    object_id = models.PositiveIntegerField()

    pub_date = models.DateTimeField()

    content_object = generic.GenericForeignKey('content_type', 'object_id')



    class Meta:

        ordering = ('-pub_date',)



    def __unicode__(self):

        return self.content_type.name





</pre>

<p>If you&#8217;re familiar with our previous tutorials (or Django in general), by now this should look somewhat familiar. We have a regular <code>ForeignKey</code> to the <code>ContentType</code> as we discussed above. Then we have an <code>id</code> field, which we need to pass to the <code>GenericForeignKey</code> field (along with <code>content_type</code>). Finally we add a <code>datetime</code> field for easy sorting. If you look at the <code>GenericForeignKey</code> documentation you&#8217;ll notice this is pretty much the same code used to demonstrate <code>GenericForeignKeys</code>. The only difference is we&#8217;ve added a <code>date</code> field.



</p><p>Now we have a basic script, but we certainly don&#8217;t want to update this by hand every time we post something. Especially since our delicious.com import script runs automatically.

</p><p>Well, it turns out there&#8217;s a very powerful feature baked into Django which can handle the task for us.

</p><p>Django includes an internal &#8220;dispatcher&#8221; which allows objects to listen for signals from other objects. In our case, our tumblelog app is going to &#8220;listen&#8221; to our Entry and Link models. Every time a new Entry or Link is saved, those models will send out a signal. When the tumblelog app gets the signal it will automatically update itself.

</p><p>Sweet. How do we do it?

</p>

<a name="Listen_for_the_Signals"></a><h2> <span class="mw-headline"> Listen for the Signals </span></h2>

<p>The first thing we need to do is import the signals framework. Add this to the top of your <code>model.py</code> file:

</p>

<pre class="brush: js">from django.db.models import signals

from django.contrib.contenttypes.models import ContentType

from django.dispatch import dispatcher

from blog.models import Entry

from links.models import Link

</pre>

<p>OK, now move to the bottom of the file and add these lines:



</p>

<pre class="brush: js">for modelname in [Entry, Link]:

	dispatcher.connect(create_tumble_item, signal=signals.post_save, sender=modelname)



</pre>

<p>In Django 1.1 (and 1.0 I think) the signal have changed.

Change the import to:

</p>

<pre class="brush: js">from django.db.models import signals

from django.contrib.contenttypes.models import ContentType

from django.db.models.signals import post_save

from blog.models import Entry

from links.models import Link

</pre>

<p>and change the dispatcher line to

</p>

<pre class="brush: js">post_save.connect(create_tweet_item, sender=Entry)

post_save.connect(create_tweet_item, sender=Link)

</pre>

<p><br />

</p><p><br />

So what&#8217;s it do? Well it tells the dispatcher to listen for the <code>post_save</code> signal from out Entry and Link models and whenever it gets the signal, it will fire off our <code>create_tumble_item</code> function.



</p><p>But wait, we don&#8217;t have a <code>create_tumble_item</code> function do we?

</p><p>No, so we better write one. Just above the <code>dispatcher</code> function add this code:

</p>

<pre class="brush: js">def create_tumble_item(sender, instance, signal, *args, **kwargs):

	if 'created' in kwargs:

		if kwargs['created']:

			create = True

			ctype = ContentType.objects.get_for_model(instance)

			if ctype.name == 'link':

				pub_date = instance.date

			else:

				pub_date = instance.pub_date

			if create:

				t = TumbleItem.objects.get_or_create(content_type=ctype, object_id=instance.id, pub_date=pub_date)

</pre>

<p>What&#8217;s this function doing? For the most part it&#8217;s just taking the data sent by the dispatcher and using it to create a new <code>TumbleItem</code>.

</p><p>The first line looks to see if a variable, <code>created</code>, has been passed by the dispatcher. The <code>post_save</code> signal is sent everytime an object is saved, so it&#8217;s possible we&#8217;ve just updated an existing item rather than creating a new one. In that case, we don&#8217;t want to create a new <code>TumbleItem</code>, so the function checks to make sure this is, in fact, a new object.



</p><p>If the dispatcher has passed the variable <code>created</code>, and its true, then we set our own <code>create</code> flag and get the <code>content_type</code> of the passed instance. This way, we know whether it&#8217;s a Link or an Entry.

</p><p>If it&#8217;s a Link we need to find the datetime info. When we built our Link model, we called the field <code>date</code>, so we set our normalizing <code>pub_date</code> field equal to the <code>instance.date</code> field.



</p><p>If the instance is a blog Entry we set <code>pub_date</code> to the value of the instance&#8217;s <code>pub_date</code> field since, it shares the name we used in our Entry model.

</p><p>Then we create a new TumbleItem using the built-in <code>get_or_create</code> method. We also pass in a <code>content_type</code>, <code>id</code> and <code>pub_date&lt;code&gt; to their respective fields.



</code></p><p>And there you have it. Any time you create a blog entry or the script adds a new link, our new TumbleItem model will automatically update.

</p><p>There&#8217;s a slight problem though. What about the data we&#8217;ve already got in there?

</p><p>Well to make sure it gets added, we&#8217;re going to have to comment out the following lines:

</p>

<pre class="brush: js">	if 'created' in kwargs:

		if kwargs['created']:

</pre>

<p>Comment it out and save the file. Then fire up the terminal and enter this code one line at a time:

</p>

<pre class="brush: js">&gt;&gt;&gt; from blog.models import Entry

&gt;&gt;&gt; from link.models import Link

&gt;&gt;&gt; entries = Entry.objects.all()

&gt;&gt;&gt; for entry in entries:

...     entry.save()

...



&gt;&gt;&gt; links = Link.objects.all()

&gt;&gt;&gt; for link in Link:

...     link.save()

...

&gt;&gt;&gt;

</pre>

<p>What did it do? We just called the &lt;code&gt;save method and dispatcher passed its signal along to the TumbleItem model which then updated itself. Because we commented out the lines that check to see if an item is new, the function ran regardless of the instance&#8217;s created variable.

</p><p>Now uncomment those lines and save the file.

</p><p>Before we move on I should point out <code>post_save</code> isn&#8217;t the only signal Django can send. There are in fact a whole bunch of useful signals like <code>request_started</code>, <code>pre_save</code> and many more. Check out the <a href="http://code.djangoproject.com/wiki/Signals" class="external text" title="http://code.djangoproject.com/wiki/Signals" rel="nofollow">Django wiki</a> for more details.



</p><p><br />

</p>

<a name="Writing_the_URLs_and_views"></a><h2> <span class="mw-headline"> Writing the URLs and views </span></h2>

<p>Now we need to add a tumblelog URL and pull out the data. Open up your project level <code>urls.py</code> file and add this line:

</p>

<pre class="brush: js">(r'^tumblelog/', 'tumblelog.views.tumbler'),

</pre>

<p>Now create a new <code>views.py</code> file inside your tumblelog folder and open it up to paste in this code:



</p>

<pre class="brush: js">from tumblelog.models import TumbleItem

from django.shortcuts import render_to_response



def tumbler(request):

	context = {

		'tumble_item_list': TumbleItem.objects.all().order_by('-pub_date')

	}



	return render_to_response('tumblelog/list.html', context)

</pre>

<p>What&#8217;s going on here? Well first we grab the tumblelog items and then we use a Django shortcut function to return to pass the list on to template named <code>list.html</code>.

</p><p>Let&#8217;s create the template. Add a new folder &#8220;tumblelog&#8221; inside your templates folder and create the <code>list.html</code> file. We&#8217;ll start by extending our base template and filling in the blocks we created in <a href="/2010/02/Use_Templates_in_Django" title="Tutorial:Use Templates in Django"> an earlier lesson</a>:

</p>

<pre class="brush: js">{% block title&nbsp;%}My Tumblelog{% endblock&nbsp;%}

{% block primary&nbsp;%}

{% for object in object_list&nbsp;%}

	{%if object 'link'%}

		&lt;a href="{{ obj.url }}" title="{{ obj.title}}"&gt;{{ obj.title}}&lt;/a&gt;{{object.description}} Posted on {{object.pub_date|date:"D d M Y"}}

	{% endif&nbsp;%}



	{%if object 'entry'%}

		&lt;h2&gt;{{ object.title }}&lt;/h2&gt;



		&lt;p&gt;{{ object.pub_date }}&lt;/p&gt;

		{{ object.body_html|truncatewords_html:"20"|safe }}

		&lt;p&gt;&lt;a href="{{object.get_absolute_url}}"&gt;more&lt;/a&gt;&lt;/p&gt;

	{% endif&nbsp;%}

{% endfor&nbsp;%}

{% endblock&nbsp;%}



</pre>

<p>If you start up the development server and head to <a href="http://127.0.0.1:8000/tumblelog/" class="external free" title="http://127.0.0.1:8000/tumblelog/" rel="nofollow">http://127.0.0.1:8000/tumblelog/</a> you should see your blog entries and links ordered by date.

</p>

<a name="Where_do_we_go_from_here.3F"></a><h2> <span class="mw-headline"> Where do we go from here? </span></h2>

<p>We&#8217;re looking pretty good up until we get to the template stage. The <code>if</code> statements aren&#8217;t so bad when we&#8217;re only sorting two content types, but if you start pulling in tons of different types of data you&#8217;ll quickly end up with spaghetti code.

</p><p>A far better idea would be to write a template tag which takes the <code>content type</code> as an argument, uses it to call a template file, renders it and passes back to the html as a string.



</p><p>We&#8217;ll leave it up to you as an exercise (hint: read up on Django&#8217;s <a href="http://www.djangoproject.com/documentation/templates_python/#the-render-to-string-shortcut" class="external text" title="http://www.djangoproject.com/documentation/templates_python/#the-render-to-string-shortcut" rel="nofollow">render_to_string method</a>).

</p><p>The other thing you might be wondering about is pagination. If you save dozens of links a day and blog like a madman, this page is going to get really large really fast. Django ships with some built-in pagination tools (see <a href="http://www.djangoproject.com/documentation/pagination/" class="external text" title="http://www.djangoproject.com/documentation/pagination/" rel="nofollow">the docs</a>) and there&#8217;s also a slick <a href="http://code.google.com/p/django-pagination/" class="external text" title="http://code.google.com/p/django-pagination/" rel="nofollow">django-pagination app</a> available from Eric Florenzano. Eric even has a <a href="http://eflorenzano.com/blog/post/first-two-django-screencasts/#using-django-pagination" class="external text" title="http://eflorenzano.com/blog/post/first-two-django-screencasts/#using-django-pagination" rel="nofollow">very nice screencast</a> on how to set things up.

</p><p><br />

</p>

<a name="RSS_feeds"></a><h2> <span class="mw-headline"> RSS feeds </span></h2>



<p>We&#8217;re almost done. Let&#8217;s hook up some RSS feeds for our new site.

</p><p>It turns out, Django ships with a very nice <a href="http://www.djangoproject.com/documentation/syndication_feeds/" class="external text" title="http://www.djangoproject.com/documentation/syndication_feeds/" rel="nofollow">syndication framework</a>. All we need to do is turn it on and hook it up.

</p><p>Let&#8217;s start by going into our TumbleItem <code>models.py</code> file and setting up the framework. Paste in this code at the bottom of the file:

</p>

<pre class="brush: js">from django.contrib.syndication.feeds import Feed

class LatestItems(Feed):

    title = "My Tumblelog: Links"

    link = "/tumblelog/"

    description = "Latest Items posted to mysite.com"

    description_template = 'feeds/description.html'



    def items(self):

        return TumbleItems.objects.all.order_by('-pub_date')[:10]



</pre>

<p>Here we&#8217;ve imported the syndication class <code>Feed</code> and then defined our own feed class to fill in some basic data. The last step is returning the items using a normal <code>objects</code> query.



</p><p>We need to create the URLs first. There are several places you could do this, I generally opt for the main project URLs.py file. Open it up and paste this code just below the other import statements:

</p>

<pre class="brush: js">from tumblelog.models import LatestItems

feeds = {

    'tumblelog': LatestItems

}

</pre>

<p>Now add this line to your <code>urlpattern</code> function:

</p>

<pre class="brush: js">(r'^feeds/(?P&lt;url&gt;.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict': feeds}),

</pre>

<p>The last step is creating the description template in a new folder we&#8217;ll lable &#8220;feeds.&#8221; Just plug in the same code from the tumblelog template, but delete the <code>forloop</code> tag since we&#8217;re only passing a single object this time.



</p><p>And there you have it. Fire up the development server and point it to <a href="http://127.0.0.1:8000/feeds/tumblelog/" class="external free" title="http://127.0.0.1:8000/feeds/tumblelog/" rel="nofollow">http://127.0.0.1:8000/feeds/tumblelog/</a>. If you want to add separate feeds for links or just blog entries, all you need to do is repeat the process, creating new <code>feed</code> classes for each.

</p>

<a name="Conclusion"></a><h2> <span class="mw-headline"> Conclusion </span></h2>

<p>Whew! It&#8217;s been a long journey and we wrote a lot of code, but hopefully you learned a good bit about how Django works. You not only have a blog/linklog/tumblelog, but hopefully some ideas of how to approach other projects.

</p><p>Speaking of projects, although we used one, there&#8217;s really no need to organize your code this way. Sometimes the projects come in handy, but other times they make your PYTHONPATH into a snarled mess. For some other ideas on how organize you code, check out James Bennet&#8217;s <a href="http://www.b-list.org/weblog/2007/nov/09/projects/" class="external text" title="http://www.b-list.org/weblog/2007/nov/09/projects/" rel="nofollow">article on the subject</a>.

</p><p>If you ever have questions about Django, jump on the <a href="irc://irc.freenode.net/django" class="external text" title="irc://irc.freenode.net/django" rel="nofollow">#Django IRC channel</a>, there&#8217;s load of friendly and helpful developers who can point you in the right direction, and be sure to <a href="http://groups.google.com/group/django-users" class="external text" title="http://groups.google.com/group/django-users" rel="nofollow">join the mailing list</a>. Happy coding!



</p>

<div id="series">

<div class="series_hdr">From the Django Tutorial series</div>

<table style="background: rgb(229, 249, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" width="620">

<tbody><tr>

<td>

<p><a href="/2010/02/Get_Started_With_Django" title="Tutorial:Get Started With Django"> Lesson 1: Get Started With Django</a><br />

<a href="/2010/02/Install_Django_and_Build_Your_First_App" title="Tutorial:Install Django and Build Your First App"> Lesson 2: Install Django and Build Your First App</a><br />

<a href="/2010/02/Use_URL_Patterns_and_Views_in_Django" title="Tutorial:Use URL Patterns and Views in Django"> Lesson 3: Use URL Patterns and Views in Django</a><br />

<a href="/2010/02/Use_Templates_in_Django" title="Tutorial:Use Templates in Django"> Lesson 4: User Templates in Django</a><br />



<a href="/2010/02/Integrate_Web_APIs_into_Your_Django_Site" title="Tutorial:Integrate Web APIs into Your Django Site"> Lesson 5: Use Web API Data in Django</a><br />

<strong class="selflink"> Lesson 6: Build a Microblog with Django</strong>

</p>

</td></tr></tbody></table>

</div><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/build_a_microblog_with_django/feed/</wfw:commentRss>
        <slash:comments>2</slash:comments>

        
    </item>
    
    <item>
        <title>Refresh a Page Using Meta Tags</title>
        <link>http://www.webmonkey.com/2010/02/refresh_a_page_using_meta_tags/</link>
        <comments>http://www.webmonkey.com/2010/02/refresh_a_page_using_meta_tags/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=234</guid>
        		<category><![CDATA[HTML]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Childhood, as far as your basic cheese selections go, was easy. In your typical middle-class family, you had one of three choices:cheddar, Monterey Jack, and those precious, flat, sandwich-sized slices of American. That&#8217;s what all the cool kids ate. I had to fight my mother to get those into my lunch. She used to make [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>Childhood, as far as your basic cheese selections go, was easy. In your typical middle-class family, you had one of three choices:cheddar, Monterey Jack, and those precious, flat, sandwich-sized slices of American. That&#8217;s what all the cool kids ate. I had to fight my mother to get those into my lunch. She used to make sandwiches with these huge slabs of cheddar cheese that looked like they were hewed from the side of an orange glacier. Although I lost the Wonder Bread battle, I didn&#8217;t give an inch on this one. For some reason, Mom couldn&#8217;t see the simple beauty in a perfectly proportioned square of processed cheese food.



</p><p>The problem with childhood is that we never appreciate it while we have the chance. As I grew up, I developed more mature needs and tastes. Like many young adults lost in the hype of &#8217;80s mass cultural wonders like Molly Ringwald and Oingo Boingo, I began to experiment. I told myself that I didn&#8217;t have a problem, but a little brie here, and a bit of Chaumont there, and before I knew it, I was hooked.



</p><span id="more-234"></span><p>My problems aside, cheese took a serious hit in the early &#8217;90s. Cheese, it was discovered, is composed mostly of fat. It&#8217;s &#8220;bad&#8221; for you. Less fattening cheeses like feta became all the rage. Feta, if you&#8217;re unaware, originated in Greece and has been made the same way for thousands of years. Now, aside from the fact that &#8220;feta&#8221; and &#8220;meta&#8221; rhyme and share common Greek etymologies, there is absolutely no correlation between the two. You can&#8217;t eat a <tt>&lt;meta&gt;</tt> tag, which, frankly, makes it a lot less interesting.

</p><p>So what is it? Glad you asked. The <tt>&lt;meta&gt;</tt> tag is often found at the top of an HTML document between the <tt>&lt;/title&gt;</tt> and the <tt>&lt;/head&gt;</tt> tag. It has a variety of uses, but one of the most common is the client-pull function, used to either reload or redirect pages after a specified amount of time. The reload function is relatively simple, and the syntax looks like this:

</p>



<pre class="brush: js">&lt;meta http-equiv="Refresh" content="30"&gt; </pre>



<p>Let&#8217;s break this down. <tt>http-equiv</tt> gives the name of the <tt>http</tt> function that you want parsed by the server and <tt>content</tt> is the amount of time you want to wait before the server goes ahead with the <tt>http-equiv</tt>. In this case, we&#8217;re waiting 30 seconds before reloading.



</p><p>If you want to redirect users to another page, you would add a URL to the tag syntax to tell the server where it should go.

</p>



<pre class="brush: js">&lt;meta http-equiv="refresh" content="30; URL=http://www.webmonkey.com/"&gt;</pre>





<p>In this case, when 30 seconds have expired, we&#8217;re redirected to a new page, which is defined by the URL attribute in the tag.



</p><p>The <tt>&lt;meta&gt;</tt> tag can also be used to convey information about your document that can&#8217;t be found anywhere within it. A lot of people use it to add keywords to their pages. This used to have a huge effect on how the page was indexed by search engines, but since search engines (and keyword writers) have gotten smarter, meta tag keywords have come to carry less sway over search engine indexing.



</p><p>Putting keywords in your meta tags still helps define what the page is about for some users, though. To do this, you need the <tt>name</tt> element to &#8212; what else &#8212; give the information a name. This might sound a little silly at first, but if you use the <tt>&lt;meta&gt;</tt> tag several times in one document to do many different things, it&#8217;s important to keep the tags straight, otherwise you might have trouble remembering what each one does. The <tt>content</tt> attribute also differs here. Rather than assigning a refresh time, you use this space to add the keywords:

</p>



<pre class="brush: js">&lt;meta name="keywords" content="chicken, biscuits, cheese"&gt;</pre>



<p>In the above example, your document will be referenced by the additional keywords chicken, biscuit and cheese, even if the only thing on your page is a giant JPEG of your favorite NASCAR driver. Of course, this isn&#8217;t very helpful to your readers, so try to use words that relate to your content.



</p><p>The uses for the <tt>&lt;meta&gt;</tt> tag are continuously expanding, so when I figure out more, I&#8217;ll let you know. Oh, and if you&#8217;re selecting fine cheeses, I recommend a nice havarti. Although it&#8217;s from Scandinavia &#8212; which isn&#8217;t known for its fine cheeses &#8212; havarti&#8217;s quite delicious.</p><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/refresh_a_page_using_meta_tags/feed/</wfw:commentRss>
        <slash:comments>0</slash:comments>

        
    </item>
    
    <item>
        <title>Information Architecture Tutorial</title>
        <link>http://www.webmonkey.com/2010/02/information_architecture_tutorial/</link>
        <comments>http://www.webmonkey.com/2010/02/information_architecture_tutorial/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=650</guid>
        		<category><![CDATA[UI/UX]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Information architecture is the science of figuring out what you want your site to do and then constructing a blueprint before you dive in and put the thing together. It&#8217;s more important than you might think, and John Shiple, aka Squishy, tells you why. Squishy first looks at how to define your site&#8217;s goals, shedding [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>Information architecture is the science of figuring out what you want your site to do and then constructing a blueprint before you dive in and put the thing together. It&#8217;s more important than you might think, and John Shiple, aka Squishy, tells you why.

</p><p>Squishy first looks at how to define your site&#8217;s goals, shedding light on the all-important art of collecting clients&#8217; or co-workers&#8217; opinions and assembling them in a coherent, weighted order of importance. He also shares his scheme for documenting everything so that all parties can keep up.

</p><p>The next step is figuring out who the heck your audiences are going to be. Once that&#8217;s out of the way, you can start organizing your future site into pages of content and functions that the site will need to have.

</p><p>Next, Squishy gets into creativityland, where you start to build the beast:form a skeleton, pick your metaphors, map out your navigation. Then it&#8217;s time to break out the graphics program, come up with layout grids, design sketches, and mock-ups, and get ready to build!

</p><p><br />

<span id="title_name_el" class="wm_hidden_meta_class" title="Squishy's Crash Course in Information Architecture" style="visibility: hidden;"> <span id="page_path_el" class="wm_hidden_meta_class" title="/webmonkey/98/28/" style="visibility: hidden;"> <span id="author_el" class="wm_hidden_meta_class" title="squishy" style="visibility: hidden;"> <span id="creation_date_el" class="wm_hidden_meta_class" title="1998-07-13T24:00:00Z" style="visibility: hidden;"> </span></span></span></span>

</p>



<a name="Suggested_readings"></a><h2> <span class="mw-headline"> Suggested readings </span></h2>

<div id="series">

<div class="series_hdr">From the series</div>

<table style="background: rgb(229, 249, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" width="620">

<tbody><tr>

<td>

<p><strong class="selflink"> Information Architecture Tutorial</strong><br />

<a href="/2010/02/Information_Architecture_Tutorial_-_Lesson_1" title="Tutorial:Information Architecture Tutorial - Lesson 1"> Information Architecture Tutorial &#8211; Lesson 1</a><br />

<a href="/2010/02/Information_Architecture_Tutorial_-_Lesson_2" title="Tutorial:Information Architecture Tutorial - Lesson 2"> Information Architecture Tutorial &#8211; Lesson 2</a><br />

<a href="/2010/02/Information_Architecture_Tutorial_-_Lesson_3" title="Tutorial:Information Architecture Tutorial - Lesson 3"> Information Architecture Tutorial &#8211; Lesson 3</a><br />

<a href="/2010/02/Information_Architecture_Tutorial_-_Lesson_4" title="Tutorial:Information Architecture Tutorial - Lesson 4"> Information Architecture Tutorial &#8211; Lesson 4</a><br />

<a href="/2010/02/Information_Architecture_Tutorial_-_Lesson_5" title="Tutorial:Information Architecture Tutorial - Lesson 5"> Information Architecture Tutorial &#8211; Lesson 5</a>

</p>

</td></tr></tbody></table>

</div><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/information_architecture_tutorial/feed/</wfw:commentRss>
        <slash:comments>11</slash:comments>

        
    </item>
    </channel>
</rss>
