<?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>Jens Arps &#187; Goodies to go</title>
	<atom:link href="http://jensarps.de/category/goodies-to-go/feed/" rel="self" type="application/rss+xml" />
	<link>http://jensarps.de</link>
	<description></description>
	<lastBuildDate>Tue, 07 Sep 2010 14:11:57 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Encrypted client-side storage with dojo</title>
		<link>http://jensarps.de/2010/04/15/encrypted-client-side-storage-with-dojo/</link>
		<comments>http://jensarps.de/2010/04/15/encrypted-client-side-storage-with-dojo/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 21:48:54 +0000</pubDate>
		<dc:creator>Jens Arps</dc:creator>
				<category><![CDATA[Dojo Love]]></category>
		<category><![CDATA[Experiments in Web]]></category>
		<category><![CDATA[Goodies to go]]></category>
		<category><![CDATA[Storage]]></category>
		<category><![CDATA[client-side storage]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[dojox]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[localStorage]]></category>

		<guid isPermaLink="false">http://jensarps.de/?p=248</guid>
		<description><![CDATA[A couple of days ago, Nicholas Zakas wrote an article about secure client side storage. I think the scenario he mentioned (working from a cyber cafe) is not unsafe by nature, and could be well handled by an application. Nonetheless, client side storage such as localStorage still is subject to DNS spoofing attacks (which is ]]></description>
			<content:encoded><![CDATA[<p>A couple of days ago, <a href="http://www.twitter.com/slicknet/" target="_blank">Nicholas Zakas</a> wrote <a href="http://www.nczonline.net/blog/2010/04/13/towards-more-secure-client-side-data-storage/" target="_blank">an article</a> about secure client side storage. I think the scenario he mentioned (working from a cyber cafe) is not unsafe by nature, and could be well handled by an application. Nonetheless, client side storage such as <code>localStorage</code> still is subject to DNS spoofing attacks (which is the main security issue, I think). To handle this, one needs to encrypt the keys and values in the store.</p>
<p>So here you go: <code>dojox.storage.encrypted</code>, a <a href="http://en.wikipedia.org/wiki/Blowfish_%28cipher%29" target="_blank">Blowfish</a> encrypted storage. It sits on top of <code>dojox.storage</code>, and you get all the dojo storage manager goodness, mainly the automatic selection of the best storage provider available. It exposes the complete API that <code>dojox.storage</code> does. If an attacker gains access to the storage area, he can still nuke the storage, but the data found within will be useless.<br />
<span id="more-248"></span><br />
I&#8217;m not completely happy with it&#8217;s architecture, and I didn&#8217;t have the time yet to fully test it with all providers, but it works pretty well with <code>localStorage</code> and the performance is not too bad. If you have a spare minute and are interested, feel free to to test it yourself (ah I know, you don&#8217;t have the time yourself, but I&#8217;d be thankful!)…</p>
<h2>Usage</h2>
<p>Just use it as you would use dojox.storage, except that you need to set your passphrase before you start working with the storage:</p>
<pre>dojo.require("dojox.storage.encrypted");
var sto = dojox.storage.encrypted;
sto.setPassphrase("my super secret passphrase");
sto.put('key','value');
var value = sto.get('key');</pre>
<p>It uses/requires <code>dojox.encoding.crypto.Blowfish</code> but that&#8217;s been in dojo for ages, so no worries.</p>
<p>To use it, just put the <code>encrypted.js</code> file in your dojox/storage directory.</p>
<h2>Files</h2>
<p><a href="http://jensarps.de/tests/dojo_tests/dojo-release-1.4.0-src/dojox/storage/encrypted.js" target="_blank">the code (encrypted.js)</a><br />
<a href="http://jensarps.de/tests/dojo_tests/dojo-release-1.4.0-src/dojox/storage/tests/test_enc_storage.html">the test page</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jensarps.de/2010/04/15/encrypted-client-side-storage-with-dojo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>persistent local storage with dojo</title>
		<link>http://jensarps.de/2010/01/04/persistent-local-storage-with-dojo/</link>
		<comments>http://jensarps.de/2010/01/04/persistent-local-storage-with-dojo/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 21:46:40 +0000</pubDate>
		<dc:creator>Jens Arps</dc:creator>
				<category><![CDATA[Dojo Love]]></category>
		<category><![CDATA[Experiments in Web]]></category>
		<category><![CDATA[Goodies to go]]></category>
		<category><![CDATA[Storage]]></category>
		<category><![CDATA[client-side storage]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[dojox]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[local]]></category>
		<category><![CDATA[localStorage]]></category>
		<category><![CDATA[persistence]]></category>

		<guid isPermaLink="false">http://jensarps.de/?p=140</guid>
		<description><![CDATA[Last year, Brian Leroux&#8217;s Lawnchair caught my interest – it is an easy and fast way to access local persistant local storage.
Uh, persistant local storage?
Ahm, yeah, in case you don&#8217;t know, that means a client-side storage, be it in a browser, or in an Air app. It&#8217;s not very popular, but that concept has been ]]></description>
			<content:encoded><![CDATA[<p>Last year, <a href="http://twitter.com/brianleroux" target="_blank">Brian Leroux</a>&#8217;s <a href="http://brianleroux.github.com/lawnchair/" target="_blank">Lawnchair</a> caught my interest – it is an easy and fast way to access local persistant local storage.</p>
<p><strong>Uh, persistant local storage?</strong></p>
<p>Ahm, yeah, in case you don&#8217;t know, that means a client-side storage, be it in a browser, or in an Air app. It&#8217;s not very popular, but that concept has been around for a long time. So why local? There are two major reasons for it: First, we need this for apps and tools that work offline – and apps and tools that work online but need an offline backup and sync later. <a href="http://twitter.com/kriszyp" target="_blank">Kris Zyp</a> wrote a <a href="http://www.sitepen.com/blog/2008/09/23/effortless-offline-with-offlinerest/" target="_blank">post about the JsonRestStore and OfflineRest</a> back in 2008, he goes a little into detail there. Secondly, we need it for apps and tools that rely on persistence for other reasons, no matter if online or offline – like it happended to me. When I ran into Lawnchair, I had the idea to build a tool that was monitoring CSS selector usage on websites and apps (you know how you sometimes lose control about CSS selectors in webapps…). To achieve this, I needed to store data locally, and persistent.<br />
<span id="more-140"></span><br />
<strong>What dojo offers<br />
</strong></p>
<p>As I was using dojo&#8217;s excellent CSSRuleStore to find out what selectors where used, I wanted to switch from Lawnchair to a dojo solution. Dojo has dojox.storage (the above mentioned OfflineRest uses dojox.storage), which provides wrappers for the following backends: Gears, Flash, globalStorage and Adobe Air (globalStorage is Firefox&#8217;s early implementation of the early WhatWG storage draft). Hm. Not that much. Gears and Flash are 3rd party solutions, globalStorage is a Firefox-only-thingy (and old, though it&#8217;s still supported in current Versions) and Air is non-browser. That means: No IE without plugins. No Safari when Flash is not available.</p>
<p><strong>What dojo does not offer (but should)</strong></p>
<p>Guaranteed, reliable support for *any* browser. Without depending on 3rd party plugins. As of now, to have this, you&#8217;d need to use Lawnchair or <a href="http://github.com/lloyd/persist-js" target="_blank">persist,js</a>, which is pretty complete. Speaking of it, let me quote from it&#8217;s readme (it&#8217;s a good read on local persistent storage in general):</p>
<blockquote><p>The most notable attempt at addressing this problem [storing client-side persistent data] is probably Dojo Storage.  Unfortunately, Dojo Storage does not support Internet Explorer without Flash, and it does not support Safari or other WebKit-based<br />
browsers at all (at least, not without Flash).  Also, Dojo Storage is<br />
not standalone; it requires a several other Dojo components in order to<br />
operate.</p></blockquote>
<p>Whoa, even other JS tools mention the lack of support in dojo…</p>
<p><strong>New providers</strong></p>
<p>Attached to this post are wrappers for the following mechanisms:</p>
<ul>
<li>localStorage: this is the current spec, and it is supported by IE8, Firefox 3, Safari 4, Opera 10, Chrome 5.</li>
<li>userData behavior: this is Microsofts client-side storage for IE &lt; 8.</li>
<li>cookie: worst case fallback solution…</li>
</ul>
<p>With these three, there&#8217;s an almost 100% coverage of browser situations (see storage overview). There are still no-go scenarios, of course, such as IE7 with userData disabled and cookies disabled, but there&#8217;s no way to address them all.</p>
<p><strong>Notes on BehaviorStorageProvider</strong></p>
<p>This one uses the <a href="http://msdn.microsoft.com/en-us/library/ms531424%28VS.85%29.aspx" target="_blank">userData behavior</a>, present in IE from version 5 up. It works with DOM elements that have a special behavior assigned. You can then use  set/get/removeAttribute() methods to store data. It has some limitations though – of course…</p>
<ul>
<li>Maximum size varies from 64k to 1M – depending on the zone the site is in. So, you can&#8217;t rely on more than 64k.</li>
<li>UserData can be switched off in security settings.</li>
<li>I couldn&#8217;t find a way to read out stored keys if you don&#8217;t know them. Maybe this is some security thingy or just a bug – but it means that some methods in the provider don&#8217;t work. (that is, getNamespaces, getKeys and clear). To work around this, we have to take some of the precious storage space and store the keys and namespaces seperately.</li>
</ul>
<p><strong>Usage</strong></p>
<p>Copy the the providers into your <code>/dojox/storage</code> directory and add the needed <code>dojo.require</code>s to <code>/dojox/storage/_common.js</code>:</p>
<pre>dojo.require("dojox.storage.LocalStorageProvider");
dojo.require("dojox.storage.GearsStorageProvider");
dojo.require("dojox.storage.BehaviorStorageProvider");
//&gt;&gt;excludeStart("offlineProfileExclude", kwArgs.dojoxStorageBuildOption == "offline");
dojo.require("dojox.storage.WhatWGStorageProvider");
dojo.require("dojox.storage.FlashStorageProvider");
//&gt;&gt;excludeEnd("offlineProfileExclude");
dojo.require("dojox.storage.CookieStorageProvider");</pre>
<p><strong>What&#8217;s left?</strong></p>
<p>Well, it would be pretty cool to have a dojo.data API compliant store that uses dojox.storage as backend, so that you could write your apps using dojo.data calls and have a reliable offline backup. I started working on that, but then came Christmas, parents, vacation, new year and a lot of beer. But hey, it&#8217;s 2010 now, and there&#8217;s plenty of time left!</p>
<p><strong>Storage Overview</strong><br />
<!-- .overviewTable td {font-size: 10px; padding:2px 5px;} --></p>
<table class="overviewTable" border="0">
<tbody>
<tr>
<td>IE 6 / IE7</td>
<td>BehaviorStorageProvider<br />
FlashStorageProvider<br />
GearsStorageProvider<br />
CookieStorageProvider</td>
</tr>
<tr>
<td>IE 8</td>
<td>LocalStorageProvider<br />
GearsStorageProvider<br />
FlashStorageProvider<br />
CookieStorageProvider</td>
</tr>
<tr>
<td>Safari 3</td>
<td>FlashStorageProvider<br />
CookieStorageProvider</td>
</tr>
<tr>
<td>Safari 4</td>
<td>LocalStorageProvider<br />
FlashStorageProvider<br />
CookieStorageProvider</td>
</tr>
<tr>
<td>Chrome 5</td>
<td>LocalStorageProvider<br />
FlashStorageProvider<br />
CookieStorageProvider</td>
</tr>
<tr>
<td>Firefox 2</td>
<td>WhatWGStorageProvider (= globalStorage)<br />
GearsStorageProvider<br />
FlashStorageProvider<br />
CookieStorageProvider</td>
</tr>
<tr>
<td>Firefox 3</td>
<td>LocalStorageProvider<br />
GearsStorageProvider<br />
FlashStorageProvider<br />
CookieStorageProvider</td>
</tr>
<tr>
<td>Opera 10</td>
<td>LocalStorageProvider<br />
FlashStorageProvider (?)<br />
CookieStorageProvider</td>
</tr>
</tbody>
</table>
<p><strong>Files</strong></p>
<p><a href="http://jensarps.de/tests/dojo_tests/dojo-release-1.4.0-src/dojox/storage/LocalStorageProvider.js" target="_blank">LocalStorageProvider.js</a><br />
<a href="http://jensarps.de/tests/dojo_tests/dojo-release-1.4.0-src/dojox/storage/BehaviorStorageProvider.js" target="_blank">BehaviorStorageProvider.js</a><br />
<a href="http://jensarps.de/tests/dojo_tests/dojo-release-1.4.0-src/dojox/storage/CookieStorageProvider.js" target="_blank">CookieStorageProvider.js</a><br />
<a href="http://jensarps.de/tests/dojo_tests/dojo-release-1.4.0-src/dojox/storage/tests/test_storage.html" target="_blank">Storage Test Page</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jensarps.de/2010/01/04/persistent-local-storage-with-dojo/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>More fun with strings: dojo.string.contains()</title>
		<link>http://jensarps.de/2009/11/29/more-fun-with-strings-dojo-string-contains/</link>
		<comments>http://jensarps.de/2009/11/29/more-fun-with-strings-dojo-string-contains/#comments</comments>
		<pubDate>Sun, 29 Nov 2009 19:27:25 +0000</pubDate>
		<dc:creator>Jens Arps</dc:creator>
				<category><![CDATA[Dojo Love]]></category>
		<category><![CDATA[Experiments in Web]]></category>
		<category><![CDATA[Goodies to go]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[fun]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[string]]></category>

		<guid isPermaLink="false">http://jensarps.de/?p=114</guid>
		<description><![CDATA[In the series &#8220;convenience wrappers for small tasks that increase code readability&#8221;, today contains() is starring. Having a contains() method could also serve another purpose: to maybe prevent people from using match() to find out if a string contains a given substring (what is still proposed in some JS tutorials out there…). So, I want ]]></description>
			<content:encoded><![CDATA[<p>In the series &#8220;convenience wrappers for small tasks that increase code readability&#8221;, today contains() is starring. Having a contains() method could also serve another purpose: to maybe prevent people from using match() to find out if a string contains a given substring (what is still proposed in some JS tutorials out there…). So, I want the contains() method to also have a switch to work case-insensitive.</p>
<p>Besides indexOf(), there are some other ways to achieve this, so – let&#8217;s have a competition and find out who&#8217;s the fastest!<br />
<span id="more-114"></span></p>
<h3>The Contestants</h3>
<p><strong>replace and length</strong></p>
<p>One possibility is to replace the searched string with an empty string, read the length property of the modified string and compare it to the length of the haystack. If it&#8217;s different, the haystack contains the needle. Reading the length property is extra work, but comparing two integers is faster than comparing two strings, so maybe it&#8217;s faster in general.</p>
<p><strong>replace</strong></p>
<p>Again, replace the searched string with an empty string. Then compare the the modified string with the haystack. If they are different, the haystack contains the needle.</p>
<p><strong>split</strong></p>
<p>Take the haystack and try to split it using the needle as the seperator. If the result&#8217;s length is greater than one, the haystack contains the needle.</p>
<p><strong>indexOf</strong></p>
<p>Find the first occurance of needle in haystack; if the result is something else than -1, the haystack contains the needle.</p>
<h3>Results</h3>
<p>For testing, I did 10,000 iterations and retrieved the execution time in ms. The methods were tested in the order presented above.</p>
<p>On Chromium (Mac build, Version 4.0.203.0 here), replace + length is slightly faster than replace, and both are faster than split. indexOf is by far the fastest.</p>
<p>1) true: 7 / false: 3.5<br />
2) true: 7.5 / false: 3.5<br />
3) true: 10 / false: 8<br />
4) true: 2.5 / false: 3</p>
<p>Safari 4 has nearly the same results as Chromium, but the numbers tend to differ a lot from test to test.</p>
<p>1) true: 4-18, avg 10 / false: 2.5<br />
2) true: 4-19, avg 10 / false: 3<br />
3) true: 6-22. avg 13 / false: 6-23 avg. 16<br />
4) true: 2 / false: 3</p>
<p>On Firefox 3.5, split a bit faster than the two replace methods, but indexOf is again by far the fastest.</p>
<p>1) true: 13 / false 10<br />
2) true: 13 / false 10<br />
3) true: 10 / false 9<br />
4) true: 1.5 / false: 2</p>
<p>On IE 8 (run in a VM), both replace versions perform almost the same, and faster than split. Again, indexOf is fastest. Only 2 &#8211; 3 times faster than the replace methods, but still the fastest.</p>
<p>1) true: 35 / false: 25<br />
2) true: 30 / false: 25<br />
3) true: 60 / false: 50<br />
4) true: 15 / false: 15</p>
<p>You can run the tests yourself, if you are interested, the test page is <a href="http://jensarps.de/tests/dojo_tests/test_Contains.html" target="_blank">here</a>.</p>
<h3>Summary</h3>
<p>The results are pretty obvious: indexOf() outperforms the other contestants. Which is not really a surprise, considering that whatever Javascript does during indexOf() –  it has also to do the same before being able to do a split() or replace(). So, the proposed way for a contains() method is the following:</p>
<pre>dojo.string.contains = function(/* string */ needle, /* string */ haystack, /* bool */ caseInsensitive) {
    if(caseInsensitive) {
        needle = needle.toLowerCase();
        haystack = haystack.toLowerCase();
    }
    return haystack.indexOf(needle) !== -1;
}</pre>
<p>If you want to use contains() in your code, just copy the above lines somewhere in your code. Again, don&#8217;t forget to dojo.require(&#8221;dojo.string&#8221;) before.</p>
<p>Or, if you want to have beginsWith(), endsWith() and contains() all-in-one, use this: <a href="http://jensarps.de/tests/dojo_tests/dojo.string.addons.js" target="_blank">dojo.string.addons.js</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jensarps.de/2009/11/29/more-fun-with-strings-dojo-string-contains/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>dojo.string.beginsWith()</title>
		<link>http://jensarps.de/2009/10/27/dojo-string-beginswith/</link>
		<comments>http://jensarps.de/2009/10/27/dojo-string-beginswith/#comments</comments>
		<pubDate>Tue, 27 Oct 2009 20:36:18 +0000</pubDate>
		<dc:creator>Jens Arps</dc:creator>
				<category><![CDATA[Dojo Love]]></category>
		<category><![CDATA[Goodies to go]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[fun]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[string]]></category>

		<guid isPermaLink="false">http://jensarps.de/?p=78</guid>
		<description><![CDATA[Most cases where you find String.substr() in the wild are to check if a given string begins with a certain other string. Be it checking for a prefix or sorting out zipcodes that begin with certain numbers. And because code readability is a good thing (really, it is important), it would be nice to have ]]></description>
			<content:encoded><![CDATA[<p>Most cases where you find String.substr() in the wild are to check if a given string begins with a certain other string. Be it checking for a prefix or sorting out zipcodes that begin with certain numbers. And because code readability is a good thing (really, it <em>is</em> important), it would be nice to have a String.beginsWith() method. Or, because of dojo love, a dojo.string.beginsWith() method.</p>
<p>Consider the following code:</p>
<pre>var nearbyZipcodes = dojo.filter(givenZipcodes,function(zipcode){
    return dojo.string.beginsWith(zipcode,'12');
});</pre>
<p><span id="more-78"></span><br />
No need to tell you what this does, right? So, let&#8217;s do this then! The only thing left is to think about performance: Is there a difference between String.substr() and String.substring()? And can we get faster than the two?</p>
<p>If we have very short needles to look for in our haystack, one could consider the following approach:</p>
<pre>dojo.string.beginsWith = function(/* string */ needle, /* string */ haystack) {
    var i,
        len = needle.length;
    if(needle.length &gt; haystack.length) {
        return false;
    }
    for(i = 0; i &lt; len; i++) {
        if(needle.charAt(i) !== haystack.charAt(i)) {
            return false;
        }
    }
    return true;
}</pre>
<p>For very short needles, or when we expect close to no hits, this might be faster. So I set up a test page and let the different methods run against each other. The results clearly spoke against the char iteration method: On Firefox, iteration was <em>always</em> slower, even when the iteration method could return false after the first character. And when it had to iterate more often, times went up (I somehow had in mind Tracemonkey was perfect for simple iterations – but in this case it won&#8217;t help). Only on Safari the iteration method could compete with native substr() / substring() – but was never significantly faster. So, we&#8217;ll stick to the native methods (there was no real difference between the two).</p>
<p>More convenience?</p>
<p>Depending on your datasource, you might want to trim the input. No problem, as we use dojo, we can use it&#8217;s super fast trim and end up with the following:</p>
<pre>dojo.string.beginsWith = function(/* string */ needle, /* string */ haystack, /* bool */ trimBefore) {
    if(trimBefore) {
        needle = dojo.string.trim(needle)
    }
    if(needle.length &gt; haystack.length) {
        return false;
    }
    return haystack.substr(0,needle.length) === needle;
}</pre>
<p>So simple, so sweet.</p>
<p>You can run the tests for yourself, the page is located here: <a href="http://jensarps.de/tests/dojo_tests/test_beginsWith.html" target="_blank">test_beginsWith.html</a></p>
<p>If you want to use beginsWith in your code, just put the lines above it anywhere in your code – but don&#8217;t forget to dojo.require(&#8217;dojo.string&#8217;) before.</p>
]]></content:encoded>
			<wfw:commentRss>http://jensarps.de/2009/10/27/dojo-string-beginswith/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A collapsible fieldset as dojo widget</title>
		<link>http://jensarps.de/2009/10/16/a-collapsible-fieldset-as-dojo-widget/</link>
		<comments>http://jensarps.de/2009/10/16/a-collapsible-fieldset-as-dojo-widget/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 18:43:01 +0000</pubDate>
		<dc:creator>Jens Arps</dc:creator>
				<category><![CDATA[Dojo Love]]></category>
		<category><![CDATA[Goodies to go]]></category>
		<category><![CDATA[dijit]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[widget]]></category>

		<guid isPermaLink="false">http://jensarps.de/?p=59</guid>
		<description><![CDATA[Though many people would disagree, I for one like to use fieldsets to structure complex forms. Even better do I like fieldsets that are collapsible.
As there is no such fieldset with dojo, I decided to write my own widget. While doing so, I learnt an interesting lesson…
First, I wrote it pretty simple, inheriting the widget ]]></description>
			<content:encoded><![CDATA[<p>Though many people would disagree, I for one like to use fieldsets to structure complex forms. Even better do I like fieldsets that are collapsible.</p>
<p>As there is no such fieldset with dojo, I decided to write my own widget. While doing so, I learnt an interesting lesson…</p>
<p>First, I wrote it pretty simple, inheriting the widget from dijit._Widget and dijit._Templated. It had a toggle button next to its legend, which could be clicked. The toggle was a simple display none/block change.<br />
<span id="more-59"></span><br />
But I wanted it to be accessible via the keyboard – so I added a tabIndex and a key handler. Next, I wanted it to be able to hold and parse widgets, so I inherited it from dijit.layout.ContentPane so I could make use of the content setter. Then I wanted it to animate smoothly, so I added animations, and so on… You get the point, I guess. Well, this went on for a while, until I made an unpleasant discovery: My fieldset was almost a clone of dijit.TitlePane. Ugh.</p>
<p><em>I had put all the time into creating a copy of something, that already existed.</em></p>
<p>So I inherited the fieldset widget from dijit.TitlePane and ended up with less than 50 lines of code. And it was a matter of minutes to do so. Ok, lesson learned: If you need something that doesn&#8217;t exist and you are going to code it – first check if there&#8217;s something that behaves similar to what you want. Or similar to what you <em>might want in the future</em>. If I had invested a little more time in thinking about the fieldset widget before starting to code, it would have been obvious that I wanted the above mentioned features one day. And I would have saved a lot of time.</p>
<p>Well, however, here it is: a collapsible fieldset, coming with all the ContentPane goodness (child widgets, remote loading,…).</p>
<p>You can create it via markup (I put it into a namespace called &#8220;app&#8221;; choose a namespace you like):</p>
<pre>&lt;fieldset dojotype="app.Fieldset"&gt;
    &lt;legend&gt;Legend&lt;/legend&gt;
    Content
&lt;/fieldset&gt;</pre>
<p>or programmatically:</p>
<pre>var fieldset = new app.Fieldset({legend:'dojo fieldset', id: 'someId'},dojo.create('div',{},dojo.body()));</pre>
<p>The fieldset takes pretty much the same arguments as dijit.TitlePane. To change the legend, use <code>dojo.attr('legend','Teh new legend')</code>, to change the content <code>dojo.attr('content',content)</code> as usual. To stay close to TitlePane, I left <code>_setTitleAttr()</code> in it, but it is an alias for <code>_setLegendAttr()</code>.</p>
<p>The code is simple (after I inherited from TitlePane), I only added a method to setup the legend tag and changed the methods that handle hover states, as the TitlePane&#8217;s methods paid no respect to the dijit&#8217;s base class. The fieldset is closed by default, but you can add <code>open="true"</code> to the markup (or add <code>open: true</code> to the constructor args) to make it start open. You can style it as you would style any other widget.</p>
<p>The testpage is over here: <a href="http://jensarps.de/tests/dojo_tests/test_Fieldset.html" target="_blank">test_Fieldset.html<br />
</a> Code: <a href="http://jensarps.de/tests/dojo_tests/dojo-1.3.2/app/Fieldset.js" target="_blank">Fieldset.js</a><br />
Template: <a href="http://jensarps.de/tests/dojo_tests/dojo-1.3.2/app/templates/Fieldset.html" target="_blank">Fieldset.html</a></p>
<p><strong>Update</strong>: If you have downloaded the code and intend to use it, please re-download it, as I updated a method and fixed a namespace confusion (and added doc).</p>
]]></content:encoded>
			<wfw:commentRss>http://jensarps.de/2009/10/16/a-collapsible-fieldset-as-dojo-widget/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>dojox.analytics.Urchin for jQuery</title>
		<link>http://jensarps.de/2009/10/03/dojox-analytics-urchin-for-jquery/</link>
		<comments>http://jensarps.de/2009/10/03/dojox-analytics-urchin-for-jquery/#comments</comments>
		<pubDate>Sat, 03 Oct 2009 17:28:41 +0000</pubDate>
		<dc:creator>Jens Arps</dc:creator>
				<category><![CDATA[Framework Peace]]></category>
		<category><![CDATA[Goodies to go]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[tracking]]></category>

		<guid isPermaLink="false">http://jensarps.de/?p=38</guid>
		<description><![CDATA[Or: Still ending the ga.js wait…
It has become quiet here the last weeks – due to an awesome trip to Italy. Returning home, I decided to put Google Analytics on this page.
As I always hate waiting for the ga.js to load while visiting websites, I wanted a mechanism to delay the load of it. Why ]]></description>
			<content:encoded><![CDATA[<p>Or: <em>Still</em> ending the ga.js wait…</p>
<p>It has become quiet here the last weeks – due to an awesome trip to Italy. Returning home, I decided to put Google Analytics on this page.</p>
<p>As I always hate waiting for the ga.js to load while visiting websites, I wanted a mechanism to delay the load of it. Why this is a good idea has been discussed often enough elsewhere, so we take it as fact. Peter Higgins once <a href="http://higginsforpresident.net/2008/06/google-analytics-after-onload/" target="_blank">wrote such a wrapper for dojo</a>, and as of dojo 1.3, it&#8217;s officially included in dojox (see <a href="http://alex.dojotoolkit.org/2009/04/ending-the-gajs-wait/" target="_blank">Alex Russel&#8217;s post</a>). But this Wordpress theme runs jQuery, and I didn&#8217;t want to have two frameworks in one website – so I searched for something that did the job for jQuery.<br />
<span id="more-38"></span><br />
But I didn&#8217;t really find what I was looking for. Well, there <em>are</em> some jQuery plugins that provide functionality like I wanted. Some were overpowered, some poorly written – and in the end, they all relied on jQuery.getScript(). The problem is, that getScript() adds a random parameter to the GET call, so that the called script is never cached. While this <em>may</em> be useful for some situations, in this case it&#8217;s really annoying and undesireable. In addition, I liked the idea of dojox.analytics.Urchin to not really <em>wait</em> for the script to be loaded, but instead to go see every now and then if the _gat global variable is present, and to give up after some time in case something went wrong.</p>
<p>So I decided to &#8220;port&#8221; dojox.analytics.Urchin to jQuery. It works almost the same as it&#8217;s dojo origin, with two major differences: First, you can&#8217;t have several instances of it running, you call it directly via jQuery.urchin.load(args). Second, there&#8217;s an option waitForDOM, set to true as default, that delays the loading of ga.js until the DOM is ready. If you call jQuery.urchin.load() from within a jQuery(document).ready() block, set this to false.</p>
<p>Example? Here you go:</p>
<pre>&lt;script type="text/javascript" src="jquery.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="jquery.urchin.js"&gt;&lt;/script&gt;

&lt;script type="text/javascript"&gt;
jQuery.urchin.load({acct:'UA-111111-1'});
&lt;/script&gt;</pre>
<p>Or, if you need more options:</p>
<pre>&lt;script type="text/javascript"&gt;
$(document).ready(function() {
    // do some stuff
    // ...
    // load ga.js
    $.urchin.load({
        acct:'2234-2342',
        timeout: 8000,
        waitForDOM: false
    });
});
&lt;/script&gt;</pre>
<p>You can get the file here: <a href="http://jensarps.de/tests/jquery_analytics/jquery.urchin.js" target="_blank">jquery.urchin.js</a></p>
<p>Uncompressed version: <a href="http://jensarps.de/tests/jquery_analytics/jquery.urchin.uncompressed.js">jquery.urchin.uncompressed.js</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jensarps.de/2009/10/03/dojox-analytics-urchin-for-jquery/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Static data handling in PHP</title>
		<link>http://jensarps.de/2009/09/03/static-data-handling-in-php/</link>
		<comments>http://jensarps.de/2009/09/03/static-data-handling-in-php/#comments</comments>
		<pubDate>Thu, 03 Sep 2009 19:13:42 +0000</pubDate>
		<dc:creator>Jens Arps</dc:creator>
				<category><![CDATA[Goodies to go]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://jensarps.de/?p=26</guid>
		<description><![CDATA[Every now and then I stumble upon PHP Code dealing with config files. Besides being happy that people use config files (uh, yes, it happens too often that people don&#8217;t…), I am often unhappy with how they&#8217;re dealing with config files. You can find the ugliest things out there, like arrays in .php files (my ]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-thumbnail wp-image-32" title="Bild 17" src="http://jensarps.de/wp-content/uploads/2009/09/Bild-17.png" alt="Bild 17" width="150" />Every now and then I stumble upon PHP Code dealing with config files. Besides being happy that people use config files (uh, yes, it happens too often that people don&#8217;t…), I am often unhappy with how they&#8217;re dealing with config files. You can find the ugliest things out there, like arrays in .php files (my favorite). However, even if config files are used, there are strange things happening to them, like being read once and serialized into a constant.</p>
<p>So I want to share today a very primitive static data handler that I use for quite some time now, and wich has always served me well. By static, I mean data that doesn&#8217;t change during runtime, like smtp server connection data, database connection data and the likes.</p>
<p><span id="more-26"></span></p>
<p>The idea is to have a seperate directory (named &#8220;static&#8221; in my case) with .data files in it. Every .data file should care about a certain aspect of static data needed in an application. This directory is then blocked via an .htaccess file, containing the single line:</p>
<pre># file: .htaccess
Deny From All</pre>
<p>During the bootsrap process of your app, the collector is called to walk through that directory and gather the data from all the files:</p>
<pre>// file: bootstrap.php
// load static data
YourProject_StaticData::getInstance()-&gt;collectStaticData();</pre>
<p>These files are pretty much standard config files, so they are readable via php&#8217;s function parse_ini_file. That function has two major limitations: It cannot handle hierarchy beyond two levels and it breaks when it encounters a quote character in a value. These limitations are discussed elsewhere, but with this static data collector we can at least push the first one a level further away. A data file could look like this:</p>
<pre># file: mailconfig.data
[smtp]
host     = somehost.tld
auth     = true
username = user@somehost.tld
password = somepass
[lists]
whitelist = "goodone@example.com,admin@somehost.tld"
blacklist = "badone@example.com"
[options]
checkwhitelist = false
checkblacklist = true
# ...</pre>
<p>To get the connection data to the applications&#8217;s smtp account, you&#8217;d simply call:</p>
<pre>$smtpConfig = YourProject_StaticData::getInstance()-&gt;getSubSection('mailconfig','smtp');</pre>
<p>Fairly easy to use, pretty and readable. And it also is very handy for something that *very* often annoys me when looking into some client&#8217;s code: establishing a connection to a database. To different databases in most cases, for development, testing and deployment. I&#8217;ve seen pretty awkward attempts to handle this – but it can be done with one line of code, regardless of where the code is running. Say, you use <a href="http://www.doctrine-project.org/" target="_blank">Doctrine</a> as ORM for your database, and have a data file like the following, using host names as keys (besides all my love for the <a href="http://en.wikipedia.org/wiki/Nosql" target="_blank">NoSQL</a> movement, I run into a mysql database on nearly every project):</p>
<pre># file: dbms.data
project.local    = "mysql://user:pass@localhost/project_db"
test.project.tld = "mysql://testuser:testpass@project.tld/test_project_db"
project.tld      = "mysql://user:pass@project.tld/project_db"</pre>
<p>you can easily connect to your database by defining a constant that contains the current host name (wich is a good idea, in general) and call</p>
<pre>// file: bootstrap.php
//set up a connection
Doctrine_Manager::connection(
    YourProject_StaticData::getInstance()-&gt;getSubSection('dbms',HOST),
    'mainConnection'
)-&gt;setCharset("utf8");</pre>
<p>Clean and short. And independant from your location – just see to it that your data file contains the right connection data for each host, and never touch that line of code in your bootstrapping process again.</p>
<p>The PHP class uses the <a href="http://en.wikipedia.org/wiki/Singleton_pattern" target="_blank">singleton design pattern</a> (as you already know from the code above), and is less than 100 lines of code in size. Including doc. It&#8217;s as simple as it is handy. And it can be easily extended – if the need arises, what never happened to me.</p>
<p>I hope you can find it as useful as I do!</p>
<p>You can grab the file over here: <a href="/code/StaticData.php.txt">StaticData.php</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jensarps.de/2009/09/03/static-data-handling-in-php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
