<?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>eriksmartt.com/blog &#187; web</title>
	<atom:link href="http://www.eriksmartt.com/blog/archives/tag/web/feed" rel="self" type="application/rss+xml" />
	<link>http://www.eriksmartt.com/blog</link>
	<description>my little chunk of bandwidth</description>
	<lastBuildDate>Mon, 06 Sep 2010 04:00:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1-alpha</generator>
		<item>
		<title>Security use-cases that weaken security</title>
		<link>http://www.eriksmartt.com/blog/archives/1405</link>
		<comments>http://www.eriksmartt.com/blog/archives/1405#comments</comments>
		<pubDate>Thu, 19 Aug 2010 22:15:12 +0000</pubDate>
		<dc:creator>erik</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[experience]]></category>
		<category><![CDATA[ux]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.eriksmartt.com/blog/?p=1405</guid>
		<description><![CDATA[I do, appreciate it when companies try to address &#8220;security&#8221;, but this is so bad it&#8217;s comical. I hope &#8220;math&#8221; wasn&#8217;t your favorite subject in school:]]></description>
			<content:encoded><![CDATA[<p>I do, appreciate it when companies try to address &#8220;security&#8221;, but this is so bad it&#8217;s comical. I hope &#8220;math&#8221; wasn&#8217;t your favorite subject in school:</p>
<p><img src="http://www.eriksmartt.com/blog/wp-content/uploads/2010/08/Screen-shot-2010-08-17-at-9.27.43-AM.png" alt="Screen-shot-2010-08-17-at-9.27.43-AM.png" title="Screen-shot-2010-08-17-at-9.27.43-AM.png" border="1" width="600" height="387" /></p>]]></content:encoded>
			<wfw:commentRss>http://www.eriksmartt.com/blog/archives/1405/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stuck with the &#8220;critical security problems&#8221; of Flash?</title>
		<link>http://www.eriksmartt.com/blog/archives/1402</link>
		<comments>http://www.eriksmartt.com/blog/archives/1402#comments</comments>
		<pubDate>Thu, 19 Aug 2010 22:06:06 +0000</pubDate>
		<dc:creator>erik</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[experience]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[ux]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.eriksmartt.com/blog/?p=1402</guid>
		<description><![CDATA[It is not helpful when this: Links to this:]]></description>
			<content:encoded><![CDATA[<p>It is not helpful when this:</p>
<p><img src="http://www.eriksmartt.com/blog/wp-content/uploads/2010/08/Screen-shot-2010-08-19-at-5.00.50-PM.png" alt="Screen shot 2010-08-19 at 5.00.50 PM.png" title="Screen shot 2010-08-19 at 5.00.50 PM.png" border="0" width="500" height="69" /></p>
<p>Links to this:</p>
<p><img src="http://www.eriksmartt.com/blog/wp-content/uploads/2010/08/Screen-shot-2010-08-19-at-5.01.01-PM.png" alt="Screen shot 2010-08-19 at 5.01.01 PM.png" title="Screen shot 2010-08-19 at 5.01.01 PM.png" border="0" width="500" height="121" /></p>]]></content:encoded>
			<wfw:commentRss>http://www.eriksmartt.com/blog/archives/1402/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jsmacro &#8212; an oddly named JavaScript preprocessor</title>
		<link>http://www.eriksmartt.com/blog/archives/1254</link>
		<comments>http://www.eriksmartt.com/blog/archives/1254#comments</comments>
		<pubDate>Tue, 26 Jan 2010 01:38:55 +0000</pubDate>
		<dc:creator>erik</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jsmacro]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.eriksmartt.com/blog/?p=1254</guid>
		<description><![CDATA[For awhile now I&#8217;ve wanted a JavaScript preprocessor to conditionally include debug and testing code when needed. It&#8217;s always registered as merely a &#8220;nice to have&#8221;, so I hadn&#8217;t sought one out. However, I had a little time over the weekend and wanted to play with the idea, so here it is: jsmacro (on GitHub.) [...]]]></description>
			<content:encoded><![CDATA[<p>For awhile now I&#8217;ve wanted a JavaScript preprocessor to conditionally include debug and testing code when needed.  It&#8217;s always registered as merely a &#8220;nice to have&#8221;, so I hadn&#8217;t sought one out.  However, I had a little time over the weekend and wanted to play with the idea, so here it is: <a href="http://github.com/smartt/jsmacro">jsmacro</a> (on GitHub.)</p>
<p>[Note that before writing this I did seek out existing implementations, and found <a href="http://www.bramstein.com/projects/preprocess/">js-preprocess</a> to be the most interesting; However, I needed something that would work as part of an existing build chain, so authoring the tool in Python instead of JavaScript made more sense.]</p>
<p>Currently, jsmacro is poorly named, as I didn&#8217;t write the macro system that was in my head.  Instead, it&#8217;s currently a basic preprocessor supporting only DEFINE and IF statements, which happened to be all I needed at the time.  Usage works like this:</p>
<h3>Input JavaScript</h3>
<pre><code>
  //@define DEBUG 0

  var foo = function() {
    //@if DEBUG
    alert('This.');
    alert('That.');
    //@end

    print "Hi";
  };
</code></pre>
<p>Pass the above JavaScript through jsmacro from the command line like this: <code>./jsmacro.py -f infile.js &gt; outfile.js</code> (assuming the files are all in the same directory), and you get the following:</p>
<h3>Output JavaScript</h3>
<pre><code>
  var foo = function() {

    print "Hi";
  };
</code></pre>
<p>The tool has registered the variable &#8216;DEBUG&#8217; as 0 (i.e., false), so the conditional include statements omit the alert() calls.  If DEBUG had been set to 1 (i.e., true), the alert() statements would remain (though all jsmacro instructions would be removed either way.)</p>
<p>One of the tricky things about doing macros or preprocessing in JavaScript is that I wanted the code to be valid JavaScript before the tool is run (which is why C-preprocessors won&#8217;t work.)  The idea is that you develop as you normally would, but wrap your debug and testing code in conditional jsmacro statements so that they are automatically removed as part of your build process.</p>
<p>There&#8217;s nothing fancy about the current implementation (it&#8217;s a crude state machine that scans line-by-line, top-to-bottom looking for regex patterns and deciding whether to output the line of not.)  Crude as it may be though, it completely solved a problem for me, and hopefully it will help you out as well.</p>]]></content:encoded>
			<wfw:commentRss>http://www.eriksmartt.com/blog/archives/1254/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Atlas demo: If Interface Builder made web apps</title>
		<link>http://www.eriksmartt.com/blog/archives/1173</link>
		<comments>http://www.eriksmartt.com/blog/archives/1173#comments</comments>
		<pubDate>Wed, 07 Oct 2009 14:38:04 +0000</pubDate>
		<dc:creator>erik</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.eriksmartt.com/blog/?p=1173</guid>
		<description><![CDATA[Neat demo of upcoming Cappuccino UI development tool Atlas. If you&#8217;ve used XCode and Interface Builder, the app will seem rather familiar:]]></description>
			<content:encoded><![CDATA[<p>Neat demo of upcoming <a href="http://cappuccino.org/">Cappuccino</a> UI development tool <a href="http://280atlas.com/">Atlas</a>.  If you&#8217;ve used XCode and Interface Builder, the app will seem rather familiar:</p>
<p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="437" height="293" id="viddler"><param name="movie" value="http://www.viddler.com/simple_on_site/1db9bf4d" /><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="true" /><embed src="http://www.viddler.com/simple_on_site/1db9bf4d" width="437" height="293" type="application/x-shockwave-flash" allowScriptAccess="always" allowFullScreen="true" name="viddler" ></embed></object></p>]]></content:encoded>
			<wfw:commentRss>http://www.eriksmartt.com/blog/archives/1173/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ubiquity command to expand hyperlinks</title>
		<link>http://www.eriksmartt.com/blog/archives/588</link>
		<comments>http://www.eriksmartt.com/blog/archives/588#comments</comments>
		<pubDate>Tue, 07 Oct 2008 15:58:51 +0000</pubDate>
		<dc:creator>erik</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[productivity]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.eriksmartt.com/blog/?p=588</guid>
		<description><![CDATA[Another simple Ubiquity command for the morning&#8230; This one, called &#8216;expandlinks&#8217;, finds all links on the current page and adds the link&#8217;s URL (as a hyperlink itself) next to each existing link label. This is particularly handy if you&#8217;re going to print an HTML page for later reference. CmdUtils.CreateCommand({ name: "expandlinks", homepage: "http://eriksmartt.com/blog/", author: { [...]]]></description>
			<content:encoded><![CDATA[<p>Another simple <a href="https://wiki.mozilla.org/Labs/Ubiquity">Ubiquity</a> command for the morning&#8230; This one, called &#8216;expandlinks&#8217;, finds all links on the current page and adds the link&#8217;s URL (as a hyperlink itself) next to each existing link label.  This is particularly handy if you&#8217;re going to print an HTML page for later reference.</p>
<pre><code>
CmdUtils.CreateCommand({
  name: "expandlinks",
  homepage: "http://eriksmartt.com/blog/",
  author: { name: "Erik Smartt"},
  license: "MPL",
  preview: "Expands all hyperlinks, showing link locations.",
  execute: function() {
    var doc =  Application.activeWindow.activeTab.document;
    jQuery(doc.body).find("a").each(function(i) {
        jQuery(this).after(" &amp;lt;&lt;a href='" + this.href + "'&gt;" + this.href + "&lt;/a&gt;&amp;gt;");
    });
  }
})
</code></pre>
<p>And yes, it will be much easier to subscribe to these commands once I gather them into a JS file for Ubiquity.  For now, you can copy/paste into the command editor if you&#8217;re interested in trying it out.</p>]]></content:encoded>
			<wfw:commentRss>http://www.eriksmartt.com/blog/archives/588/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Even simpler then my last Ubiquity examp&#8230;</title>
		<link>http://www.eriksmartt.com/blog/archives/547</link>
		<comments>http://www.eriksmartt.com/blog/archives/547#comments</comments>
		<pubDate>Wed, 27 Aug 2008 20:21:39 +0000</pubDate>
		<dc:creator>erik</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[productivity]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.eriksmartt.com/blog/?p=547</guid>
		<description><![CDATA[Even simpler then my last Ubiquity example, this one came about from an actual project need to verify a custom character-length based text truncation filter. Select the text in the browser, invoke Ubiquity, and type: charcount CmdUtils.CreateCommand({ name: "charcount", takes: {"text to count chars in": noun_arb_text}, preview: function( pblock, argText ) { pblock.innerHTML = argText.text.length; [...]]]></description>
			<content:encoded><![CDATA[<p>Even simpler then my last <a href="https://wiki.mozilla.org/Labs/Ubiquity">Ubiquity</a> example, this one came about from an actual project need to verify a custom character-length based text truncation filter.  Select the text in the browser, invoke Ubiquity, and type: charcount</p>
<p><code>
<pre>
CmdUtils.CreateCommand({
  name: "charcount",
  takes: {"text to count chars in": noun_arb_text},
  preview: function( pblock, argText ) {
    pblock.innerHTML = argText.text.length;
  }
})
</pre>
<p></code></p>
<p><b>Update</b>: See comments below for Ubiquity 0.5 compatibility updates</p>]]></content:encoded>
			<wfw:commentRss>http://www.eriksmartt.com/blog/archives/547/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Extending Mozilla Ubiquity &#8212; stock charts and Google Finance lookup</title>
		<link>http://www.eriksmartt.com/blog/archives/543</link>
		<comments>http://www.eriksmartt.com/blog/archives/543#comments</comments>
		<pubDate>Wed, 27 Aug 2008 20:08:24 +0000</pubDate>
		<dc:creator>erik</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[productivity]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.eriksmartt.com/blog/?p=543</guid>
		<description><![CDATA[Mozilla Ubiquity was released this week, and the functionality was so inspiring that I couldn&#8217;t help playing with it. For those that haven&#8217;t checked it out yet, think &#8220;Quicksilver inside Firefox&#8221;&#8230; or perhaps, &#8220;a contextually-aware command-line for your web browser.&#8221; If that still doesn&#8217;t mean anything to you&#8230; well, you&#8217;ll have to watch the intro [...]]]></description>
			<content:encoded><![CDATA[<p><a href="https://wiki.mozilla.org/Labs/Ubiquity">Mozilla Ubiquity</a> was released this week, and the functionality was so inspiring that I couldn&#8217;t help playing with it.  For those that haven&#8217;t checked it out yet, think &#8220;Quicksilver inside Firefox&#8221;&#8230; or perhaps, &#8220;a contextually-aware command-line for your web browser.&#8221;  If that still doesn&#8217;t mean anything to you&#8230; well, you&#8217;ll have to <a href="http://labs.mozilla.com/2008/08/introducing-ubiquity/">watch the intro video</a> ;-)</p>
<p>Extending Ubiquity&#8217;s vocabulary is done via JavaScript, and <a href="https://wiki.mozilla.org/Labs/Ubiquity/Ubiquity_0.1_Author_Tutorial">the developer docs</a> are pretty straight forward.</p>
<p>The docs cover Hello World, so I figured that the next best intro test would be a way to lookup stock charts and quotes.  Here&#8217;s the result of a few minutes hacking on it:</p>
<p><code>
<pre>
CmdUtils.CreateCommand({
  name: "tik",
  takes: {"stock ticker symbol": noun_arb_text},
  preview: function( pblock, argText ) {
    var charturl = "http://chart.finance.yahoo.com/c/1y/a/" + argText.text;
    pblock.innerHTML = "<img src='" + charturl + "' />";
  },
  execute: function( argText ) {
    var windowManager = Components.classes["@mozilla.org/appshell/window-mediator;1"]
                      .getService(Components.interfaces.nsIWindowMediator);
    var browserWindow = windowManager.getMostRecentWindow("navigator:browser");
    var browser = browserWindow.getBrowser();
    var url = "http://finance.google.com/finance?q=" + argText.text;
    browser.loadOneTab(url, null, null, null, false, false);
  }
})
</pre>
<p></code></p>
<p>This command introduces a &#8216;tik&#8217; keyword, which loads 1-year stock symbol charts (from Yahoo) into the preview pane, and allows click-through to open a new tab for the Google Finance page of said symbol.  Note that the preview-pane doesn&#8217;t always resize correctly for the chart to fit (though you can generally make it happen by typing a space after the stock symbol.)  I guess there&#8217;s still some work to do there.</p>]]></content:encoded>
			<wfw:commentRss>http://www.eriksmartt.com/blog/archives/543/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Book Review: &#8220;Practical Django Projects&#8221;</title>
		<link>http://www.eriksmartt.com/blog/archives/506</link>
		<comments>http://www.eriksmartt.com/blog/archives/506#comments</comments>
		<pubDate>Tue, 22 Jul 2008 02:08:23 +0000</pubDate>
		<dc:creator>erik</dc:creator>
				<category><![CDATA[books]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.eriksmartt.com/blog/?p=506</guid>
		<description><![CDATA[Summary: Targeted at developers wanting to learn Django by building example applications rather then (or in addition to) reading the docs and man pages The reader builds three working applications by following along The examples are based on up-to-date Django features (ie., a 2008 build) Lesson&#8217;s focused on using Django (not on Django&#8217;s inner workings) [...]]]></description>
			<content:encoded><![CDATA[<h3>Summary:</h3>
<ul>
<li>Targeted at developers wanting to learn Django by building example applications rather then (or in addition to) reading the docs and man pages</li>
<li>The reader builds three working applications by following along</li>
<li>The examples are based on up-to-date Django features (ie., a 2008 build)</li>
<li>Lesson&#8217;s focused on using Django (not on Django&#8217;s inner workings)</li>
<li>Doesn&#8217;t waste time explaining Python and HTML (nor does it dive deep explaining the how/why of what you&#8217;re doing in the examples)</li>
<li>Introduces the reader to powerful Django features &#8212; covering a wide range of capability</li>
<li>Examples focus on designing for code reuse (and leading by example, by integrating with existing reusable apps and Python libraries)</li>
<li>Offers an alternative approach to learning, focused on relevant, practical examples</li>
</ul>
<h3>Background:</h3>
<p><a href="http://www.amazon.com/gp/product/1590599969?ie=UTF8&#038;tag=eriksmarttcom&#038;linkCode=as2&#038;camp=1789&#038;creative=9325&#038;creativeASIN=1590599969">Practical Django Projects</a><img src="http://www.assoc-amazon.com/e/ir?t=eriksmarttcom&#038;l=as2&#038;o=1&#038;a=1590599969" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> (<a href="http://www.apress.com/book/view/1590599969">Apress book description</a>) was written by <a href="http://www.b-list.org/">James Bennett</a>, release manager and contributor to the <a href="http://djangoproject.com/">Django</a> Web Framework. It was published by <a href="http://www.apress.com/">Apress</a> in 2008.  This was Bennett&#8217;s first book.</p>
<p>Full disclosure: I was provided with a free, review-copy of the book by Apress.</p>
<h3>The Book:</h3>
<p>Practical Django Projects introduces the reader to the Django Web Framework by example.  It takes the reader step-by-step through three example projects: a basic CMS, a blog application (called <a href="http://code.google.com/p/coltrane-blog/">Coltrane</a>, which powers the author&#8217;s personal blog), and a code-sharing/snippets site (called <a href="http://code.google.com/p/cab/">Cab</a>, which powers <a href="http://www.djangosnippets.org/">http://www.djangosnippets.org/</a>.)  The examples cover real-world problems (and integration tasks) that developers are likely to be interested in, and leaves the reader with three working Django applications.</p>
<p>The lessons are spread across eleven chapters:</p>
<ol>
<li><b>Welcome to Django</b> &#8212; a wonderfully short introduction that wastes no space explaining prerequisites (it assumes the reader knows Python)</li>
<li><b>Your First Django Site: A Simple CMS</b> &#8212; an introduction to the Django Admin and <a href="http://www.djangoproject.com/documentation/flatpages/">Flatpages</a></li>
<li><b>Customizing the Simple CMS</b> &#8212; customizing the Admin interface (adding <a href="http://tinymce.moxiecode.com/">TinyMCE</a>) and developing a simple, reusable search feature</li>
<li><b>A Django-Powered Weblog</b> &#8212; defining the basic models, and using <a href="http://code.google.com/p/django-tagging/">django-tagging</a> and <a href="http://www.djangoproject.com/documentation/generic_views/">Generic Views</a></li>
<li><b>Expanding the Weblog</b> &#8212; adding <a href="http://del.icio.us/">del.icio.us</a>-synced links, and custom categories</li>
<li><b>Templates for the Weblog</b> &#8212; more extensive use of Generic Views, template inheritance, and custom template tags</li>
<li><b>Finishing the Weblog</b> &#8212; using <a href="http://www.djangoproject.com/documentation/add_ons/">django.contrib</a>.comments and model signals to develop a moderation system with email notification and <a href="http://akismet.com/">Akismet</a> integration; Using <a href="http://www.djangoproject.com/documentation/syndication_feeds/">django.contrib.syndication</a> to add RSS/Atom feeds</li>
<li><b>A Social Code-Sharing Site</b> &#8212; building the initial models, integrating with the <a href="http://pygments.org/">pygments</a> syntax highlighter, and writing custom model managers</li>
<li><b>Form Processing in the Code-Sharing Application</b> &#8212; great examples of using <a href="http://www.djangoproject.com/documentation/newforms/">newforms</a> (much better then the <a href="http://www.amazon.com/gp/product/1590597257?ie=UTF8&#038;tag=eriksmarttcom&#038;linkCode=as2&#038;camp=1789&#038;creative=9325&#038;creativeASIN=1590597257">The Definitive Guide to Django</a><img src="http://www.assoc-amazon.com/e/ir?t=eriksmarttcom&#038;l=as2&#038;o=1&#038;a=1590597257" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />&#8216;s chapter on form processing)</li>
<li><b>Finishing the Code-Sharing Application</b> &#8212; more custom template tags, this time used with bookmarking and rating features</li>
<li><b>Writing Reusable Django Applications</b> &#8212; a summary of Bennett&#8217;s philosophy on decoupling application features into reusable components (with references to the UNIX saying, &#8220;do one thing, and do it well&#8221;)</li>
</ol>
<p>The examples focus on building applications the &#8220;Django way&#8221; &#8212; meaning that they heavily leverage Django features such as Generic Views, custom template tags, and the django.contrib package.  Each section starts by outlining the features to be developed, then walking the reader through model definitions, URLs, template design, and the request-handler (view) code.</p>
<p>While working through the three example applications, Bennett teaches the reader how to decouple applications from projects, how to think about (and look for) opportunities for code reuse, and how to integrate with other reusable Django applications.  The lessons aren&#8217;t so much &#8220;how does Django work&#8221;, but rather &#8220;how do you, as a developer, structure your projects to get the most out of the framework.&#8221;  Depending on your level of comfort using Django and Python, the lessons will either be a breeze, or ridiculously confusing.  (ie., there&#8217;s a lot of magic going on in the examples, and the book assumes that either you get it, you&#8217;re comfortable not knowing, or that you&#8217;ll figure out the finer bits when you need them.)</p>
<h4>The Core Message</h4>
<p>Ultimately, the book isn&#8217;t so much about learning Django, as it is about learning how to use Django properly (where properly is defined as the way in which the Django developers use Django.)  From this perspective, it&#8217;s quite successful.  The reader is shown a number of patterns and concepts that can be applied to any Django project.</p>
<p>Bennett wraps up the book with a chapter on design philosophy, but I think the overall lesson of the book is best summarized on page 124, with the following quote:</p>
<blockquote><p>
&#8230;this is the hallmark of a well-built Django application.  Installing it shouldn&#8217;t involve any more work than the following:</p>
<ol>
<li>Add it to <code>INSTALLED_APPS</code> and run <code>syncdb</code>.</li>
<li>Add a new URL pattern to route to its default URLConf.</li>
<li>Set up any needed templates.</li>
</ol>
</blockquote>
<p>This is the zen of pluggable Django applications.  It&#8217;s the path Bennett wants to help you start down.  The value of going down this path will depend on how often you&#8217;ll use Django in the future.</p>
<h3>Conclusion:</h3>
<p>Overall, I think the book will be more valuable for someone just getting started with Django, then someone who&#8217;s been hacking lower-level with the framework for awhile.  It&#8217;s a developer-focused, quick-start, &#8220;get you on the right foot&#8221; kind of book that I certainly would have appreciated more a few years ago.  The big question then, is whether this book is for you.  The answer depends on a couple things, with the most important being how you like to learn.  Do you prefer learning by example, or learning by reading the docs and building things on your own? <b>If you prefer to have an expert guide you step-by-step, then this book is for you.</b>  You&#8217;ll still need to poke around in the <a href="http://www.djangoproject.com/documentation/">Django documentation</a> to really grok how it all works, but this book will get you up to speed quickly.</p>
<p>If you&#8217;ve read the docs, done the online tutorials, and are still interested in picking up some best-practices on decoupling your code from your specific application (ie., learning how Django supports code reuse), then this may still be a book for you.  If you know you&#8217;ll be building a large application, the lessons in the book <b>might help prevent you from writing a single, monolithic application</b>, or at least give you some insight into how to organize and package your code.  Down the road you&#8217;ll thank yourself.</p>
<p>For me personally, I was actually looking forward to this book before it came out.  I think the Django docs online (as great as they are) can sometimes lack in providing best practices.  However, I&#8217;ve also been using the framework professionally for a number of years (to deploy personal, start-up, and enterprise-class web applications), and I&#8217;ve previously built and deployed a pluggable, multi-site, Django-based blog engine (with del.icio.us and Akismet integration, flexible moderation rules, etc.), so the idea of using a blog engine as the core example in the book was a bit disappointing.  That said, I did enjoy seeing another developer&#8217;s approach on solving the same problem, and I picked up a few nice tips around some of the more recent Django features.</p>
<p>If you&#8217;re looking to build a reusable code library (and you should be, if you&#8217;re going to build more then one Django project) and ensure that you&#8217;re using Django efficiently, this book will help point you down the right path and have you thinking about decoupling your architecture from the start.</p>]]></content:encoded>
			<wfw:commentRss>http://www.eriksmartt.com/blog/archives/506/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Netflix shows the world how not to treat your customers by dropping Profiles &#8212; Updated: Change of plans</title>
		<link>http://www.eriksmartt.com/blog/archives/466</link>
		<comments>http://www.eriksmartt.com/blog/archives/466#comments</comments>
		<pubDate>Fri, 20 Jun 2008 20:46:56 +0000</pubDate>
		<dc:creator>erik</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[media]]></category>
		<category><![CDATA[product-management]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.eriksmartt.com/blog/?p=466</guid>
		<description><![CDATA[Like many other Netflix customers, I received the &#8220;Important News Regarding Netflix Profiles&#8221; email this week stating that Netflix &#8220;will be eliminating Profiles, the feature that allowed you to set up separate DVD Queues under one account, effective September 1, 2008.&#8221; Upon reading it, the claim sounded so absurd that I assumed it was phishing/spam. [...]]]></description>
			<content:encoded><![CDATA[<p>Like many other Netflix customers, I received the &#8220;Important News Regarding Netflix Profiles&#8221; email this week stating that Netflix &#8220;<i>will be eliminating Profiles, the feature that allowed you to set up separate DVD Queues under one account, effective September 1, 2008.</i>&#8221;  Upon reading it, the claim sounded so absurd that I assumed it was phishing/spam.  Seriously.</p>
<p>Sadly, the news started showing up with quotes and claims that the statement may actually be true.  &#8220;<a href="http://www.hackingnetflix.com/2008/06/netflix-elimina.html">Netflix Eliminating Account Profiles</a>&#8221; (on hackingnetflix.com) claims that &#8220;<i>Netflix spokesperson Steve Swasey said that the decision to eliminate Profiles is a &#8216;final decision.&#8217;</i>&#8221;</p>
<p>Here&#8217;s the kicker though; The now famous email ends with, &#8220;<i>While it may be disappointing to see Profiles go away, this change will help us continue to improve the Netflix website for all our customers.</i>&#8221;  Really?  How so?</p>
<p>For those not familiar with Netflix Profiles, the feature was somewhat unique.  Instead of having a single persona per account, Netflix Profiles allowed a single account (ie., household) to setup multiple profiles (ie., husband, wife, kids, pets, etc.), so that each profile could manage their own rental queue.  It also allowed the main account holder (ie. the parents) to review the other profile&#8217;s queue (ie., the kids) and set limitations, like whether the profiles were allowed to rent R-rated movies.  The feature was amazingly helpful in eliminating arguments about who controlled the rental queue.</p>
<p>Removing features from a product can be a tough decision for any Product Manager.  Features that are rarely used are easy to toss aside; But (market differentiating) <b>features that customers love should never be thrown out without helping the customers replace or replicate the same benefit in another manner.</b>  In this case, Netflix dropped a much-loved feature, but left their customers without an alternative (other then opening more Netflix accounts, which isn&#8217;t a likely reaction for irritated customers.)</p>
<p>For more:</p>
<ul>
<li><a href="http://www.techconsumer.com/2008/06/19/netflix-eliminating-profiles-tells-us-we-dont-own-our-data/">Netflix Eliminating Profiles: Tells Us We Don’t Own Our Data</a></li>
</ul>
<p><b>[Update: 2008-06-30]</b> Complaining works!  Netflix just announced that they are keeping Profiles:</p>
<blockquote><p>
You spoke, and we listened. We are keeping Profiles. Thank you for all the calls and emails telling us how important Profiles are.</p>
<p>We are sorry for any inconvenience we may have caused. We hope the next time you hear from us we will delight, and not disappoint, you.
</p></blockquote>]]></content:encoded>
			<wfw:commentRss>http://www.eriksmartt.com/blog/archives/466/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Time to backup gmail if this is true&#8230;</title>
		<link>http://www.eriksmartt.com/blog/archives/439</link>
		<comments>http://www.eriksmartt.com/blog/archives/439#comments</comments>
		<pubDate>Wed, 23 Apr 2008 03:52:34 +0000</pubDate>
		<dc:creator>erik</dc:creator>
				<category><![CDATA[experience]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.eriksmartt.com/blog/?p=439</guid>
		<description><![CDATA[If this post is true, there&#8217;s now a really good reason to backup gmail locally: &#8220;Is google shutting down email accounts if they suspect hijacking?&#8220;]]></description>
			<content:encoded><![CDATA[<p>If this post is true, there&#8217;s now a <strong>really</strong> good reason to backup gmail locally: &#8220;<a href="http://experiencecurve.com/archives/is-google-shutting-down-email-accounts-if-they-suspect-hijacking">Is google shutting down email accounts if they suspect hijacking?</a>&#8220;</p>]]></content:encoded>
			<wfw:commentRss>http://www.eriksmartt.com/blog/archives/439/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reading &#8220;The Definitive Guide to Django&#8221;; Verdict: A solid learning reference for a beginning/intermediate Django user</title>
		<link>http://www.eriksmartt.com/blog/archives/411</link>
		<comments>http://www.eriksmartt.com/blog/archives/411#comments</comments>
		<pubDate>Tue, 01 Jan 2008 01:07:50 +0000</pubDate>
		<dc:creator>erik</dc:creator>
				<category><![CDATA[books]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.eriksmartt.com/blog/archives/411</guid>
		<description><![CDATA[Last week I received a review-copy of the new &#8220;The Definitive Guide to Django&#8221; book from Apress. I hadn&#8217;t planned on buying the book since it seemed a little too beginner-focused; but I agreed to give it an honest reading, so I happily dove in with an &#8220;it&#8217;s Python, of course I&#8217;m going to like [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I received a review-copy of the new &#8220;<a href="http://www.djangobook.com/">The Definitive Guide to Django</a>&#8221; book from <a href="http://www.apress.com/">Apress</a>.  I hadn&#8217;t planned on buying the book since it seemed a little too beginner-focused; but I agreed to give it an honest reading, so I happily dove in with an &#8220;it&#8217;s <a href="http://python.org/">Python</a>, of course I&#8217;m going to like it&#8221; attitude.</p>
<h3>Background</h3>
<p>The book was written by <a href="http://www.holovaty.com/">Adrian Holovaty</a> and <a href="http://www.jacobian.org/">Jacob Kaplan-Moss</a>, the creators and &#8220;Benevolent Dictators&#8221; of the <a href="http://www.djangoproject.com/">Django</a> Web Framework.  It was Holovaty and Kaplan-Moss&#8217; first book, and, I believe, meant to be the first Django book to market.  The book was drafted online; open to peer-review and community feedback; and ultimately published under the GNU Free Documentation License.</p>
<p>From the get-go, the print edition had a few inherent market challenges to face: First, the entire book is available online, for free, at: &lt;<a href="http://www.djangobook.com/">http://www.djangobook.com/</a>&gt;.  Second, in many ways the book is a re-hash of the docs available at &lt;<a href="http://www.djangoproject.com/documentation/">http://www.djangoproject.com/documentation/</a>&gt;, which are also free.  Third, the book covers Django 0.96, not SVN.  (0.96 is technically the latest-snapshot release, but a lot has changed since 0.96.)  And finally, the $45 MSRP could be seen as a little steep for what is effectively a printed copy of a free, online book.</p>
<h3>The print experience</h3>
<p>Diving in, the book takes the reader through the basic installation process, provides a brief background on how the framework came to be (and why you want one), then steps through the major features (ie., the template system, ORM, URLconfs, generic views, etc.)  It&#8217;s what you&#8217;d expect from a technical reference &#8212; no fluff, and straight to the details.  There are plenty of code snippets to learn from, and the sidebar notes tend to be insightful.</p>
<p>Since it wasn&#8217;t new material for me, the book was a fairly quick read; but the experience of reading Django documentation in book-form was actually quite fascinating.  There&#8217;s something about settling into a comfortable chair with a book, pen, and highlighter that you just can&#8217;t get with online documentation.  Perhaps it was just a little more noticeable given the material.  When I read the Django docs online, I tend to skim over them while trying to solve a problem.  I use them as a reference more then a learning tool, and it&#8217;s usually while actively coding, thus my brain is partially distracted with whatever it is I&#8217;m building.</p>
<p>With a physical book, you can unplug, step away from the computer, and give the material your undivided attention.  This isolation from distraction results in a much deeper understanding of the text.  <b>This is the real the value of the printed book &mdash; it&#8217;s an opportunity to digest online documentation in an environment more conducive to learning and retention.</b></p>
<h3>My general take-aways and observations</h3>
<ul>
<li>The book definitely has a beginner/intermediate feel to it, but only in the sense of a beginner Django user &mdash; not a beginner Web developer or Python programmer.  I&#8217;m curious how well the book is received by folks who are beginners at Django and dynamic Web development since the text brings up a lot of complex topics in Web development that aren&#8217;t really explained.  (Ex., database administration, server clustering, manipulating HTTP headers, etc.)</li>
<li>The breadth of the book is impressive, but in some ways, the book really feeds you through a firehose, so to speak.  It throws a lot of new concepts at the reader and doesn&#8217;t always explain why you&#8217;d need to know them, or how you might use them in the real world.  For someone deploying a site with Django, it will be good to know that all these features are available, but it might take awhile before they need to use them (if ever.)</li>
<li>The book does touch on some of the more advanced Django features (like extending the template system and writing custom middleware), which was nice, but some topics are reserved for the appendix and get limited coverage (ex., model managers and &#8216;Q&#8217; queries.)  Others, like the Sites Framework, are given good exposure, but not so much that the reader is left with a clear picture on when to use them and what their limitations are.</li>
<li>The <a href="http://www.djangobook.com/en/1.0/chapter07/">forms processing</a> chapter was a bit lighter then what I was hoping for &#8212; especially given that the current newforms documentation still trends toward &#8220;read the source code.&#8221;  It provides enough to start using newforms if your form needs are pretty basic, but doesn&#8217;t address creating your own widgets, or any of the fun stuff you can do once you start dynamically generating and manipulating newforms objects.</li>
<li>It might have been nicer if the examples in the book were a little more tied together, perhaps all focused on building a single example project and showing how the various features are used in real-world applications.  (The example of the book-publisher&#8217;s app was a reoccurring theme, but not so strongly that each chapter applied it&#8217;s new learnings to it.)</li>
<li>The Deploying Django: &#8220;Going Big&#8221; sub-section provides a nice infrastructure graphics for how high-traffic systems might be setup, but once you get to the point of being &#8220;big&#8221;, you need to architect for it, and that&#8217;s really outside of the scope of this book.  For this section, it might have been nice to reference other resources on scaling infrastructure, and perhaps pointing out some of the ways that Django can be optimized for performance and horizontal scaling.  (For example, one of the Django projects we put into production at work will happily support 1,200 requests/second, but the database layer and session middleware have been reworked a bit, and the content caching approach is a little different then the standard Django offering.)</li>
<li>On the more positive side, <b>even as someone who&#8217;s been using Django for some time, I still learned a few new tricks</b>, and I was reminded of a few features that I could be taking better advantage of.  (And when you do this stuff professionally, every shortcut and productivity gain has monetary value &mdash; avoiding even a half-hour of debugging pays for the cost of this book.)</li>
<li><b>This book would make a fantastic read for a back-end developer joining a project that is already using Django</b>.  I normally tell new developers to go through the Python Tutorial at &lt;<a href="http://python.org/doc/tut/">http://python.org/doc/tut/</a>&gt; if they&#8217;re new to Python, then to complete the Django Tutorials at &lt;<a href="http://www.djangoproject.com/documentation/">http://www.djangoproject.com/documentation/</a>&gt; before trying to grok any in-progress Django project.  Now I have a third reference (though I might still suggest that they walk through the tutorials first, so that they have some context when reading the book.  Otherwise, there are just too many new concepts to do a straight read-through and still grasp it all.)</li>
</ul>
<h3>Summary</h3>
<p>The market needed a good Django book, and this one delivered a solid reference for the framework.  Arguably, it&#8217;s not really a &#8220;Beginner&#8217;s Guide to Django&#8221;, but hopefully it covers enough of the basics that future books can focus on best practices and more advanced techniques. (On a related note, there&#8217;s apparently an upcoming &#8220;Practical Django Projects&#8221; book, also from Apress, that will focus more on building &#8220;reusable Django applications from start to finish&#8221;.  This might actually make for a better beginner&#8217;s book, depending on how it turns out. [Via <a href="http://www.b-list.org/weblog/2007/dec/12/speaking-and-writing/">The B-List: Speaking and writing</a>].)</p>
<p>The million-dollar question then, is &#8220;<b>Should you buy this book?</b>&#8221;  My answer ended up being a bit more positive then I expected, but there are two parts:  First, if you&#8217;re a front-end developer only, you don&#8217;t need this book.  You can just read <a href="http://www.djangobook.com/en/1.0/chapter04/">Chapter 4: The Django Template System</a> online, and then use the &#8220;<a href="http://www.djangoproject.com/documentation/templates/">Django Templates: Guide for HTML authors</a>&#8221; section of the online docs as a reference.  For back-end developers, the story is different. If you&#8217;re going to just &#8220;read it while you hack&#8221;, then you might as well just read it online; but if you&#8217;re serious about building applications with Django (especially if you&#8217;re new to it), then you should consider the book and investing the time to step away from the computer and really let yourself get into it.  Unless you are an active contributor to Django (which I&#8217;m not, just to be clear), the odds are pretty good that you&#8217;ll learn something new, even if you&#8217;re already using Django today.</p>]]></content:encoded>
			<wfw:commentRss>http://www.eriksmartt.com/blog/archives/411/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Changing the URL experience with typography</title>
		<link>http://www.eriksmartt.com/blog/archives/383</link>
		<comments>http://www.eriksmartt.com/blog/archives/383#comments</comments>
		<pubDate>Wed, 11 Jul 2007 20:49:19 +0000</pubDate>
		<dc:creator>erik</dc:creator>
				<category><![CDATA[experience]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.eriksmartt.com/blog/archives/383</guid>
		<description><![CDATA[I started using the Locationbar&#178; Firefox add-on a few weeks ago, and I&#8217;ve been amazed at how significantly it changes the experience with URLs. The interesting thing is that I already think about URLs as RESTful commands&#8230; but when you see URLs broken apart visually into distinct domain, path, and argument sections, the visual interpretation [...]]]></description>
			<content:encoded><![CDATA[<p>I started using the <a href="https://addons.mozilla.org/en-US/firefox/addon/4014">Locationbar</a>&sup2; Firefox add-on a few weeks ago, and I&#8217;ve been amazed at how significantly it changes the experience with URLs.  The interesting thing is that I already think about URLs as <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST</a>ful commands&#8230; but when you <b>see</b> URLs broken apart visually into distinct domain, path, and argument sections, the visual interpretation quickly change from &#8220;a bunch of random text that the browser understands&#8221;, into &#8220;a domain-name/brand, and specific service&#8221;.</p>
<p>It&#8217;s difficult to explain without visuals, so let&#8217;s start with a traditional looking URL:</p>
<p><img src="http://farm2.static.flickr.com/1403/778007092_8232b29552.jpg" width="300" height="70" alt="es_url_oldschool" /></p>
<p>The traditional-looking URL is a bunch of text.  We recognize it as a URL, and typically market it as a full-text string.  However, many sites use non-friendly URLs (think Vignette CURLs, for those who know what I&#8217;m talking about), in which case URLs are often massive strings full of seemingly random characters.  When surfing sites with such URLs, the browser&#8217;s location bar becomes something you ignore until you&#8217;re ready to type in a new address.</p>
<p>Now let&#8217;s look at a Location&#8217;ized version of the same URL:</p>
<p><img src="http://farm2.static.flickr.com/1408/778007102_b92ad6e67f.jpg" width="300" height="70" alt="es_url_locationized" /></p>
<p>Quite different!  The Location&#8217;ized URL is a distinct representation of a domain name (&#8220;eriksmartt.com&#8221;), and a service (&#8220;blog&#8221;).  Information we don&#8217;t need, which normally just causes visual clutter (like the &#8216;/&#8217; characters), has been greyed-out, and brand-recognition remains strong.</p>
<p>Here&#8217;s another example:</p>
<p><img src="http://farm2.static.flickr.com/1031/778825915_b9c669f9a5.jpg" width="300" height="70" alt="lolcat_url_example" /></p>
<p>Just looking at that URL, it&#8217;s pretty clear what site I was on, and what I was asking for &#8212; which is exactly what a URL is.  Writing out <a href="http://flickr.com/photos/tags/lolcat/">http://flickr.com/photos/tags/lolcat</a> loses some of this meaning.  It becomes a single address, rather then a service and a request.</p>
<p>Of course, clever domain-names can lose some of their brand recognition using this approach:</p>
<p><img src="http://farm2.static.flickr.com/1300/778992553_ea38e50ae3.jpg" width="300" height="70" alt="delicious_locationized" /></p>
<p>Still, I&#8217;ve already grown so accustom to seeing URLs as Locationbar&sup2; displays them, that it feels disappointing to use browsers lacking this capability.  I&#8217;ve also found the tool to be extremely handy while developing websites, making it very clear which server I&#8217;m accessing, and what request I made.</p>
<p><a href="http://www.urbandictionary.com/define.php?term=ymmv">YMMV</a>, but I definitely recommend trying it out &#8212; and I&#8217;d love to hear about your experience using the add-on!</p>]]></content:encoded>
			<wfw:commentRss>http://www.eriksmartt.com/blog/archives/383/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
