<?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/"
	>

<channel>
	<title>Code. Design. Explore. &#187; Code</title>
	<atom:link href="http://www.janisb.com/blog/category/code/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.janisb.com/blog</link>
	<description>The World Through the Eyes of John Brennan</description>
	<pubDate>Mon, 11 Jan 2010 16:51:17 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Displaying synced data spatially and temporally (map+timeline)</title>
		<link>http://www.janisb.com/blog/2009/01/displaying-synced-data-spatially-and-temporally-maptimeline/</link>
		<comments>http://www.janisb.com/blog/2009/01/displaying-synced-data-spatially-and-temporally-maptimeline/#comments</comments>
		<pubDate>Tue, 06 Jan 2009 01:52:52 +0000</pubDate>
		<dc:creator>John Brennan</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.janisb.com/blog/?p=188</guid>
		<description><![CDATA[I&#8217;m excited to tell you about my first &#8220;real&#8221; contribution to open source!  Sure, I&#8217;ve given my feedback on various forums over the years, but I have never worked on a project solely for open source&#8230; until now!  And I&#8217;m excited about it.
Last year I needed to built a component to view data both spatially [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m excited to tell you about my first &#8220;real&#8221; contribution to open source!  Sure, I&#8217;ve given my feedback on various forums over the years, but I have never worked on a project solely for open source&#8230; until now!  And I&#8217;m excited about it.</p>
<p>Last year I needed to built a component to view data both spatially and temporally for work.  I tried searching for something open source, but nothing existed.  All I found was lots of people asking for such a component.  So in Nov of 2007 I decided to build it.  Why post it in Jan of 2009 then?  Well let&#8217;s just say &#8220;process.&#8221;  It&#8217;s not easy to release open source software when you work at a company.  But anyway&#8230;</p>
<p>The component uses and synchronizes <a rel="nofollow" href="http://openlayers.org/">OpenLayers</a> map API with MIT&#8217;s <a rel="nofollow" href="http://simile.mit.edu/timeline/">SIMILE timeline</a>.</p>
<p>A <a href="http://maptimeline.googlecode.com/svn/trunk/samples/external_source.html">demo is available here</a>.</p>
<p>And the project can be found here:</p>
<p><a href="http://code.google.com/p/maptimeline/">http://code.google.com/p/maptimeline/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.janisb.com/blog/2009/01/displaying-synced-data-spatially-and-temporally-maptimeline/feed/</wfw:commentRss>
		</item>
		<item>
		<title>command line script to delete .svn files / folders</title>
		<link>http://www.janisb.com/blog/2008/12/command-line-script-to-delete-svn-files-folders/</link>
		<comments>http://www.janisb.com/blog/2008/12/command-line-script-to-delete-svn-files-folders/#comments</comments>
		<pubDate>Mon, 29 Dec 2008 19:22:30 +0000</pubDate>
		<dc:creator>John Brennan</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[bash]]></category>

		<category><![CDATA[command]]></category>

		<guid isPermaLink="false">http://www.janisb.com/blog/?p=173</guid>
		<description><![CDATA[I was trying to copy the base of a project for another project I was starting.  I figure it&#8217;s smart to write this down as I will probably refer to it again.
find ./ -name ".svn" &#124; xargs rm -Rf
]]></description>
			<content:encoded><![CDATA[<p>I was trying to copy the base of a project for another project I was starting.  I figure it&#8217;s smart to write this down as I will probably refer to it again.</p>
<pre>find ./ -name ".svn" | xargs rm -Rf</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.janisb.com/blog/2008/12/command-line-script-to-delete-svn-files-folders/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Auto seed database for testing using Fixtures</title>
		<link>http://www.janisb.com/blog/2008/09/auto-seed-database-for-testing-using-fixtures/</link>
		<comments>http://www.janisb.com/blog/2008/09/auto-seed-database-for-testing-using-fixtures/#comments</comments>
		<pubDate>Fri, 12 Sep 2008 18:04:00 +0000</pubDate>
		<dc:creator>John Brennan</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[Kohana]]></category>

		<guid isPermaLink="false">http://www.janisb.com/blog/?p=95</guid>
		<description><![CDATA[I learned about the concept of Fixtures when I started looking into the CakePHP framework.  I implemented something similar for one of my projects using Pylons.
I&#8217;ve been using the Kohana framework for about a week now.  It has the performance of Code Igniter, while making some better design decisions imo (like the ability [...]]]></description>
			<content:encoded><![CDATA[<p>I learned about the concept of Fixtures when I started looking into the <a href="http://www.cakephp.org/">CakePHP</a> framework.  I implemented something similar for one of my projects using Pylons.</p>
<p>I&#8217;ve been using the <a href="http://www.kohanaphp.com">Kohana</a> framework for about a week now.  It has the performance of Code Igniter, while making some better design decisions imo (like the ability to actually access the GET parameters).  Although many people love all the magic that comes with CakePHP (hats off to them for a superb framework!), I prefer to know how the data is traveling through the pipes.  This is especially important with new frameworks where sometimes you have to dig into the core to see whats happening.</p>
<p>A test fixture allows you to have a consistent database for testing.  Sure you could write a bunch of SQL statements, but that&#8217;s not easily maintainable.  <strong>Read:</strong> Schema changes will break your scripts.  Fixtures can be XML, JSON, or the newly popular YAML (which I will demonstrate here).</p>
<p><a href="http://en.wikipedia.org/wiki/YAML">YAML</a> is a human-readable data serialization format.  It&#8217;s like XML, but without all the braces.  Please see the link for more as I want to focus on fixtures for this article.</p>
<p>Great, you&#8217;re back.  Now back to fixtures.  I follow the convention of clearing the database when the test runs and leaving it as is when my test finishes.  This allows me the chance to go back into the db if I want to check its state.  Besides, wiping the db won&#8217;t serve any purpose other than to lose that state.</p>
<p>The most important library is my Fixtures library.  It takes a reference to a database instance and a fixtures path.  You will then call its load method to load the file into the database.  That&#8217;s it!  I&#8217;m using the <a href="http://spyc.sourceforge.net/">Spyc</a> library to parse YAML.</p>
<p>I&#8217;ll give you the quick flow of things, post snippets of a couple files and package up all the code for your downloading pleasure.</p>
<h2>Flow</h2>
<ol>
<li>Unit test controller gets called</li>
<li>Instantiates Fixture class</li>
<li>Loads all YAML files from unit_test config file</li>
<li>Tests run</li>
</ol>
<h2>Code explained</h2>
<p><strong>/application/controllers/unit_test.php</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td><td class="code"><pre class="php"><span style="color: #000000; font-weight: bold;">class</span> Unit_test_Controller <span style="color: #000000; font-weight: bold;">extends</span> Controller <span style="color: #66cc66;">&#123;</span>
&nbsp;
	const ALLOW_PRODUCTION = <span style="color: #000000; font-weight: bold;">FALSE</span>;
&nbsp;
	<span style="color: #808080; font-style: italic;">// stores database config group to use</span>
	protected <span style="color: #0000ff;">$DB_GROUP</span> = <span style="color: #000000; font-weight: bold;">NULL</span>;
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> index<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
	<span style="color: #66cc66;">&#123;</span>
        <span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">DB_GROUP</span> = Kohana::<span style="color: #006600;">config</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'unit_test.database_group'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
		<span style="color: #808080; font-style: italic;">// setup a db reference</span>
        <span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">db</span> = Database::<span style="color: #006600;">instance</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">DB_GROUP</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
		<span style="color: #808080; font-style: italic;">// load fixtures for test</span>
        <span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">fixture</span> = <span style="color: #000000; font-weight: bold;">new</span> Fixture<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">db</span>, Kohana::<span style="color: #006600;">config</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'unit_test.fixtures_path'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
		<span style="color: #0000ff;">$fixt_files</span> = Kohana::<span style="color: #006600;">config</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'unit_test.load_fixtures'</span><span style="color: #66cc66;">&#41;</span>;
		<span style="color: #b1b100;">foreach</span> <span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$fixt_files</span> <span style="color: #b1b100;">as</span> <span style="color: #0000ff;">$fixt</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>
			<span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">fixture</span>-&gt;<span style="color: #006600;">load</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$fixt</span><span style="color: #66cc66;">&#41;</span>;
		<span style="color: #66cc66;">&#125;</span>
&nbsp;
		<span style="color: #808080; font-style: italic;">// Run tests and show results!</span>
		<span style="color: #000066;">echo</span> <span style="color: #000000; font-weight: bold;">new</span> Unit_Test;
	<span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></td></tr></table></div>

<p>This is your entry point into the test harness.  You&#8217;ll call it just like any other controller.  While the Database library uses the &#8216;default&#8217; group defined in <em>/config/database.php</em>, I want to use a separate Database connection.  I defined it as &#8216;test&#8217; and I have defined that name in the <em>/config/unit_test.php</em> file.</p>
<p>It creates a new Fixture object with the database connection and path where it can find my fixtures.  Then calls load() for each file defined (in the config file).</p>
<p><strong>Bug:</strong> As I am posting this I just found a bug where if you have multiple files that you are loading that use the same table all but the last set of inserts will be removed because I am truncating in the load file.  I should just do this to the table once per run.</p>
<p><strong>/application/libraries/Fixture.php</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
</pre></td><td class="code"><pre class="php"><span style="color: #000000; font-weight: bold;">class</span> Fixture_Core <span style="color: #66cc66;">&#123;</span>
    protected <span style="color: #0000ff;">$db</span>;
    protected <span style="color: #0000ff;">$fixture_path</span>;
&nbsp;
    <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$db</span>, <span style="color: #0000ff;">$fixure_path</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>
        <span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span>!<span style="color: #000066;">is_dir</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$fixure_path</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>
            <span style="color: #000066;">exit</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;{$fixure_path} is not a valid path to fixtures.  Please redefine in config.&quot;</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span>
        <span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">db</span> = <span style="color: #0000ff;">$db</span>;
        <span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">fixture_path</span> = <span style="color: #0000ff;">$fixure_path</span>;
    <span style="color: #66cc66;">&#125;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">/*
     * loads fixture data $fixt into corresponding table
     *
     * @param String $fixt Name of fixture file to load (without the extension). Found in the fixtures folder of the test directory
     */</span>
    <span style="color: #000000; font-weight: bold;">function</span> load<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$fixt</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>
        <span style="color: #0000ff;">$Spyc</span> = <span style="color: #000000; font-weight: bold;">new</span> Spyc;
        <span style="color: #0000ff;">$fixt_data</span> = <span style="color: #0000ff;">$Spyc</span>-&gt;<span style="color: #006600;">YAMLLoad</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">fixture_path</span>.DIRECTORY_SEPARATOR.<span style="color: #0000ff;">$fixt</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
        <span style="color: #808080; font-style: italic;"># $fixt_data is supposed to be an associative array outputted by spyc from YAML file</span>
        <span style="color: #b1b100;">foreach</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$fixt_data</span> <span style="color: #b1b100;">as</span> <span style="color: #0000ff;">$table</span>=&gt;<span style="color: #0000ff;">$data</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>
    	     <span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">db</span>-&gt;<span style="color: #006600;">query</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;TRUNCATE TABLE {$table}&quot;</span><span style="color: #66cc66;">&#41;</span>;
            <span style="color: #b1b100;">foreach</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$data</span> <span style="color: #b1b100;">as</span> <span style="color: #0000ff;">$idx</span>=&gt;<span style="color: #0000ff;">$row</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>
                <span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">db</span>-&gt;<span style="color: #006600;">insert</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$table</span>, <span style="color: #0000ff;">$row</span><span style="color: #66cc66;">&#41;</span>;
            <span style="color: #66cc66;">&#125;</span>
        <span style="color: #66cc66;">&#125;</span>
    <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></td></tr></table></div>

<p>Here I&#8217;m essentially leveraging the parsing of the Spyc library which handles the loading and parsing of the YAML file.  Then I&#8217;m simply inserting it into the appropriate table.</p>
<p>Hope that helps!!</p>
<h2>Download</h2>
<p><a href='http://www.janisb.com/blog/wp-content/uploads/2008/09/kohana_test_fixtures.zip'>kohana_test_fixtures.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.janisb.com/blog/2008/09/auto-seed-database-for-testing-using-fixtures/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Stop polluting my global namespace</title>
		<link>http://www.janisb.com/blog/2008/09/stop-polluting-my-global-namespace/</link>
		<comments>http://www.janisb.com/blog/2008/09/stop-polluting-my-global-namespace/#comments</comments>
		<pubDate>Thu, 11 Sep 2008 22:17:49 +0000</pubDate>
		<dc:creator>John Brennan</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[bestpractices]]></category>

		<category><![CDATA[patterns]]></category>

		<guid isPermaLink="false">http://www.janisb.com/blog/?p=94</guid>
		<description><![CDATA[If it was 1999 and you were telling you&#8217;re friends to visit your web site then this post probably wouldn&#8217;t fit you.
Luckily for us, it&#8217;s not 1999 and calling what I do &#8220;building a website&#8221; frankly just hurts my feelings (I much prefer web app because web sites were always static pages without much business [...]]]></description>
			<content:encoded><![CDATA[<p>If it was 1999 and you were telling you&#8217;re friends to visit your <em>web site</em> then this post probably wouldn&#8217;t fit you.</p>
<p>Luckily for us, it&#8217;s not 1999 and calling what I do &#8220;building a website&#8221; frankly just hurts my feelings (I much prefer <em>web app</em> because web sites were always static pages without much business logic behind it.)</p>
<p>I haven&#8217;t lived on this planet long enough to see many programming languages evolve&#8230; that is until JavaScript.  When I first started building web sites (yes, I called it that back then), the JavaScript I wrote looked like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript">&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Party like it was <span style="color: #CC0000;">1999</span>&lt;/title&gt;
&lt;script language=<span style="color: #3366CC;">&quot;javascript&quot;</span>&gt;
&lt;!--
<span style="color: #003366; font-weight: bold;">function</span> changeBg<span style="color: #66cc66;">&#40;</span>obj, newColor<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
    obj.<span style="color: #006600;">style</span>.<span style="color: #006600;">backgroundColor</span> = newColor;
<span style="color: #66cc66;">&#125;</span>
--&gt;
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;a href=<span style="color: #3366CC;">&quot;#&quot;</span> onClick=<span style="color: #3366CC;">&quot;changeBg(this, '#00aaff'); return false;&quot;</span>&gt;change background&lt;/a&gt;
...</pre></div></div>

<p>This code makes me cringe!  For several reasons.  Let me explain&#8230;</p>
<ol>
<li>I never want to see onClick events embedded in your HTML (or presentation markup).  Instead, move it to an external file and link it.  <em>This goes for the majority of your JavaScript calls, like changeBg() too</em></li>
<li>You are flooding the global namespace with new functions.  Not only is it unmaintainable, it&#8217;s also completely devoid of any organization.</li>
</ol>
<h2>The Right Way</h2>
<p>Thanks to guys like <a href="http://paulbuchheit.blogspot.com/">Paul Buchheit</a> (G-Mail), we have been able to uncover other extremely useful aspects of JavaScript.  As JavaScript comes into its own we need to embrace best practices and write beautiful code.</p>
<p>At work, I&#8217;ve noticed that while other engineers write great Java code, their JavaScript sometimes looks like a last minute thought.  I don&#8217;t think this is due to laziness, but rather that they are unaware of the fact that you can apply design patterns to JavaScript just as you would other languages.  Usually.</p>
<h2>JavaScript Patterns</h2>
<p>As I started to write this post I found a bunch of other bloggers already felt the itch and wrote very informative articles on this same topic.  So to avoid reinventing the wheel&#8230;</p>
<p><a href="http://www.klauskomenda.com/code/javascript-programming-patterns/#singleton">Singleton</a><br />
<a href="http://www.klauskomenda.com/code/javascript-programming-patterns/#module">Module Pattern</a><br />
<a href="http://www.klauskomenda.com/code/javascript-programming-patterns/#revealing">Revealing Module Pattern</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.janisb.com/blog/2008/09/stop-polluting-my-global-namespace/feed/</wfw:commentRss>
		</item>
		<item>
		<title>What did Prototype do?!?</title>
		<link>http://www.janisb.com/blog/2008/08/what-did-prototype-do/</link>
		<comments>http://www.janisb.com/blog/2008/08/what-did-prototype-do/#comments</comments>
		<pubDate>Wed, 06 Aug 2008 16:46:06 +0000</pubDate>
		<dc:creator>John Brennan</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Tips]]></category>

		<category><![CDATA[prototype]]></category>

		<guid isPermaLink="false">http://www.janisb.com/blog/?p=92</guid>
		<description><![CDATA[I&#8217;ve been using Prototype + Scriptaculous for my current project.  It surprises me that I haven&#8217;t encountered this problem until just now though.
I noticed some funky behavior today when I tried iterating over an array of values.  I have loved Prototype for some time.  It&#8217;s elegant style, ease of DOM manipulation, and [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using <a href="http://www.prototypejs.com">Prototype</a> + <a href="http://script.aculo.us/">Scriptaculous</a> for my current project.  It surprises me that I haven&#8217;t encountered this problem until just now though.</p>
<p>I noticed some funky behavior today when I tried iterating over an array of values.  I have loved Prototype for some time.  It&#8217;s elegant style, ease of DOM manipulation, and ummm.. it&#8217;s style!</p>
<p>However, the behavior I just encountered I don&#8217;t care for.  I know that Prototype modifies (extends) the builtin objects of Javascript, namely Array and Object.  I like the added bang for the buck that I get.  But look at this test:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">var</span> l_a = <span style="color: #66cc66;">&#91;</span><span style="color: #3366CC;">&quot;A&quot;</span>,<span style="color: #3366CC;">&quot;B&quot;</span>,<span style="color: #3366CC;">&quot;C&quot;</span><span style="color: #66cc66;">&#93;</span>;
<span style="color: #003366; font-weight: bold;">var</span> l_r = <span style="color: #3366CC;">&quot;&quot;</span>;
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> l_x <span style="color: #000066; font-weight: bold;">in</span> l_a<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>l_r += l_x + <span style="color: #3366CC;">&quot; &quot;</span>;<span style="color: #66cc66;">&#125;</span>
<span style="color: #000066;">alert</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>l_r == <span style="color: #3366CC;">&quot;0 1 2 &quot;</span><span style="color: #66cc66;">&#41;</span> + <span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> + l_r<span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>What do you think that prints out?  Chances are you&#8217;re wrong.  <span id="more-92"></span>It actually prints out the array&#8230; followed by all the functions used to extend the Array object.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">false</span>
<span style="color: #CC0000;">0</span> <span style="color: #CC0000;">1</span> <span style="color: #CC0000;">2</span> each eachSlice all any collect detect findAll grep include inGroupsOf inject invoke max min partition pluck reject sortBy toArray zip size inspect find select member entries _reverse _each clear first last compact flatten without reduce uniq clone toJSON call</pre></div></div>

<p>The same sort of problem happens if you were to use object literals instead of arrays.  Let me show you the bad and good ways to use each of them.</p>
<h2>Array looping, BAD</h2>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">var</span> l_a = <span style="color: #66cc66;">&#91;</span><span style="color: #3366CC;">&quot;A&quot;</span>,<span style="color: #3366CC;">&quot;B&quot;</span>,<span style="color: #3366CC;">&quot;C&quot;</span><span style="color: #66cc66;">&#93;</span>;
<span style="color: #003366; font-weight: bold;">var</span> l_r = <span style="color: #3366CC;">&quot;&quot;</span>;
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> l_x <span style="color: #000066; font-weight: bold;">in</span> l_a<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>l_r += l_x + <span style="color: #3366CC;">&quot; &quot;</span>;<span style="color: #66cc66;">&#125;</span>
<span style="color: #000066;">alert</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>l_r == <span style="color: #3366CC;">&quot;A B C &quot;</span><span style="color: #66cc66;">&#41;</span> + <span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> + l_r<span style="color: #66cc66;">&#41;</span>;
&nbsp;
Output:
<span style="color: #003366; font-weight: bold;">false</span>
A B C each eachSlice all any collect detect findAll grep include inGroupsOf inject invoke max min partition pluck reject sortBy toArray zip size inspect find select member entries _reverse _each clear first last compact flatten without reduce uniq clone toJSON call</pre></div></div>

<h2>Array looping, GOOD</h2>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">var</span> l_a = <span style="color: #66cc66;">&#91;</span><span style="color: #3366CC;">&quot;A&quot;</span>,<span style="color: #3366CC;">&quot;B&quot;</span>,<span style="color: #3366CC;">&quot;C&quot;</span><span style="color: #66cc66;">&#93;</span>;
<span style="color: #003366; font-weight: bold;">var</span> l_r = <span style="color: #3366CC;">&quot;&quot;</span>;
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> l_x = <span style="color: #CC0000;">0</span>;l_x &lt; l_a.<span style="color: #006600;">length</span>;l_x++<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>l_r += l_a<span style="color: #66cc66;">&#91;</span>l_x<span style="color: #66cc66;">&#93;</span> + <span style="color: #3366CC;">&quot; &quot;</span>;<span style="color: #66cc66;">&#125;</span>
<span style="color: #000066;">alert</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>l_r == <span style="color: #3366CC;">&quot;A B C &quot;</span><span style="color: #66cc66;">&#41;</span> + <span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> + l_r<span style="color: #66cc66;">&#41;</span>;
&nbsp;
Output:
<span style="color: #003366; font-weight: bold;">true</span>
A B C</pre></div></div>

<h2>Object looping, BAD</h2>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">var</span> l_a = <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>;
l_a<span style="color: #66cc66;">&#91;</span><span style="color: #3366CC;">&quot;a&quot;</span><span style="color: #66cc66;">&#93;</span> = <span style="color: #3366CC;">&quot;A&quot;</span>;
l_a<span style="color: #66cc66;">&#91;</span><span style="color: #3366CC;">&quot;b&quot;</span><span style="color: #66cc66;">&#93;</span> = <span style="color: #3366CC;">&quot;B&quot;</span>;
l_a<span style="color: #66cc66;">&#91;</span><span style="color: #3366CC;">&quot;c&quot;</span><span style="color: #66cc66;">&#93;</span> = <span style="color: #3366CC;">&quot;C&quot;</span>;
<span style="color: #003366; font-weight: bold;">var</span> l_i;
<span style="color: #003366; font-weight: bold;">var</span> l_r = <span style="color: #3366CC;">&quot;&quot;</span>;
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> l_x = <span style="color: #CC0000;">0</span>;l_x &lt; l_a.<span style="color: #006600;">length</span>;l_x++<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>l_r += l_a<span style="color: #66cc66;">&#91;</span>l_x<span style="color: #66cc66;">&#93;</span> + <span style="color: #3366CC;">&quot; &quot;</span>;<span style="color: #66cc66;">&#125;</span>
<span style="color: #000066;">alert</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>l_r == <span style="color: #3366CC;">&quot;A B C &quot;</span><span style="color: #66cc66;">&#41;</span> + <span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> + l_r<span style="color: #66cc66;">&#41;</span>;
&nbsp;
Output:
<span style="color: #003366; font-weight: bold;">false</span></pre></div></div>

<h2>Object looping, GOOD</h2>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #003366; font-weight: bold;">var</span> l_a = <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>;
l_a<span style="color: #66cc66;">&#91;</span><span style="color: #3366CC;">&quot;a&quot;</span><span style="color: #66cc66;">&#93;</span> = <span style="color: #3366CC;">&quot;A&quot;</span>;
l_a<span style="color: #66cc66;">&#91;</span><span style="color: #3366CC;">&quot;b&quot;</span><span style="color: #66cc66;">&#93;</span> = <span style="color: #3366CC;">&quot;B&quot;</span>;
l_a<span style="color: #66cc66;">&#91;</span><span style="color: #3366CC;">&quot;c&quot;</span><span style="color: #66cc66;">&#93;</span> = <span style="color: #3366CC;">&quot;C&quot;</span>;
<span style="color: #003366; font-weight: bold;">var</span> l_i;
<span style="color: #003366; font-weight: bold;">var</span> l_r = <span style="color: #3366CC;">&quot;&quot;</span>;
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> l_x <span style="color: #000066; font-weight: bold;">in</span> l_a<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span>l_r += l_x + <span style="color: #3366CC;">&quot; &quot;</span>;<span style="color: #66cc66;">&#125;</span>
<span style="color: #000066;">alert</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>l_r == <span style="color: #3366CC;">&quot;a b c &quot;</span><span style="color: #66cc66;">&#41;</span> + <span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> + l_r<span style="color: #66cc66;">&#41;</span>;
&nbsp;
Output:
<span style="color: #003366; font-weight: bold;">true</span>
a b c</pre></div></div>

<h2>Long story short&#8230;</h2>
<p>When using arrays always iterate over the elements with:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #000066; font-weight: bold;">for</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> l_x = <span style="color: #CC0000;">0</span>;l_x &lt; l_a.<span style="color: #006600;">length</span>;l_x++<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>When using object literals always iterate over the elements with:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span style="color: #000066; font-weight: bold;">for</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> l_x <span style="color: #000066; font-weight: bold;">in</span> l_a<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.janisb.com/blog/2008/08/what-did-prototype-do/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Tip with Bookmarklets</title>
		<link>http://www.janisb.com/blog/2008/08/tip-with-bookmarklets/</link>
		<comments>http://www.janisb.com/blog/2008/08/tip-with-bookmarklets/#comments</comments>
		<pubDate>Sat, 02 Aug 2008 22:41:33 +0000</pubDate>
		<dc:creator>John Brennan</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Tips]]></category>

		<category><![CDATA[bookmarklet]]></category>

		<guid isPermaLink="false">http://www.janisb.com/blog/?p=89</guid>
		<description><![CDATA[A few months ago I built a bookmarklet for the app I&#8217;m currently developing for the government.  A bookmarklet is essentially JavaScript embedded in a link and placed in your browser&#8217;s bookmarks folder or toolbar.
The bookmarklet I build is meant to enable analysts to clip content from the web and add it to a [...]]]></description>
			<content:encoded><![CDATA[<p>A few months ago I built a bookmarklet for the app I&#8217;m currently developing for the government.  A bookmarklet is essentially JavaScript embedded in a link and placed in your browser&#8217;s bookmarks folder or toolbar.</p>
<p>The bookmarklet I build is meant to enable analysts to clip content from the web and add it to a &#8220;notebook.&#8221;  These notebooks are used by analysts to organize information and collaborate.  We are also leveraging a triple store backend to connect similar keywords and make assertions which will ultimately allow these analysts to find more relevant information and catch the bad guy.  But enough of what I do, let&#8217;s get back to the bookmarklet stuff.</p>
<p>So I had originally had all the code inside the link.  The real problem with this is that new versions require an &#8220;install&#8221; and that is not what the web was about.  So after some thinking I realized that I could just embed a file in the bookmarklet, so updates can be made seamlessly (or once the file cache expires).</p>
<p>While I was going through this process I came across some strange behavior when trying to attach the script element to the BODY.  Another caveat to this approach was that if some arcaic website is still using FRAMESET there actually won&#8217;t be a BODY tag.  More of a reason to attach it to HEAD.</p>
<p>Code is below:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript">javascript:<span style="color: #003366; font-weight: bold;">function</span> loadScript<span style="color: #66cc66;">&#40;</span>scriptURL<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> scriptElem = document.<span style="color: #006600;">createElement</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'SCRIPT'</span><span style="color: #66cc66;">&#41;</span>;
  scriptElem.<span style="color: #006600;">setAttribute</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'language'</span>, <span style="color: #3366CC;">'JavaScript'</span><span style="color: #66cc66;">&#41;</span>;
  scriptElem.<span style="color: #006600;">setAttribute</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'src'</span>, scriptURL<span style="color: #66cc66;">&#41;</span>;
  document.<span style="color: #006600;">getElementsByTagName</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'head'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">appendChild</span><span style="color: #66cc66;">&#40;</span>scriptElem<span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>
loadScript<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'http://localhost/bookmarklet.js'</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.janisb.com/blog/2008/08/tip-with-bookmarklets/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Velocity Conf - My takeaways</title>
		<link>http://www.janisb.com/blog/2008/06/velocity-conf-my-takeaways/</link>
		<comments>http://www.janisb.com/blog/2008/06/velocity-conf-my-takeaways/#comments</comments>
		<pubDate>Thu, 26 Jun 2008 07:04:22 +0000</pubDate>
		<dc:creator>John Brennan</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[Velocity08]]></category>

		<category><![CDATA[VelocityConf08]]></category>

		<guid isPermaLink="false">http://www.janisb.com/blog/?p=88</guid>
		<description><![CDATA[San Francisco was great!  I got to take part in a great conference, network with other people facing similar challenges and catch up with some of my old friends in the area.
It&#8217;s amazing how many people are doing &#8220;startups&#8221; in that area.  I put startups in quotes though because a startup isn&#8217;t anything [...]]]></description>
			<content:encoded><![CDATA[<p>San Francisco was great!  I got to take part in a great conference, network with other people facing similar challenges and catch up with some of my old friends in the area.</p>
<p>It&#8217;s amazing how many people are doing &#8220;startups&#8221; in that area.  I put startups in quotes though because a startup isn&#8217;t anything less than a great idea that hasn&#8217;t been fully executed yet.  Second, I should clarify &#8220;amazing&#8221; too.  Obviously Silicon Valley is the mecca for high-tech startups in the world, but you don&#8217;t actually realize what that means until you start to talk to people there.  Here in San Diego I can count the number of people I know working on startups on one hand.  Ok, maybe 2 hands if you count people wanting to get involved, but haven&#8217;t made that first step yet.</p>
<p>While I was catching up with Sameer and Shirin over dinner they were telling me how the majority of their friends (aside from working at Google) work in startups.</p>
<p>That said, here&#8217;s a summary of what I got from the Velocity conference.  I had a great time and <a href="http://en.oreilly.com/velocity2008/public/schedule/speaker/1669">Steve Souders</a> and the O&#8217;Reilly team really did a great job putting this together.  My only suggestion for next time would be to show some more real examples.  For example, I know that in order to scale you need to shard, partition and replicate the databases.  You need to profile and test, then profile and test again.  Maybe I was looking for more of a workshop, but it was very informative and I hope you return next year!</p>
<p><span id="more-88"></span></p>
<p>Here&#8217;s what I got&#8230;</p>
<h2>Performance Overview and Tools</h2>
<ul>
<li>Plan for perf from day 1</li>
<li>Set expectations ahead of time
<ul>
<li>why do users of World of Warcraft accept downtime each week (and pay for the service), but users of Friendster/twitter don&#8217;t?  Expectations.</li>
</ul>
</li>
<li>Even after you solved YOUR performance problems, ads become the root of the problem!
<ul>
<li>Artur has a <a href="http://www.google.com/notebook/public/15466807879718028470/BDQqRIwoQ65Gisasj#SDR24IgoQr6X2sqsj">cool hack</a> to overwrite document.write to get around this problem</li>
</ul>
</li>
<li>Measure the right things
<ul>
<li>No cache scenario is really important</li>
</ul>
</li>
<li>When optimizing perf you can&#8217;t just look at the mean average, you have to look at the median, percentile, and outliers too.</li>
<li>Automated testing and profiling needs to be part of the process!</li>
<li>keep historical records of how features perform</li>
<li>consider keeping some (small amount of) profiling code in production</li>
<li>Tools
<ul>
<li><a href="http://kite.keynote.com/">Kite</a>
<ul>
<li>Real-time testing from multiple locations</li>
<li>Interactively test perf from desktop, last mile, and cloud</li>
<li>available in Aug</li>
</ul>
</li>
<li><a href="http://code.google.com/p/jiffy-web/">Jiffy</a>
<ul>
<li>measure individual pieces of page rendering (script load, AJAX execution, page load, etc.) on every client</li>
<li>report those measurements and other metadata to a web server</li>
<li>aggregate web server logs into a database</li>
<li>generate reports</li>
<li>has Firebug plugin</li>
</ul>
</li>
<li><a href="http://research.microsoft.com/projects/doloto/">Doloto</a>
<ul>
<li>analyzes application workloads and automatically performs code splitting</li>
<li>code gets processed and only necessary initialization code gets transfers right away</li>
<li>the rest of the code is replaced by short stubs and transferred lazily in the background</li>
</ul>
</li>
<li><a href="http://cloudstatus.com:8000">CloudStatus</a>
<ul>
<li>Provide service to monitor uptime and availability for AWS, Google appengine, etc</li>
</ul>
</li>
<li><a href="http://www.fiddler2.com/fiddler2/">Fiddler</a> (profiling tool)
<ul>
<li>Written by my old mentor from Microsoft!</li>
<li>measure request size, page wgt</li>
<li>analyze caching, compression, page composition</li>
<li>simulate low-speed/high-latency connections</li>
<li>breakpoint debugging</li>
<li>traffic modification</li>
<li><a href="http://www.fiddler2.com/fiddler/Perf/">perf test walkthrough</a></li>
</ul>
</li>
<li>AOL PageTest
<ul>
<li>Online version: <a href="http://www.webpagetest.org/">http://www.webpagetest.org</a></li>
<li><a href="http://pagetest.wiki.sourceforge.net/">http://pagetest.wiki.sourceforge.net/</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>Optimizing Page Load Times</h2>
<ul>
<li>Apache changes
<ul>
<li>use gzip, far future expires and etag</li>
<li>Don&#8217;t use advanced compression (run time cost)</li>
</ul>
</li>
<li>Javascript changes
<ul>
<li>reduce DOM elements</li>
<li><a href="http://ajaxpatterns.org/On-Demand_Javascript">lazy load components</a></li>
<li>use GET unless you need POST</li>
<li>use JSON instead of XML (don&#8217;t want to walk the XML tree!)</li>
<li>minify with YUI compressor + HTTP compression</li>
<li>use jQuery</li>
</ul>
</li>
<li>Content changes
<ul>
<li><a href="http://www.julienlecomte.net/blog/2007/09/16/">minify JS+CSS as part of build process</a></li>
<li>render most of content on server side (instead of using JS+DOM for example)</li>
<li>fewer serialized actions</li>
<li>eliminated DNS lookup</li>
<li>move your contents closer to your customers (use a CDN)</li>
</ul>
</li>
<li>Trim cookies
<ul>
<li>moving them away from your root domain and root path &#8220;/&#8221; bc those will be sent with EVERY page request</li>
<li>compress cookies (heads) not just bodies</li>
<li>grouping multiple smaller files into fewer bigger ones (image clustering)</li>
<li>eliminating them by moving your static content to a different domain</li>
<li>trim down the # of requests and redirects (round trips)</li>
</ul>
</li>
<li>Work on improving perceived performance
<ul>
<li>cheat when you can by updating UI then do the work</li>
</ul>
</li>
<li>Unique tricks
<ul>
<li>After page load, download external CSS and JS for upcoming page views</li>
</ul>
</li>
<li>See my <a href="http://www.google.com/notebook/public/15466807879718028470/BDQqRIwoQ65Gisasj#SDUThIgoQmu3_uqsj">notes on Julien Lecomte&#8217;s High Performance Ajax</a> for more great tips</li>
</ul>
<h2>Optimizing Images</h2>
<ul>
<li>Choose PNG over GIF
<ul>
<li>avg savings of 20%</li>
</ul>
</li>
<li>Crushing PNGs
<ul>
<li>most image programs DO NOT optimize</li>
<li>cmdline tools:
<ul>
<li><a href="http://pmt.sourceforge.net/pngcrush">pngcrush</a></li>
<li>pngrewrite</li>
<li>optipng</li>
<li>pngout</li>
</ul>
</li>
<li>avg savings of 16%</li>
</ul>
</li>
<li>strip needless JPEG metadata</li>
<li>reducing their color palettes
<ul>
<li>convert truecolor PNG to palette PNG (PNG8)</li>
</ul>
<ul>
<li>PNG8 has 256 colors, truecolor has millions</li>
</ul>
</li>
<li>far future expires (harder than it seems)</li>
<li>combine images
<ul>
<li>use sprites</li>
</ul>
</li>
</ul>
<h2>Scaling</h2>
<ul>
<li>Use <a href="http://www.danga.com/memcached/">Memcached<br />
</a></p>
<ul>
<li>high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load.  Handles the majority of your reads.  It&#8217;s practically a requirement, but not a substitute for bad design!</li>
</ul>
</li>
<li>Use a CDN
<ul>
<li><a href="http://www.pantherexpress.net/">Panther</a> - cheap and good (recommended by someone from <a href="http://www.stardoll.com">stardoll.com</a>)</li>
<li>Akamai - expensive, but top of the line</li>
</ul>
</li>
<li>Increase cache hits (with edge caching)
<ul>
<li>doesn&#8217;t like <a href="http://www.squid-cache.org/">squid</a></li>
<li>loves <a href="http://varnish.projects.linpro.no/">varnish</a>
<ul>
<li>a bit unstable</li>
<li>segfaults under load (running trunk)</li>
</ul>
</li>
</ul>
</li>
<li>Database scaling options
<ul>
<li>Vertical partitioning - splits table columns into separate tables or even splitting of tables into separate databases.  You can use a view to read the data again, but can&#8217;t insert/delete from a view.  <strong>Speaker was against this approach.</strong></li>
<li>Replication
<ul>
<li>most apps are read intensive, which is handled by memcached</li>
<li>does not help to scale writes (bc all slaves in a master-slave setup must get written)</li>
</ul>
</li>
<li>Sharding
<ul>
<li>&#8220;only&#8221; solution for large scale apps</li>
<li>can be hard to implement if not designed for&#8230;needs planning</li>
<li>want most queries to be run on same shard
<ul>
<li>good: sharding blogs by user_id</li>
<li>bad: sharding by country_id (large portion can come from same country)</li>
</ul>
</li>
<li>techniques
<ul>
<li>fixed hash sharding</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>DB scaling tips
<ul>
<li>if you have problems bc foreign key obj, look if db offers cluster indexes.  will cut down on disk seeks.</li>
<li>app should be unaware of partition strategy. app should ask where a user lives and go get it</li>
<li>you start with a normalized db, but you need to denormalize when you start scaling</li>
<li>have triggers that hit processing nodes to figure out how to build a new row to add to db as denormalized data</li>
<li>if you are a brand new startup don&#8217;t worry about partitioning, sharding</li>
<li>better to launch to all then have a private beta and hope those users are still interested in 6 months</li>
<li>good to think about how you <em><strong>could</strong></em> use sharding down the road</li>
</ul>
<ul>
<li>
<ul>
<li>
<ul>
<li>
<ul>
<li>even IDs on A, odd on B</li>
</ul>
</li>
<li>data dictionary
<ul>
<li>user 25 has data on server D</li>
<li>dict can become bottleneck</li>
</ul>
</li>
<li>mixed hashing</li>
</ul>
</li>
<li><a href="http://www.hivedb.com/">HiveDB</a></li>
<li><a href="http://www.hscale.org/">HSCALE</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>Operations</h2>
<ul>
<li>Think about how your architecture will scale when design it, but don&#8217;t shard or partition until you have to.  You&#8217;re bottlenecks might not be what you think.
<ul>
<li>LinkedIn underestimated the number of events/messages that would occur in the system.  To scale they had to denormalize and duplicate that event for each user it was sent to.</li>
<li>SmugMug didn&#8217;t realize they would get 1000s of comments on a single photo, so they needed to re-architecture how they handle comments.</li>
<li>SmugMug was logging all people that were viewing the photos, but after a huge traffic burst the site crumbled.  They had to adjust how they were logging (I didn&#8217;t pick up how).</li>
</ul>
</li>
<li>The Cloud
<ul>
<li>There needs to be an MVC framework for the backend, much like the MVC frameworks that exist today for the frontend (RoR, CakePHP, Pylons)</li>
<li>Data centers are unsustainable in their current form.  Energy costs will double in next 5 yrs.  We need Active power management.  Basically, when you leave the room, turn off the light.  Which means power down servers that you don&#8217;t need.  Virtualize.</li>
<li>You beat complexity by automating it</li>
</ul>
</li>
<li>Cloud computing services
<ul>
<li><a href="http://www.rightscale.com">RightScale</a> - leverages AWS EC2</li>
<li>AWS</li>
<li>b-hive</li>
<li>joyent</li>
<li>gogrid</li>
<li>Verio</li>
<li>EngineYard</li>
<li>3tera</li>
<li>sun <a href="http://powerofnetwork.com/">powerofnetwork.com</a></li>
</ul>
<ul>
<li><a href="http://eucalyptus.cs.ucsb.edu/">Eucalyptus</a> (open-source)
<ul>
<li>open-source software infrastructure for implementing cloud computing on clusters</li>
<li>compatible with EC2</li>
<li>wants to be the common denominator</li>
<li>doesn&#8217;t focus on the scalability</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>Tuning Recommendations</h2>
<ul>
<li><a href="http://www.danga.com/memcached/">Memcached</a>
<ul>
<li>network
<ul>
<li>ensure network processing is distributed across CPUs</li>
<li>bind memcached to CPUs not processing interrupts</li>
</ul>
</li>
<li>run memcached 1.2.5 with 4 threads (default)</li>
<li>use in 64-bit mode for a large cache size</li>
<li>run in multi-threaded mode</li>
</ul>
</li>
<li>MySQL
<ul>
<li>5.1 has several perf improvements over 5.0</li>
<li>joins over sub-queries</li>
<li>use limits</li>
<li>innodb</li>
<li>avoid too frequent FS flushes
<ul>
<li>innodb_flush_log_at_trx_commit = 2</li>
</ul>
</li>
<li><strong>separate read/write databases</strong></li>
<li>avoids trashing query cache</li>
</ul>
</li>
<li>Apache
<ul>
<li>network stack: tune TCP time-wait if handling lots of conn</li>
<li>do not load modules that you do not need (in httpd.conf)</li>
<li>tune ListenBacklog(8192), ServerLimit(2048), MaxClients(2048)</li>
</ul>
</li>
<li>PHP
<ul>
<li>turn off <em>safe_mode</em> if you don&#8217;t need it
<ul>
<li>safe_mode = off</li>
</ul>
</li>
<li>increase <em>realpath_cache_size</em> if you have lots of files
<ul>
<li>realpath_cache_size = 128K</li>
</ul>
</li>
<li>use <a href="http://xcache.lighttpd.net/wiki/Introduction">xcache </a>(stability problems? &#8230; participant in audience said he uses it in large scale and works great) or <a href="http://pecl.php.net/apc">APC</a></li>
</ul>
</li>
</ul>
<h2>Miscellaneous</h2>
<p>I was at the IE8 session and they spoke about a few new object enhancements.</p>
<ul>
<li>XDomainRequest - cross domain communication w/o server-side proxy</li>
<li>Improved XMLHTTPRequest obj now with timeout attribute</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.janisb.com/blog/2008/06/velocity-conf-my-takeaways/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Velocity Conf Day 1</title>
		<link>http://www.janisb.com/blog/2008/06/velocity-conf-day-1/</link>
		<comments>http://www.janisb.com/blog/2008/06/velocity-conf-day-1/#comments</comments>
		<pubDate>Tue, 24 Jun 2008 01:07:10 +0000</pubDate>
		<dc:creator>John Brennan</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[Interesting]]></category>

		<category><![CDATA[Tips]]></category>

		<category><![CDATA[Velocity08]]></category>

		<category><![CDATA[VelocityConf08]]></category>

		<guid isPermaLink="false">http://www.janisb.com/blog/?p=87</guid>
		<description><![CDATA[I&#8217;m currently attending the O&#8217;Reilly Conference, Velocity Web Performance and Operations.  It&#8217;s the first of its kind, focusing on building web applications that scale.  My focus for the conference is to build on top of what I already know and dive deeper into performance best practice, database tuning, achieving more with less, launching [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m currently attending the O&#8217;Reilly Conference, <a href="http://en.oreilly.com/velocity2008/public/content/home">Velocity Web Performance and Operations</a>.  It&#8217;s the first of its kind, focusing on building web applications that scale.  My focus for the conference is to build on top of what I already know and dive deeper into performance best practice, database tuning, achieving more with less, launching in the cloud, and performance/profiling tools to track these trends.</p>
<p>My notes will be available live <a href="http://www.google.com/notebook/public/15466807879718028470/BDQqRIwoQ65Gisasj">here</a>:</p>
<p><a href="http://www.google.com/notebook/public/15466807879718028470/BDQqRIwoQ65Gisasj"></a><em>Feel free to leave your comments if their are specific questions you want asked.<br />
</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.janisb.com/blog/2008/06/velocity-conf-day-1/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Avoid annoying session timeouts with an AJAX heartbeat</title>
		<link>http://www.janisb.com/blog/2008/05/avoid-annoying-session-timeouts-with-an-ajax-heartbeat/</link>
		<comments>http://www.janisb.com/blog/2008/05/avoid-annoying-session-timeouts-with-an-ajax-heartbeat/#comments</comments>
		<pubDate>Fri, 09 May 2008 01:52:33 +0000</pubDate>
		<dc:creator>John Brennan</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.janisb.com/blog/?p=61</guid>
		<description><![CDATA[Jeff Atwood made an interesting comment on his blog, Coding Horror, about how to take advantage of AJAX to send sort-of heartbeat back to the server to keep the session from expiring.  I think this is a great idea.  Getting automatically logged out is extremely annoying (unless of course it&#8217;s my bank in [...]]]></description>
			<content:encoded><![CDATA[<p>Jeff Atwood made an interesting comment on his blog, <a href="http://www.codinghorror.com/blog/archives/001100.html">Coding Horror</a>, about how to take advantage of AJAX to send sort-of heartbeat back to the server to keep the session from expiring.  I think this is a great idea.  Getting automatically logged out is extremely annoying (unless of course it&#8217;s my bank in which case I&#8217;m appreciative).</p>
<p>From his post:</p>
<blockquote><p>As a user, I can say pretty unequivocally that session expiration sucks. Is it really so unreasonable to start doing something in your web browser, walk away for an hour &#8212; maybe even for a few hours &#8212; then come back and expect things to just work?</p>
<p>As programmers, I think we can do better. It is possible. I am inundated with session timeout messages every day from a variety of sources, but I&#8217;ve never once seen a session expiration message from gmail, for example. Here&#8217;s what I suggest:</p>
<p>Create a background JavaScript process in the browser that sends regular heartbeats to the server. Regenerate a new cookie with timed expiration, say, every 5 or 10 minutes.</p>
<p><a href="http://www.codinghorror.com/blog/archives/001100.html">Continue reading &#8216;Your Session Has Timed Out&#8217;&#8230;</a></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.janisb.com/blog/2008/05/avoid-annoying-session-timeouts-with-an-ajax-heartbeat/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Zero to 60 with Pylons… in just minutes (Part 3)</title>
		<link>http://www.janisb.com/blog/2008/05/zero-to-60-with-pylons-in-just-minutes-part-3/</link>
		<comments>http://www.janisb.com/blog/2008/05/zero-to-60-with-pylons-in-just-minutes-part-3/#comments</comments>
		<pubDate>Tue, 06 May 2008 01:56:26 +0000</pubDate>
		<dc:creator>John Brennan</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[Pylons]]></category>

		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.janisb.com/blog/?p=44</guid>
		<description><![CDATA[The Presentation
Without presentation a web page is just text.  In the early days of building web sites styles and colors were mixed with JavaScript and large animated gifs.  Yes, during those days they were referred to as &#8220;web sites,&#8221; no one called them &#8220;web apps&#8221; yet.  And to be frank, with all [...]]]></description>
			<content:encoded><![CDATA[<h2>The Presentation</h2>
<p>Without presentation a web page is just text.  In the early days of building web sites styles and colors were mixed with JavaScript and large animated gifs.  Yes, during those days they were referred to as &#8220;web sites,&#8221; no one called them &#8220;web apps&#8221; yet.  And to be frank, with all that work that went into it that hurt my feelings.  Anyway, today I&#8217;m going to go beyond just showing how to get Mako working with your templates, but go as far as show you a better way to structure your templates in a Rails-like fashion.</p>
<p>I&#8217;m going to leave explain Mako to the <a href="http://www.makotemplates.org/">developers</a>, but in exchange I will give you some real examples.</p>
<p>Some of my methods are borrowed for Ruby on Rails.  I essentially have 3 parts to my presentation layer &#8212; layouts, views, and elements.</p>
<p><span id="more-44"></span></p>
<h2>Layouts, views, and elements oh my!</h2>
<p>A <strong>layout </strong>is the largest of the 3 containers and contains the page’s chrome (header, footer, sidebar) as well as all page scripts and stylesheets.</p>
<p>A <strong>view </strong>is the meat of the page. This is where all the content resides. Views are organized into folders based on their respective controller. For example,  the home controller would have a folder called home where all of its views would reside.</p>
<p>An <strong>element</strong> is a component that may be shared by multiple views. For example, the home controller may have 2 different views, say the welcome screen and a dashboard screen.  Both views might want to share pieces of the view that are the same.  These would be elements. Elements are located within a specific view folder.</p>
<p>Below is a figure of the relationship:</p>
<p><img class="alignnone size-medium wp-image-57" title="layout-view-grid" src="http://www.janisb.com/blog/wp-content/uploads/2008/05/layout-view-grid-300x253.gif" alt="Figure showing the relationship between layouts, views, and elements" width="300" height="253" /><br/></p>
<p>And here is what the file structure would look like:</p>
<p><img class="alignnone size-full wp-image-58" title="template-file-structure" src="http://www.janisb.com/blog/wp-content/uploads/2008/05/template-file-structure.gif" alt="" width="167" height="255" /><br style="clear:both"/></p>
<h2>Layout details</h2>
<p>Let&#8217;s get started by looking at the layout.  As I said before, this is the chrome of the page.  I like to keep all my external scripts (CSS and JavaScript) in 1 place though.  At first it wasn&#8217;t so straightforward with Mako, but by overwriting function definitions this is possible.</p>
<p>Here&#8217;s a bare bones default layout I have created for this project.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
</pre></td><td class="code"><pre class="html4strict"><span style="color: #009900;">&lt;%
# 
# layouts/default.mako
# The default layout to wrap the page contents.
#
%<span style="color: #000000; font-weight: bold;">&gt;</span></span>
#########################################################
#########################################################
### Begin HTML Template
###
<span style="color: #00bbdd;">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01//EN&quot; &quot;http://www.w3.org/TR/html4/strict.dtd&quot;&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;html</span> xmlns=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/xhtml&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;head&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">http-equiv</span>=<span style="color: #ff0000;">&quot;content-type&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;text/html; charset=utf-8&quot;</span> /<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;title&gt;</span></span>My first app<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/title&gt;</span></span>
&nbsp;
${ h.javascript_include_tag('global', builtins=True) }
${ h.stylesheet_link_tag('/css/styles.css',media='all') }
${self.additional_head_tags()}
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #808080; font-style: italic;">&lt;!--
###
### Scripts to execute once DOM is loaded
   function init() {
      ${self.additional_jscript_init()}
   }
   Event.observe(window, &quot;load&quot;, init);
&nbsp;
###
### Custom scripts for the specific page inheriting this layout
   ${self.additional_jscript()}
//--&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/head&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;body&gt;</span></span>
&nbsp;
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;wrap&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
### **********************************
### HEADER
### **********************************
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;header&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;h1&gt;</span></span>Simple Pylons Examples - My First App<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h1&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span>
&nbsp;
### **********************************
### MAIN CONTENT
### **********************************
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;main&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      ${ next.body() }
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span>
&nbsp;
### **********************************
### SIDEBAR
### **********************************
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;sidebar&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      ${self.sidebar()}
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/body&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/html&gt;</span></span>
### End HTML Template
###
#########################################################
#########################################################
### Define funcs that may be inherited and overwritten in child templates
###
<span style="color: #009900;">&lt;%def <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;additional_head_tags()&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;</span>/%def&gt;</span>
<span style="color: #009900;">&lt;%def <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;additional_jscript_init()&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;</span>/%def&gt;</span>
<span style="color: #009900;">&lt;%def <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;additional_jscript()&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;</span>/%def&gt;</span>
<span style="color: #009900;">&lt;%def <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;sidebar()&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;</span>/%def&gt;</span></pre></td></tr></table></div>

<p>You might have noticed that aside from the common HTML declarations I have a few other python expressions that make function calls and look like that are pulling in additional content.  If you noticed that, you are right!</p>
<p>I have set up a simple way to get JavaScript code included when the DOM loads, the ability to load other external script files, as well as modify the sidebar.</p>
<p>For example, I&#8217;m telling Mako to take all JavaScript initialization calls and place them at line 26.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>26
</pre></td><td class="code"><pre class="python">$<span style="color: black;">&#123;</span><span style="color: #008000;">self</span>.<span style="color: black;">additional_jscript_init</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#125;</span></pre></td></tr></table></div>

<p>Towards the bottom of the page I am defining these functions, although I plan to overwrite them in the views, which I will show you next.</p>
<h2>It&#8217;s all about the View</h2>
<p>Although the layout is the chrome of the page, your view is the entry point, and the doorway from the controller out to the user.</p>
<p>An entry point in your controller would look something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">return</span> render<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;/home/list.mako&quot;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Here we are calling the <em>list view</em> for the <em>home controller</em>.  The view will then decide what layout it should use, bring in any elements it needs, fill in any places where variables need to be filled, and send it off to the user.</p>
<p>Here is an example view of the list view:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
</pre></td><td class="code"><pre class="html4strict"><span style="color: #009900;">&lt;%inherit file=<span style="color: #ff0000;">&quot;../layouts/default.mako&quot;</span>/<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;">&lt;%
# 
# templates/home/list.mako 
# Displays list of user names to demonstrate end-to-end
#
%<span style="color: #000000; font-weight: bold;">&gt;</span></span>
#########################################################
#########################################################
### Override inherited funcs
###
###############################
### additional_head_tags()
<span style="color: #009900;">&lt;%def <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;additional_head_tags()&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    ${parent.additional_head_tags()}
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;${h.url_for('javascript')}/example.js&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;</span>/%def&gt;</span>
###############################
### additional_jscript_init()
<span style="color: #009900;">&lt;%def <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;additional_jscript_init()&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    ${parent.additional_jscript_init()}
    modify_footer();
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;</span>/%def&gt;</span>
###############################
### sidebar()
<span style="color: #009900;">&lt;%def <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;sidebar()&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    ${parent.sidebar()}
    <span style="color: #009900;">&lt;%include file=<span style="color: #ff0000;">&quot;elements/sidebar.mako&quot;</span>/<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;</span>/%def&gt;</span>
###
#########################################################
#########################################################
### Begin HTML Template
###
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;h2&gt;</span></span>Welcome<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h2&gt;</span></span>
Hey, how are ya?</pre></td></tr></table></div>

<p>In line 1 we are telling the view what layout to use.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="python">&lt;%inherit <span style="color: #008000;">file</span>=<span style="color: #483d8b;">&quot;../layouts/default.mako&quot;</span>/&gt;</pre></td></tr></table></div>

<p>Starting in line 14, we are overwriting a function that we defined in our layout.  Since we don&#8217;t want to completely overwrite it thought, we make a call to the parent (the layout) first.  Here we are including an additional JavaScript file.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>14
15
16
17
</pre></td><td class="code"><pre class="html4strict"><span style="color: #009900;">&lt;%def <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;additional_head_tags()&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    ${parent.additional_head_tags()}
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;${h.url_for('javascript')}/example.js&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;</span>/%def&gt;</span></pre></td></tr></table></div>

<h2>And a sprinkle of Elements</h2>
<p>From the example above, we are including a sidebar element at line 28.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>28
</pre></td><td class="code"><pre class="html4strict"><span style="color: #009900;">&lt;%include file=<span style="color: #ff0000;">&quot;elements/sidebar.mako&quot;</span>/<span style="color: #000000; font-weight: bold;">&gt;</span></span></pre></td></tr></table></div>

<p>This allows us to share components between views and even layouts.  Elements have access to the global <strong>c</strong> variable just as the layout and views do.  As a convention I like to call out what variables need to be defined for an element to work towards the top of the file.  As such, an example should follow&#8230;</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="html4strict"># 
# element/sidebar.mako 
# Sidebar element
#
# Required defined vars:
#  c.active_users - An array of active users {Users database objects}
#
%&gt;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p&gt;</span></span>Ads<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/p&gt;</span></span>
% for user in c.active_users:
    ${ user.name }<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;br</span>/<span style="color: #000000; font-weight: bold;">&gt;</span></span>
% endfor</pre></td></tr></table></div>

<p>Here we are assuming that we have several active users that we wish to loop over.  The object would be obtained in the calling controller as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="python">users = meta.<span style="color: black;">Session</span>.<span style="color: black;">query</span><span style="color: black;">&#40;</span>model.<span style="color: black;">User</span><span style="color: black;">&#41;</span>.<span style="color: black;">filter_by</span><span style="color: black;">&#40;</span>date &gt;= <span style="color: #dc143c;">time</span>.<span style="color: black;">now</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #ff4500;">-86400</span>*<span style="color: #ff4500;">7</span><span style="color: black;">&#41;</span>
c.<span style="color: black;">active_users</span> = users</pre></div></div>

<h2>Download</h2>
<p>That concludes the 3 part series of <a href="/blog/2008/04/zero-to-60-with-pylons-in-just-minutes-part-1/">Zero to 60 with Pylons</a></p>
<p>If you wish to see the full, bare bones project in action you can <a href="/blog/wp-content/uploads/2008/05/myfirstapp.zip">download here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.janisb.com/blog/2008/05/zero-to-60-with-pylons-in-just-minutes-part-3/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
