<?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>klauskomenda.com &#187; Web</title>
	<atom:link href="http://www.klauskomenda.com/archives/category/web/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.klauskomenda.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Wed, 14 Dec 2011 23:58:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Text to speech functionality in web applications using the iSpeech API</title>
		<link>http://www.klauskomenda.com/archives/2011/11/11/text-to-speech-functionality-in-web-applications-using-the-ispeech-api/</link>
		<comments>http://www.klauskomenda.com/archives/2011/11/11/text-to-speech-functionality-in-web-applications-using-the-ispeech-api/#comments</comments>
		<pubDate>Fri, 11 Nov 2011 23:02:40 +0000</pubDate>
		<dc:creator>Klaus</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[ispeech]]></category>
		<category><![CDATA[navigation]]></category>
		<category><![CDATA[text-to-speech]]></category>

		<guid isPermaLink="false">http://www.klauskomenda.com/?p=1067</guid>
		<description><![CDATA[Speech-enable your web applications using the iSpeech REST API. ]]></description>
			<content:encoded><![CDATA[<p>&#8220;Turn right onto Main Street&#8221;. If you are using a car navigation system like <a href="http://www.garmin.com/us/products/ontheroad">Garmin</a> or <a href="http://www.tomtom.com/">TomTom</a>, you will be all too familiar with phrases like this, spoken to you by the device mounted to your dashboard, magically guiding you through the maze of local roads and highways to your destination. Such <a href="http://en.wikipedia.org/wiki/Text_to_speech">text-to-speech</a> capabilities are usually associated with native software implementations, not so much with web applications. With the <a href="http://www.ispeech.org/developers">iSpeech API</a>, that changes. You can now build web applications that implement text-to-speech functionality with the power of JavaScript and HTML5.</p>
<p>The <a href="http://www.ispeech.org/text.to.speech.demo.php">iSpeech demo page</a> gives you an idea of the power of the API by providing a regular text input and being able to turn any text into spoken words. Let&#8217;s have a closer look now as to what is required to make this work in a web application.</p>
<h2>Step 1: Sign up for a Developer Account and set up an API key</h2>
<p><a href="http://www.ispeech.org/developer/signup/stage1">Signing up for a developer account</a> is a requirement in order to use the API. After creating your account and logging in, you can <a href="http://www.ispeech.org/developer/createkey">create a new API key</a>. Fill in the form and select &#8220;Desktop, Web, Other&#8221; as the application type in order to be able to use iSpeech&#8217;s REST API.</p>
<h2>Step 2: Trying out the API</h2>
<p>After creating an API key, you should find it in <a href="http://www.ispeech.org/developer/readallkeys">your list of available API keys</a>. Clicking on &#8220;Settings&#8221; leads you to a form where you can set certain parameters for the text-to-speech functionality, like file formats, bit rates and frequency as well as add some more information about the app that uses the key. For this step, we just want to try out the API and get some text converted into speech, so the first thing we need to do is familiarize ourselves with how the API request is constructed. iSpeech provides <a href="http://www.ispeech.org/api">good documentation</a> on that and gives us the general layout of the request:</p>
<pre><code>http://api.ispeech.org/api/rest?apikey=YOURAPIKEYHERE&amp;action=convert&amp;text=This+is+the+text+I+want+to+convert</code></pre>
<p>Now we only need to replace YOURAPIKEYHERE with the API key we created in Step 1 and copy that request URL to the address bar of our browser or create an <a href="http://html5doctor.com/native-audio-in-the-browser/">HTML5 audio element</a> like the one below to embed in our HTML document.</p>
<p><audio controls preload="auto" autobuffer><source src="http://api.ispeech.org/api/rest?apikey=developerdemokeydeveloperdemokey&#038;action=convert&#038;text=This+is+the+text+I+want+to+convert" /><source src="http://api.ispeech.org/api/rest?apikey=developerdemokeydeveloperdemokey&#038;action=convert&#038;text=This+is+the+text+I+want+to+convert&#038;format=ogg" /><source src="http://api.ispeech.org/api/rest?apikey=developerdemokeydeveloperdemokey&#038;action=convert&#038;text=This+is+the+text+I+want+to+convert&#038;format=wav" /></audio></p>
<h2>Step 3: Tweaking the Request Parameters</h2>
<p>The attentive reader might have noticed, from looking at the source code of the audio element in step 2, that we need to provide several fallback versions in addition to the MP3 format that the iSpeech API generates by default. This is necessary to satisfy the different codec requirements by modern browsers. To achieve this, the iSpeech API has a <span class="code">format</span> parameter, that lets us specify the format in which we would like the audio piece to be returned to us. A complete list of supported formats can be found in the <a href="http://www.ispeech.org/api">iSpeech API documentation</a>. </p>
<p>If we want to use the <a href="http://en.wikipedia.org/wiki/Ogg_vorbis">Ogg Vorbis</a> format, we can specify this like this:</p>
<pre><code>http://api.ispeech.org/api/rest?apikey=YOURAPIKEYHERE&amp;action=convert&amp;text=This+is+the+text+I+want+to+convert&amp;format=ogg</code></pre>
<p>We can also specify a different voice using the &#8220;voice&#8221; parameter:</p>
<pre><code>http://api.ispeech.org/api/rest?apikey=YOURAPIKEYHERE&amp;action=convert&amp;text=This+is+the+text+I+want+to+convert&amp;format=ogg&amp;voice=auenglishfemale</code></pre>
<p>It is also possible to slow down the voice by providing a &#8220;speed&#8221; parameter with values between -10 (very slow) and 10 (very fast). However I noticed that not all voices provided by iSpeech support this parameter.</p>
<pre><code>http://api.ispeech.org/api/rest?apikey=YOURAPIKEYHERE&amp;action=convert&amp;text=This+is+the+text+I+want+to+convert&amp;format=ogg&amp;speed=-5</code></pre>
<h2>Sounds great (literally), but&hellip;</h2>
<p>By this point it is probably obvious that being able to use this text-to-speech API from within HTML documents using regular web technologies is pretty powerful. However, there is a catch to it in the name of costs. The web API key that we created is free for the first 500 words being transformed to audio by the API (you can check your key&#8217;s total word balance on the settings page of the key). If you exceed that limit, you have to pay, $50 for 1000 word credits to be exact, which essentially means that you can only feasibly use this API in some sort of premium app setting where your revenue generated can cover for these costs. While I would love this technology to be free, I can understand that it is not, considering the amount of work that goes into developing such piece of software. </p>
<p>The upside is, however, that iSpeech in addition to the REST API also offers SDKs for pretty much all popular mobile platforms, such as the <a href="http://www.ispeech.org/developers/iphone">iPhone</a>, and API keys generated for these do not have any word quota imposed on them. Maybe another good reason to start learning Objective-C.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.klauskomenda.com/archives/2011/11/11/text-to-speech-functionality-in-web-applications-using-the-ispeech-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Search along a route with CloudMade&#8217;s Local Search API</title>
		<link>http://www.klauskomenda.com/archives/2011/11/06/search-along-a-route-with-cloudmades-local-search-api/</link>
		<comments>http://www.klauskomenda.com/archives/2011/11/06/search-along-a-route-with-cloudmades-local-search-api/#comments</comments>
		<pubDate>Mon, 07 Nov 2011 05:09:49 +0000</pubDate>
		<dc:creator>Klaus</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[bikenav]]></category>
		<category><![CDATA[cloudmade]]></category>
		<category><![CDATA[local search]]></category>
		<category><![CDATA[search along route]]></category>

		<guid isPermaLink="false">http://www.klauskomenda.com/?p=1065</guid>
		<description><![CDATA[A tutorial demonstrating how to give users functionality that they were used to get only from their car navigation systems.]]></description>
			<content:encoded><![CDATA[<p>Suppose you go on a casual bike ride with a couple of friends. Wouldn&#8217;t it be nice to know if there are any coffee shops located along the route to refuel on caffeine and sugar? Or lets say you are doing a longer ride and would want to pick up a spare tube along the way. It would be good to know if there is any bike shop conveniently located along the route. Meet <a href="http://developers.cloudmade.com/projects/local-search/examples/searching-for-objects-along-route">CloudMade&#8217;s Local Search API</a>, which I used to power this specific feature in the most recent version of <a href="/apps/bikenav/">BikeNav</a>. This article is going to show you how you can include that in your next mobile-aware app.</p>
<h2>Step 1: Sign up for a Developer Account and get an API key</h2>
<p>CloudMade lets you <a href="http://cloudmade.com/register">sign up for a developer account</a> for free. After completing that initial step, access your account and click on the &#8220;Get API Key&#8221; button. Fill the details into the form presented to you, selecting &#8220;Web&#8221; as the platform and the &#8220;Free&#8221; pricing plan. Since we will not use any of the <a href="http://cloudmade.com/select/web">other features</a> the API provides, the free version has more than we need.</p>
<h2>Step 2: Create a token from your API key</h2>
<p>In order to be able to communicate with CloudMade&#8217;s servers, you need to create an access token from your API key. This is done by sending an HTTP POST request to a particular authentication server as noted in <a href="http://developers.cloudmade.com/projects/show/auth">their documentation</a>. If you are using PHP, the following code can help you out (using <a href="http://wezfurlong.org/blog/2006/nov/http-post-from-php-without-curl/">Wez Furlong&#8217;s do_post_request function</a>).</p>
<pre><code>$apiKey = 'my-api-key';
$userId = 'your-generated-user-id';

// http://wezfurlong.org/blog/2006/nov/http-post-from-php-without-curl/
function do_post_request($url, $data, $optional_headers = null)
{
  $params = array('http' =&gt; array(
              'method' =&gt; 'POST',
              'content' =&gt; $data
            ));
  if ($optional_headers !== null) {
    $params['http']['header'] = $optional_headers;
  }
  $ctx = stream_context_create($params);
  $fp = @fopen($url, 'rb', false, $ctx);
  if (!$fp) {
    throw new Exception("Problem with $url, $php_errormsg");
  }
  $response = @stream_get_contents($fp);
  if ($response === false) {
    throw new Exception("Problem reading data from $url, $php_errormsg");
  }
  return $response;
}
$token =  do_post_request('http://auth.cloudmade.com/token/' . $apiKey . '?userid=' . $userId, '');

echo "generated token: " . $token;</code></pre>
<h2>Step 3: Requesting POI data along a given route</h2>
<p>Equipped with the token from Step 2, we can now try to retrieve POIs along the route. The following example would do a search along the route for a maximum of 20 points of interest of type &#8220;cafe&#8221; from my place to Cupertino, within a radius of 1 kilometer and returning the data in <a href="http://en.wikipedia.org/wiki/JSONP">JSONP</a> format.</p>
<pre><code>http://geocoding.cloudmade.com/[APIKEY]/geocoding/v2/find.js?token=[TOKEN]&amp;object_type=cafe&amp;along=37.36721,-122.03533,37.36756,-122.0354,37.36752,-122.03662,37.36672,-122.03607,37.36642,-122.03648,37.36429,-122.03288,37.33911,-122.03241,37.33763,-122.03239,37.32283,-122.03241&amp;distance=1000&amp;results=20&amp;callback=mySuperCallback</code></pre>
<p>The <a href="http://developers.cloudmade.com/wiki/geocoding-http-api/Documentation">find method</a> of the Local Search API lets you pass in various parameters, which are <a href="http://developers.cloudmade.com/wiki/geocoding-http-api/Documentation#Parameters">well documented</a>. For the purpose of this article, the following are the most important ones:</p>
<ul>
<li><span class="highlight">object_type</span>: the API lets you choose from an <a href="http://developers.cloudmade.com/wiki/geocoding-http-api/Object_Types">extensive list of point-of-interest types</a>
</li>
<li><span class="highlight">along</span>: vector of the route your are traveling along, i.e. a comma separated list of lat/long pairs</li>
<li><span class="highlight">distance</span>: radius of the search are in meters</li>
<li><span class="highlight">results</span>: number of results to return</li>
<li><span class="highlight">callback</span>: signaling the server to return the response in JSONP format and specifying a publicly accessible JavaScript function to execute, passing in the response data</li>
</ul>
<p>The result from the above request will come back as JSONP and look similar to the following:</p>
<pre><code>mySuperCallback({
    "found": "3",
    "bounds": [{
        "json": ["37.33155", "-122.03642"]
    }, {
        "json": ["37.36805", "-122.03266"]
    }],
    "features": [{
        "id": "7367785",
        "centroid": {
            "type": "POINT",
            "coordinates": ["37.36768", "-122.03642"]
        },
        "bounds": [{
            "json": ["37.36768", "-122.03642"]
        }, {
            "json": ["37.36768", "-122.03642"]
        }],
        "properties": {
            "operator": "Starbucks",
            "osm_element": "node",
            "amenity": "cafe",
            "synthesized_name": "Cafe",
            "osm_id": "266625630"
        },
        "type": "Feature"
    }, {
        "id": "26073213",
        "centroid": {
            "type": "POINT",
            "coordinates": ["37.33155", "-122.03266"]
        },
        "bounds": [{
            "json": ["37.33155", "-122.03266"]
        }, {
            "json": ["37.33155", "-122.03266"]
        }],
        "properties": {
            "osm_element": "node",
            "amenity": "cafe",
            "name": "Bagel Street Cafe",
            "osm_id": "957085286"
        },
        "type": "Feature"
    }, {
        "id": "14342531",
        "centroid": {
            "type": "POINT",
            "coordinates": ["37.36805", "-122.03338"]
        },
        "bounds": [{
            "json": ["37.36805", "-122.03338"]
        }, {
            "json": ["37.36805", "-122.03338"]
        }],
        "properties": {
            "osm_element": "node",
            "amenity": "cafe",
            "name": "Peet's Coffee",
            "osm_id": "441987522"
        },
        "type": "Feature"
    }],
    "type": "FeatureCollection",
    "crs": {
        "type": "EPSG",
        "properties": {
            "code": "4326",
            "coordinate_order": ["0", "1"]
        }
    }
});</code></pre>
<p>In our <span class="code">mySuperCallback</span> function we can then use this data to e.g. plot each of the returned points of interest on a map, in addition to the given route. </p>
<h2>Be aware of long routes</h2>
<p>Attentive readers will notice that there is a slight flaw in the way the request is constructed. If you have a long route with a lot of waypoints that you are passing along in the request to the search API, at some point you will reach the limit of the maximum amount of characters you can pass along in a URL. One way to mitigate this is to drop every other entry from the array of waypoints if the number exceeds a certain limit. That way, the search will still be somewhat accurate (since you are only taking out points in between instead of cutting them off at the beginning or the end). A JavaScript example code could look like this:</p>
<pre><code>maxWaypoints = 160; // a good threshold that I noticed works well for BikeNav
waypoints = [ ... ]; // array where each entry represents a waypoint along the route
no_of_waypoints = waypoints.length;

if (no_of_waypoints &gt; maxWaypoints) {
    while (waypoints.length &gt; maxWaypoints) {
        for (var i = 0, len = waypoints.length; i &lt; len; i++) {
            waypoints.splice(i + 2, 1);
        }
    }
}</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.klauskomenda.com/archives/2011/11/06/search-along-a-route-with-cloudmades-local-search-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Map API Showdown</title>
		<link>http://www.klauskomenda.com/archives/2011/01/21/the-map-api-showdown/</link>
		<comments>http://www.klauskomenda.com/archives/2011/01/21/the-map-api-showdown/#comments</comments>
		<pubDate>Sat, 22 Jan 2011 02:10:00 +0000</pubDate>
		<dc:creator>Klaus</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[bing maps]]></category>
		<category><![CDATA[comparison]]></category>
		<category><![CDATA[google maps]]></category>
		<category><![CDATA[map]]></category>
		<category><![CDATA[map api]]></category>
		<category><![CDATA[ovi maps]]></category>
		<category><![CDATA[yahoo maps]]></category>

		<guid isPermaLink="false">http://www.klauskomenda.com/?p=881</guid>
		<description><![CDATA[Three and a half years after I had last looked in detail at the big Map APIs, I felt it was time for another look at the current Map API landscape.]]></description>
			<content:encoded><![CDATA[<p>In an <a href="/archives/2007/07/22/google-maps-api-vs-yahoo-maps-api/">article I published more than 3.5 years ago</a> (my god, time is flying), I compared the states of the <a href="http://code.google.com/apis/maps/">Google</a> and <a href="http://developer.yahoo.com/maps/">Yahoo Maps APIs</a>, particularly looking at their geocoding capabilities and performance. A lot of time has passed since then and I felt it is time to assess the Map API landscape once again, this time bringing two new players to the game: <a href="http://www.microsoft.com/maps/developers/web.aspx">Bing Maps API</a> (by <a href="http://www.microsoft.com/">Microsoft</a>) and <a href="http://api.maps.ovi.com/">Ovi Maps API</a> (by <a href="http://www.nokia.com/">Nokia</a>). I will not go into as much detail as with my old post, but rather trying to convey how each API &#8216;feels&#8217; (regarding ease-of-use, documentation etc.) from a developers point of view.</p>
<blockquote class="pullquote appear-right">
<p class="pullquote">
Kamarov: Give me a stopwatch and a map, and I&#8217;ll fly the Alps in a plane with no windows.
</p>
<p>
<cite>from <a href="http://www.imdb.com/title/tt0099810/">The Hunt for Red October</a></cite>
</p>
</blockquote>
<p>While there are great posts out there that look at the <a href="http://www.41latitude.com/post/2072504768/google-maps-label-readability">visual appearance of the map imagery and their readability</a> the topic of this post are the APIs themselves, their capabilities and features and how easy they are to use from a developers perspective. I have put together <a href="http://www.klauskomenda.com/lab/map-api-showdown/">a little side-by-side comparison</a>, inspired by <a href="http://www.sergeychernyshev.com/maps.html">Sergey Chernychev&#8217;s work</a>, to see how common tasks can be performed with the different APIs.</p>
<h2>Ovi Maps API</h2>
<p><img src="http://www.klauskomenda.com/wp-content/uploads/2011/01/ovi.jpg" alt="" title="ovi" width="293" height="186" class="img-left" /><a href="http://www.ovi.com/">Ovi</a>, Nokia&#8217;s brand for their internet services, opened up its Ovi Maps API and their documentation just recently, in <a href="http://blogs.forum.nokia.com/blog/nokia-developer-news/2010/12/23/ovi-maps-api">December 2010</a>. The API documentation consists of a <a href="http://api.maps.ovi.com/devguide/index.html">Developer&#8217;s Guide</a>, <a href="http://api.maps.ovi.com/playground2/playground.html">Maps API Playground</a> and <a href="http://api.maps.ovi.com/apireference/index.html">API Documentation</a>. The Developer&#8217;s Guide gives a short overview over the API and its capabilities with little code snippets. The aim of the API Playground is to give the developer an interactive interface to play around with code examples and edit code on the fly and see how it impacts the behavior of the example. Finally, the API documentation lists the class hierarchy and methods available for the developer as part of the API.</p>
<p>While I can see the good intentions of providing that API Playground, I actually believe it does more harm than good. For me personally, the way Ovi presents these examples and then having to click on a &#8220;code&#8221; button to see the code (without being able to easily do &#8220;view source&#8221;), is frankly, quite annoying. Also, there are not that many examples to begin with, compared to <a href="http://code.google.com/apis/maps/documentation/javascript/examples/index.html">what Google Maps offers</a>. I feel that having separate, distinct URLs for each example (as opposed to a sophisticated JavaScript-heavy interface), where you can do &#8220;view source&#8221; and easily follow what is going on, is much more helpful. Additionally, compared to how many classes and functions are available in the API documentation, this is, by no means, reflected in the examples. There is also no search functionality in the API docs, which makes them quite cumbersome to use.</p>
<p>With regards to the code, I noticed that upon instantiation of the Ovi map, the developer has to add the zoom control as well as the map type selector (for map, satellite and terrain view) in additional steps in the code, as well as the actual ability for the user to drag the map. I feel like these should come by default when instantiating the map. </p>
<pre><code>// instantiate the map
ovimap = new ovi.mapsapi.map.Display(Y.Node.getDOMNode(Y.one('#ovimap')), {
    zoomLevel: mapOptions.zoom,
    center: [mapOptions.lat, mapOptions.lng]
});

//add direct mouse interaction
ovimap.components.add(new ovi.mapsapi.map.component.Behavior());

//add the zoom bar
ovimap.components.add(new ovi.mapsapi.map.component.ZoomBar());

// add map type selector (for map, satellite and hybrid view)
ovimap.components.add(new ovi.mapsapi.map.component.TypeSelector()); </code></pre>
<p>I also encountered a weird behavior, which I feel is a bug: when zooming into the map, either by double-clicking with the mouse or using the zoom control, the zoom control disappears (at least in my comparison example). But I would attribute that to the fact that this API is very new and I would think this will be fixed soon. Looking at the playground, Ovi Maps seems to offer some interesting features in addition to standards like <a href="http://api.maps.ovi.com/playground2/playground.html?example=20">routing</a>, <a href="http://api.maps.ovi.com/playground2/playground.html?example=7">placement of markers</a>, <a href="http://api.maps.ovi.com/playground2/playground.html?example=12">rendering geo shapes</a> and <a href="http://api.maps.ovi.com/playground2/playground.html?example=41">exposing map events</a> in JavaScript. Included in the API are the abilities to <a href="http://api.maps.ovi.com/playground2/playground.html?example=25">render SVG and text inside a graphics context</a> (which might just be an abstraction layer to native SVG capabilities in the browser), as well as an <a href="http://api.maps.ovi.com/playground2/playground.html?example=24">abstraction layer for canvas</a> (at least I believe that is what this is). </p>
<p>The quality of the imagery is not that outstanding, however, the satellite images Ovi has for Europe are much better than what, e.g. Google offers. You can see for yourself if you search for Helsinki <a href="http://www.klauskomenda.com/lab/map-api-showdown/">in my comparison example</a> and zoom in to the max on both the Google and the Ovi Map.</p>
<h3>Resources</h3>
<ul>
<li><a href="http://api.maps.ovi.com/">Ovi Maps API</a></li>
<li><a href="http://api.maps.ovi.com/playground2/playground.html">Ovi Maps API Playground</a></li>
<li><a href="http://api.maps.ovi.com/apireference/index.html">Ovi Maps API documentation</a></li>
</ul>
<h2>Yahoo Maps API</h2>
<p><img src="http://www.klauskomenda.com/wp-content/uploads/2011/01/yahoo.png" alt="" title="yahoo" width="293" height="42" class="img-left" />The <a href="http://developer.yahoo.com/maps/">Yahoo Maps API</a> has not received an update for quite a while, the version I had included in my old post was 3.4, the most current one is 3.8. Besides the <a href="http://developer.yahoo.com/maps/ajax/">Ajax API</a>, Yahoo Maps still offers the <a href="http://developer.yahoo.com/flash/maps/">Flash version</a> (although one could argue how useful this still is, considering how powerful JavaScript has become in recent years), as well as a <a href="http://developer.yahoo.com/maps/rest/V1/">REST API</a> for requesting <a href="http://gws.maps.yahoo.com/mapimage?MAPDATA=8Z8wped6wXWCiOAsIjnwUKLbMhPVbCoQ6JDLHQzxjKI43Ol1yV_R91BqMW2iaH_DsVmFvJBHRzPdbTeXZQ7QTLJ_LCXhW_WfjZk94iEDERqpTYCHw8FE0UfTG3lvwBGPUggmzSx0jMjpq.gPw8tkyIY-&#038;mvt=m&#038;cltype=onnetwork&#038;.intl=us&#038;appid=YD-bGrhXEw_JXyniyYzf1l6_NzPNWbPu6Ey5Q--&#038;oper=&#038;_proxy=ydn,xml">static map images</a> (great for non-JS solutions) and <a href="http://developer.yahoo.com/maps/georss/">support for GeoRSS</a>. </p>
<p>The landing page for the Ajax API documentation has a lot of copy &#038; paste examples right there, including a small description and <a href="http://developer.yahoo.com/maps/ajax/V3.8/example/controls.html">a unique URL to display the full example</a>. They also offer a bunch of cheat sheets, which I personally don&#8217;t use because they get outdated quickly (I&#8217;d rather have good up-to-date online documentation with explanatory examples and well-structured API docs). You can download the examples plus the cheat sheets <a href="http://developer.yahoo.com/maps/ajax/V3.8/yahoo_maps_ajax_api_reference_bundle.zip">bundled together in one zip file</a> to explore on your own machine.</p>
<p>The <a href="http://developer.yahoo.com/maps/ajax/V3.8/index.html">actual API documentation</a> is, by far, not as fancy as Ovi&#8217;s, but it somehow serves me much better. For example, if you would like to know which method to call in order to set the zoom level on the map, I just use Strg+F (or ⌘+F on Mac) searching for &#8216;zoom&#8217; in the browser. After a few hits on &#8216;next&#8217;, I found <span class="code">setZoomLevel(zlevel)</span>. Without having to click myself through a class hierarchy structure.</p>
<p>Similar to Ovi, Yahoo Maps requires that type, zoom and pan controls are added separately and are not part of the initial instantiation. </p>
<pre><code>// instantiation
ymap = new YMap(Y.Node.getDOMNode(Y.one('#ymap')), YAHOO_MAP_REG, new YSize(500, 300));

// center on default location
ymap.drawZoomAndCenter(new YGeoPoint(mapOptions.lat, mapOptions.lng), 8);

// add controls as ymaps does not provide them per default
ymap.addTypeControl();     

// Add the zoom control. Long specifies a Slider versus a "+" and "-" zoom control
ymap.addZoomLong();            

// Add the Pan control to have North, South, East and West directional control
ymap.addPanControl(); </code></pre>
<p>Together with Bing Maps, Yahoo Maps also requires an API key in order to actually use the API. The key needs to be part of the URL when requesting the Yahoo Maps API JavaScript.</p>
<p>It terms of available functionality, one can tell that this API has not received any major updates in a while. Apart from the what you would expect from a maps API (display of markers, info windows, polyline overlays), it does not have any outstanding additional functionality, in fact, it actually lacks the ability to get directions (even though the <a href="http://maps.yahoo.com/">web interface</a> offers that). And looking at the map imagery, especially looking at the satellite images, other providers provide much more detail.</p>
<p>Another interesting fact is that the Yahoo API is the only one amongst the 4 whose zoom level scale is somewhat reversed, meaning a zoom level of 1 corresponds to the closest view, whereas zoom level 16 means zoomed out to continent level. What I find really nice though, is that the Yahoo API has a geocoder built-in, in contrast to some of the other APIs. So if I have a location input field, I can just pass whatever the user typed in to the <span class="code">drawZoomAndCenter</span> function, like so:</p>
<pre><code>ymap.drawZoomAndCenter(
    "San Francisco",
    zoomLevel
);</code></pre>
<h3>Resources</h3>
<ul>
<li><a href="http://developer.yahoo.com/maps/">Yahoo Maps Web Services</a></li>
<li><a href="http://developer.yahoo.com/maps/ajax/">Yahoo! Maps AJAX API Getting Started Guide</a></li>
<li><a href="http://developer.yahoo.com/maps/ajax/V3.8/index.html">API Reference Manual</a></li>
</ul>
<h2>Bing Maps API</h2>
<p><img src="http://www.klauskomenda.com/wp-content/uploads/2011/01/bing.png" alt="" title="bing" width="293" height="81" class="img-left" />With the launch of its search engine Bing, Microsoft also redid what was Live Search before and released <a href="http://www.bing.com/maps/">Bing Maps</a>. The <a href="http://msdn.microsoft.com/en-us/library/gg427610.aspx">API</a>, to develop web applications, is currently in its 7.0 version and its MSDN style documentation still makes me think I am in the year 2000&mdash;despite visual changes and redesign of the MSDN site. The first thing Microsoft points out in the <a href="http://msdn.microsoft.com/en-us/library/gg427605.aspx">&#8220;Getting Started&#8221; guide</a> is that you should please sign up for an API key. The documentation provides <a href="http://msdn.microsoft.com/en-us/library/gg427606.aspx">a few examples</a>, which should be taken with a grain of salt, as all of them include the Bing Maps JavaScript in the <span class="code">&lt;head&gt;</span> of the document, which is <a href="http://developer.yahoo.com/performance/rules.html#js_bottom">a bad idea for performance reasons</a>. It is also kinda tedious that they don&#8217;t provide the developer with actual pages where they can see the examples in action, but instead they make you copy and paste the example to your own machine and fill in your personal API key in order to see what is happening. The <a href="http://msdn.microsoft.com/en-us/library/gg427611.aspx">API reference</a> is fairly well structured and clear, however it also lacks a search functionality (although, because it is not that massive, it might not be required).</p>
<p>Instantiation of the map is pretty standard, however centering the map on a new location based on user input is not. In fact, what you need to do is include a script element dynamically, which points to the Bing geocoder webservice, and provide a JavaScript callback for the <a href="http://remysharp.com/2007/10/08/what-is-jsonp/">JSON-P</a> response (as shown in <a href="http://msdn.microsoft.com/en-us/library/gg427601.aspx">this example</a>) Something that should really be abstracted within the API. </p>
<p>In addition to the standard map functionality, Bing Maps also offers <a href="http://msdn.microsoft.com/en-us/library/gg427607.aspx">a directions service</a>, <a href="http://msdn.microsoft.com/en-us/library/gg427619.aspx">custom tile layers</a> and <a href="http://msdn.microsoft.com/en-us/library/gg427600.aspx">displaying localized maps</a>. </p>
<p>In the interface itself, the API offers a so-called Bird&#8217;s eye view, which is essentially a hybrid view (satellite plus road data/labels) which switches over to an angled view, similar to what can be seen in <a href="http://maps.google.com/">Google Maps</a> and <a href="http://www.google.com/earth/index.html">Google Earth</a>, when the zoom level is high enough. I was very impressed by the image quality here, for both cities in the US and Europe (you can see for yourself, searching again for &#8220;Helsinki&#8221; in <a href="http://www.klauskomenda.com/lab/map-api-showdown/">my example</a> and zooming in to the maximum level on Bing Maps, with the map type set to &#8220;Bird&#8217;s eye&#8221;). </p>
<h3>Resources</h3>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/dd877180.aspx">Bing Maps APIs Overview</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/gg427610.aspx">Bing Maps AJAX Control, Version 7.0</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/gg427611.aspx">API reference</a></li>
<li><a href="http://en.wikipedia.org/wiki/Bing_Maps">Wikipedia article on Bing Maps</a></li>
</ul>
<h2>Google Maps API</h2>
<p><img src="http://www.klauskomenda.com/wp-content/uploads/2011/01/google.png" alt="" title="google" width="293" height="61" class="img-left" /> Last, but not least, in my personal opinion the Google Maps API is still king amongst all the Maps APIs out there. The amount of functionality offered by the<a href="http://code.google.com/apis/maps/">Google Maps API family</a> and the <a href="http://code.google.com/apis/maps/documentation/javascript/">JavaScript API</a> itself never ceases to amaze me. With the current version 3, no API key is required any more, which makes inclusion of the JavaScript and getting started even easier.</p>
<p>Google is often criticized for is very developer centric approaches and interfaces, but the sheer amount of documentation they provide for developers plus they way they present it makes it very smooth and easy to use their API. The have a <a href="http://code.google.com/apis/maps/documentation/javascript/basics.html">guide for new developers</a> that covers the basics and standard functionality and an <a href="http://code.google.com/apis/maps/documentation/javascript/reference.html">API reference</a> (similarly structured like the one from Yahoo). But probably the best part of the docs are the <a href="http://code.google.com/apis/maps/documentation/javascript/examples/index.html">examples</a>. Well structured, with <a href="http://code.google.com/apis/maps/documentation/javascript/examples/icon-complex.html">unique URLs</a> for the developer to look at with just one click and digging deeper by doing a simple &#8216;view source&#8217;.  </p>
<p>With regards to functionality, the Google API really offers everything you could ask for from a Maps API&mdash;and more. Just to name a few that strike me as quite impressive are additional map layers, provided by <a href="http://code.google.com/apis/maps/documentation/javascript/examples/layer-kml.html">KML</a> or <a href="http://code.google.com/apis/maps/documentation/javascript/examples/layer-fusiontables-simple.html">Google Fusion Tables</a> as well as <a href="http://code.google.com/apis/maps/documentation/javascript/examples/layer-bicycling.html">Bike Paths</a> and <a href="http://code.google.com/apis/maps/documentation/javascript/examples/directions-travel-modes.html">Routes</a></a>. You can create a <a href="http://code.google.com/apis/maps/documentation/javascript/examples/maptype-styled-complex.html">custom map type with different styles</a>, <a href="http://code.google.com/apis/maps/documentation/javascript/examples/elevation-paths.html">get the elevation along a certain path</a> and include the all so beloved <a href="http://code.google.com/apis/maps/documentation/javascript/examples/streetview-simple.html">Street View</a>. In addition, the API <a href="http://code.google.com/apis/maps/documentation/javascript/basics.html#Mobile">performs great on mobile devices</a>. </p>
<p>The imagery of the satellite images is still very good and the readability of the map view <a href="http://www.41latitude.com/post/2072504768/google-maps-label-readability">has already been discussed on 41latitude.com</a>. It would be great if Google would expose Google Earth views through the JavaScript API as well (for angled views, similar to what Bing offers), but this is exposed through the <a href="http://code.google.com/apis/earth/">Earth API</a>, which is separate from the JS API. It is however seems to be possible to integrate the JS API with the Earth API, although <a href="http://earth-api-samples.googlecode.com/svn/trunk/demos/mapsapi/index.html">the example</a> is referencing the JS API version 2, which is deprecated.</p>
<h3>Resources</h3>
<ul>
<li><a href="http://code.google.com/apis/maps/">Google Maps API Family</a></li>
<li><a href="http://code.google.com/apis/maps/documentation/javascript/">Google Maps JavaScript API V3</a></li>
<li><a href="http://code.google.com/apis/maps/documentation/javascript/reference.html">Google Maps Javascript API V3 Reference</a></li>
<li><a href="http://code.google.com/apis/maps/documentation/javascript/examples/index.html">Google Maps Javascript API V3 Examples</a></li>
</ul>
<h2>Conclusion</h2>
<p>If you are looking for a generic map solution for your site or application, the <span class="highlight">Google Maps API</span> is the way to go. It incorporates features that will most likely cover close to 90 percent of the use cases out there that relate to map applications. However, you might have very specific requirements, that Google Maps might not be able to fulfill to the fullest extent. If you need an API that provides great map data for Europe, then you might want to consider the <span class="highlight">Bing Maps API</span>, which has great satellite imagery of European cities. The <span class="highlight">Ovi Maps API</span> has just been released, but has some innovative approaches in there, whereas the <span class="highlight">Yahoo Maps API</span>, because it has been neglected for quite some time, has been falling a little bit behind when it comes to state-of-the art features. If you want to read more about the topic of maps, especially regarding their readability and quality of imagery, I suggest you check out <a href="http://www.41latitude.com/">Justin O&#8217;Beirne&#8217;s site</a>, where he shares a lot of his thoughts on this topic.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.klauskomenda.com/archives/2011/01/21/the-map-api-showdown/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>A look at PhoneGap and Appcelerator Titanium</title>
		<link>http://www.klauskomenda.com/archives/2011/01/17/a-look-at-phonegap-and-appcelerator-titanium/</link>
		<comments>http://www.klauskomenda.com/archives/2011/01/17/a-look-at-phonegap-and-appcelerator-titanium/#comments</comments>
		<pubDate>Mon, 17 Jan 2011 23:09:28 +0000</pubDate>
		<dc:creator>Klaus</dc:creator>
				<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[comparison]]></category>
		<category><![CDATA[framworks]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[mobile development]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[phonegap]]></category>
		<category><![CDATA[titanium]]></category>

		<guid isPermaLink="false">http://www.klauskomenda.com/?p=853</guid>
		<description><![CDATA[Having been interested into mobile development for quite a while, I had a chance to look at two frameworks that make developing apps for web developers much easier. Without Objective-C or Java.]]></description>
			<content:encoded><![CDATA[<p>Ever since I had started working on my project for my diploma thesis, I was fascinated by the capabilities of smart phones (at the time, in 2006, 3G had just come out in Austria). Even though I had a lot of fun, learned a lot and <a href="archives/2008/12/13/location-based-services-my-book-on-amazon/">even got my thesis published</a>, for one reason or the other, I never really dared to venture into the whole mobile application development sphere professionally, thinking I should stay where I feel comfortable&mdash;web development. However, the developments over the last years, mainly around the <a href="http://www.apple.com/iphone/">iPhone</a>, but also recently regarding <a href="http://www.android.com/">Android</a>, brought me back to this topic I have always been very interested in. Being a web developer (and far away from a &#8220;proper&#8221; Computer Engineer), however, I still can&#8217;t wrap my head around certain technologies, i.e. languages. <a href="http://en.wikipedia.org/wiki/Java_%28software_platform%29">Java</a> is my <a href="http://en.wikipedia.org/wiki/Mount_Whitney">Mt. Whitney</a>, but <a href="http://en.wikipedia.org/wiki/Objective-C">Objective-C</a> is more like a <a href="http://en.wikipedia.org/wiki/Mount_Everest">Mt. Everest</a> to me. So I was very happy to see that there are people that acknowledged that this is a problem and developed <a href="http://en.wikipedia.org/wiki/Multiple_phone_web_based_application_framework">phone web based application frameworks</a> that people with a web development background can take and build mobile applications with. Without having to learn Objective-C. And right there they caught my attention once again.</p>
<h2>What are phone web based application frameworks?</h2>
<p>Essentially, these are frameworks that provide developers coming from a web development background a certain set of tools to use their current skillset (HTML, CSS, JavaScript) to build native or native-like mobile applications. <a href="http://www.phonegap.com/">PhoneGap</a> and <a href="http://www.appcelerator.com/">Appcelerator Titanium</a> are the most popular amongst all the frameworks out in the wild. I got to play around with both of them recently and I am going to share a summary of my findings and a look from 10,000 feet at the two below.</p>
<h2>PhoneGap</h2>
<p><img src="http://www.klauskomenda.com/wp-content/uploads/2011/01/phonegap_logo.jpg" alt="" width="293" height="109" class="img-left" /><a href="http://phonegap.com/">PhoneGap</a>, developed by <a href="http://www.nitobi.com/">Nitobi Software</a>, gained a lot of popularity in the web development world, because of exactly what got me interested myself. On their website, it says &#8220;Build apps in HTML and JavaScript and still take advantage of core features in iPhone/iPod touch, iPad, Google Android, Palm, Symbian and Blackberry SDKs.&#8221;. Sounded exactly what the web developer but wannabe-mobile-developer needs.</p>
<p>PhoneGap projects require the underlying SDKs (e.g. iOS SDK) to be installed and typically building the application happens from an IDE, e.g. Xcode. The developer puts his files into a <span class="code">www</span> folder in the project directory. When building, PhoneGap then renders these files inside a native WebView provided by the OS-specific language (either <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/WebKit/Classes/WebView_Class/Reference/Reference.html">Objective-C</a> or <a href="http://developer.android.com/reference/android/webkit/WebView.html">Java</a>). It exposes access to certain native device features, like Contacts, Accelerometer, Camera and Notifications, through the <a href="http://docs.phonegap.com/">PhoneGap JavaScript API</a>.</p>
<p>The actual interface of the app, however, is styled with &#8216;the usual suspects&#8217;, meaning HTML and CSS. Because of the fact that UI elements are styled with CSS, these can look significantly different to native OS interface elements (e.g. buttons), as well as the performance might be not as good as if native elements were used. </p>
<p>In the end, a PhoneGap application is essentially still a web application, wrapped inside a WebView. It still remains a web application that is displayed through rendering of HTML, CSS and JavaScript using a browser instance on a mobile device. It currently supports development for the iPhone, Google Android, Symbian OS, BlackBerry and Palm operating systems.</p>
<h3>Example</h3>
<p>The following example code is taken from <a href="http://docs.phonegap.com/phonegap_contacts_contacts.md.html#contacts.find">PhoneGaps API documentation</a> to illustrate the syntax of how a PhoneGap application is put together. In this specific case, the API is used to find all contacts with the name &#8216;Bob&#8217; in any name field:</p>
<pre><code>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Contact Example&lt;/title&gt;

    &lt;script type="text/javascript" charset="utf-8" src="phonegap.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript" charset="utf-8"&gt;

    // Wait for PhoneGap to load
    //
    function onLoad() {
        document.addEventListener("deviceready", onDeviceReady, false);
    }

    // PhoneGap is ready
    //
    function onDeviceReady() {
        // find all contacts with 'Bob' in any name field
        var options = new ContactFindOptions();
        options.filter="Bob";
        var fields = ["displayName", "names"];
        navigator.service.contacts.find(fields, onSuccess, onError, options);
    }

    // onSuccess: Get a snapshot of the current contacts
    //
    function onSuccess(contacts) {
        for (var i=0; i&lt;contacts.length; i++) {
            console.log("Display Name = " + contacts[i].displayName);
        }
    }

    // onError: Failed to get the contacts
    //
    function onError() {
        alert('onError!');
    }

    &lt;/script&gt;
  &lt;/head&gt;
  &lt;body onload="onLoad()"&gt;
    &lt;h1&gt;Example&lt;/h1&gt;
    &lt;p&gt;Find Contacts&lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre>
<h2>Appcelerator Titanium</h2>
<p><img src="http://www.klauskomenda.com/wp-content/uploads/2011/01/appcelerator_logo.png" alt="" width="293" height="100" class="img-left" /><a href="http://www.appcelerator.com/products/titanium-mobile-application-development/">Appcelerator Titanium</a> was <a href="http://www.appcelerator.com/2008/12/titanium-introduction/">launched with the same promise</a> like PhoneGap, namely to provide web developers, familiar with HTML, CSS and JavaScript, a tool to use these technologies to develop mobile applications on iOS and Android. In a way, Titanium reminds me of <a href="http://www.j2mepolish.org/cms/leftsection/introduction.html">J2ME Polish</a>, a library for Java Development on mobile devices that enables the developer to <a href="http://www.j2mepolish.org/cms/leftsection/documentation/design/visual-guide.html">create native UI elements</a> and style them using a <a href="http://www.j2mepolish.org/cms/leftsection/documentation/design/css-basics.html">CSS-like syntax</a>. Similar to PhoneGap, Titanium provides a binding layer that maps JavaScript function calls to natively available APIs. However, here is where the similarities end. The main differences to PhoneGap are:</p>
<ul>
<li><span class="highlight">Truly native applications</span>. Unlike PhoneGap, <a href="http://developer.appcelerator.com/guides/en/architecture.html">Titanium actually translates the code into native application code</a>. The application code, written in JavaScript, is being interpreted during runtime and through a bridge layer, function calls to <span class="code">Titanium.some_function</span> invoke native application code under the hood.</li>
<li><span class="highlight">Just JavaScript, no more HTML &amp; CSS</span>. Previous to version 1.0 (current version is 1.5), Titanium followed a similar approach to what PhoneGap was doing. The application code would consist of HTML, CSS and JavaScript, whereas native device services were exposed using a Titanium specific <a href="http://developer.appcelerator.com/apidoc/mobile/latest">JavaScript API</a>.  With version 1.0, HTML and CSS are gone. Code is written in pure JavaScript, using mainly functions that the Titanium API exposes. Apart from using it to access special device features (such as the camera), it also enables the developer to render native UI elements (such as tables, buttons, native maps etc.).</li>
</ul>
<p>The obvious advantage of a native application is performance. The UI will perform much better if native OS elements are used, compared to rendering HTML, CSS and JavaScript in a browser instance to e.g. create a button. As a side effect, the native look-and-feel can easily be maintained.</p>
<p>Unlike PhoneGap, building and packaging does not happen inside an IDE, but through a special piece of software called <a href="http://www.klauskomenda.com/wp-content/uploads/2011/01/titanium_developer_ss.gif" class="lightbox" title="Titanium Developer Screenshot">Titanium Developer</a>. This is the tool to set up new projects, configure, test and package them. Any IDE of your choice can be used to write the application code. </p>
<h3>Example</h3>
<p>Appcelerator provides a plethora of examples, all bundled up in their <a href="http://developer.appcelerator.com/guides/en/kitchensink.html">Kitchen Sink demo application</a>, which can be downloaded from <a href="http://github.com/appcelerator/KitchenSink">GitHub</a>. The following example, <a href="https://github.com/appcelerator/KitchenSink/blob/master/KitchenSink/Resources/examples/shake.js">taken from Kitchen Sink</a>, shows how to hook up an event listener, using the Titanium API, and display an alert window:</p>
<pre><code>var win = Titanium.UI.currentWindow;

var l = Titanium.UI.createLabel({
	text:'Shake your phone',
	top:10,
	color:'#999',
	height:'auto',
	width:'auto'
});

win.add(l);

Ti.Gesture.addEventListener('shake',function(e)
{
	Titanium.UI.createAlertDialog({title:'Shake',message:'it worked!'}).show();
});</code></pre>
<h2>Conclusion</h2>
<p>Both Phone Gap and Appcelerator Titanium give web developers the opportunity to create mobile applications without the need to learn Objective-C or Java. After the build process, both frameworks provide the developer with a packaged application that can be installed  on an actual physical device and published (e.g. using the Apple AppStore). </p>
<p><span class="highlight">PhoneGap</span> supports more Operating Systems and lets the developer essentially set up his application project like he would set up a website (e.g. with <span class="code">index.html</span>, <span class="code">css</span>, <span class="code">img</span> and <span class="code">js</span> folder etc.). PhoneGap applications are then wrapped by the framework inside a WebView during build time. This means that, upon execution, the rendering still happens inside a browser instance, which interprets the HTML, CSS and JavaScript. Compared to a truly native application, this likely means slow performance and additional effort to re-create a native experience.</p>
<p><span class="highlight">Appcelerator Titanium</span> only supports iOS and Android. Any application code is (as of version 1.0) written in pure JavaScript using mainly Titaniums JavaScript API. It seems more like a native code (Objective-C or Java) abstraction layer than code that resembles anything someone would recognize from the web development world. Unlike with PhoneGap, the developer ends up with a final software product that is truly native to the respective operating system. Because native elements are used for the interface (e.g. buttons, tables, views), the performance is better and no effort needs to be put in to recreate any native experience using HTML, CSS and JavaScript. </p>
<p>Finally, it highly depends on the requirements of the product which framework to go with. If the goal is to support as many operating systems as possible, then PhoneGap is probably the way to go. If true native-ness and performance is important, then Titanium will be the better choice. It is also important to note that only PhoneGap still holds true to their promise that a web developer can quickly jump in and use his skills to develop a mobile app. With Titanium, all the application code will be JavaScript, even the styling of elements happens through function calls (which is, arguably, still better to having to use Objective-C). An important factor for deciding which way to go would also be whether the respective JavaScript API provided offers the functionality needed for the application.</p>
<h2>Resources</h2>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Multiple_phone_web_based_application_framework">Wikipedia: multiple phone web based application framework</a> </li>
<li><a href="http://phonegap.com/">PhoneGap</a></li>
<li><a href="http://docs.phonegap.com/">PhoneGap JavaScript API docs</a></li>
<li><a href="http://appcelerator.com/">Appcelerator Titanium</a></li>
<li><a href="http://developer.appcelerator.com/guides/en/architecture.html">Overview over the Appcelerator Titanium architecture</a></li>
<li><a href="http://developer.appcelerator.com/apidoc/mobile/latest">Titanium JavaScript API docs</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.klauskomenda.com/archives/2011/01/17/a-look-at-phonegap-and-appcelerator-titanium/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>First Steps with YUI3</title>
		<link>http://www.klauskomenda.com/archives/2009/07/20/first-steps-with-yui3/</link>
		<comments>http://www.klauskomenda.com/archives/2009/07/20/first-steps-with-yui3/#comments</comments>
		<pubDate>Mon, 20 Jul 2009 19:03:40 +0000</pubDate>
		<dc:creator>Klaus</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.klauskomenda.com/?p=781</guid>
		<description><![CDATA[YUI3 moved from "Preview Release" to "Beta" a few weeks ago. So I figured, this is a good time now to play around with it and see what my colleagues on the other side of the wall came up with.]]></description>
			<content:encoded><![CDATA[<p>I have used <a href="http://developer.yahoo.com/yui/">YUI2</a> quite extensively since I joined Yahoo! in May 2007. Before that I did not really have much experience with any JavaScript library, I had played around with <a href="http://script.aculo.us/">script.aculo.us</a> and <a href="http://jquery.com/">jQuery</a> a little bit, but that was all, pretty much. Because here at Yahoo! we, naturally, use YUI in all our projects, I had to dive in and learn how to use it. After a bit of a rough start, figuring out the basics, I started to like YUI2. The reasons why were the modular approach, the good API documentation and, to me, the general way of how to use certain functions seemed pretty logical to me. Now, with the <a href="http://developer.yahoo.com/yui/3">new 3-series</a> coming out, I was curious about what changed, what improved and what to learn in order to use the next generation of the library.</p>
<h2>A few major differences</h2>
<p>I am not going to go into all the things that are different between YUI2 and YUI3, this is beyond the scope of this post. There is already lots of documentation on <abbr title="Yahoo! Developer Network"><a href="http://developer.yahoo.com/yui/3">YDN</a></abbr> and a <a href="http://developer.yahoo.com/yui/theater/desai-yui3.html">very good video</a> covering lots of questions like &#8220;So whats different?&#8221;. Just a few key things to note:</p>
<ul>
<li>YUI3 is majorly different to YUI2. It is basically a new library and thus also, in a lot of ways, works completely different than its predecessor.</li>
<li>To avoid conflicts between the two libraries, the global YAHOO object (used in YUI2) is now YUI. This also allows to have both YUI2 and YUI3 on the same page.</li>
<li>Every piece of code you write needs to be wrapped in the following statement: <code>YUI().use([YUI3 modules I want to use], function (Y) { ...my code here... } );</code>This, in theory, makes creating namespaces, like we did in YUI2, unnecessary.</li>
</ul>
<h2>A Simple Example: JavaScript Countdown</h2>
<p>Just to play around with it and start with a pretty basic example, I wanted to do a countdown in JavaScript. How would I do that using YUI3?</p>
<h3>Step by Step</h3>
<p>The following steps would need to get executed in order to make this example work:</p>
<ol>
<li>Put basic markup on the page, which marks the start time of the countdown, e.g. 30 minutes and 0 seconds.</li>
<li>Have one function, <span class="code">decreaseSeconds</span> that decreases the seconds and call this function every second (or 1000 milliseconds).</li>
<li>If the seconds counter reaches 0, decrease the minutes using <span class="code">decreaseMinutes</span>.</li>
<li>Stop the timer if minutes and seconds reach 0.</li>
</ol>
<h3>Basic Markup</h3>
<p>As said, the markup on the page already serves as the start time for the countdown and is pretty simple:</p>
<pre><code >&lt;div id="countdown"&gt;
        &lt;span id="min"&gt;30&lt;/span&gt;:&lt;span id="sec"&gt;00&lt;/span&gt;
&lt;/div&gt;</code></pre>
<h3>Putting YUI3 on the page</h3>
<p>In order to put YUI3 on the page, we need to include the YUI Global Object:</p>
<pre><code>&lt;script src="http://yui.yahooapis.com/3.0.0b1/build/yui/yui-min.js" type="text/javascript"&gt;&lt;/script&gt; </code></pre>
<p>And just to verify this is working, we will add some debugging code on the page:</p>
<pre><code>YUI().use("node", function (Y) {
    alert("YUI3 is here!");
});</code></pre>
<p>Just a few words on this. The first argument of the <span class="code">use</span> function, in this case &#8220;node&#8221;, tells the YUI instance which modules to load. As it will turn out later, the <a href="http://developer.yahoo.com/yui/3/node/">node module</a>, together with the functionality that the YUI global object provides, are enough to make this example work. The last argument here is a callback function, which has the YUI instance as an argument. In this function is where your code lives and has access to the YUI3 instance and modules, if loaded in. More on this in the documentation.</p>
<p>So we got the <a href="/lab/yui3/countdown/basics.html">basics</a> covered, YUI3 is on the page and we can move on to the program logic.</p>
<h3>Setting up variables and functions</h3>
<p>First I am going to set up some variables that I am going to need throughout the code:</p>
<pre><code>var minutes = Y.get("#min"),
    seconds = Y.get("#sec"),
    timer,
    liftOff = false;</code></pre>
<p>As you can see here, YUI3 gives you the ability to access a DOM element using CSS selectors out of the box. <span class="code">Y.get(&#8220;#min&#8221;)</span> returns a node (in YUI3 terms) which wraps the underlying DOM object. But be aware that this object here is <em>not</em> the DOM object itself, which is different to what <span class="code">YAHOO.util.Dom.get(&#8220;min&#8221;)</span> would do. </p>
<p>We will also set up the <span class="code">decreaseSeconds</span> function and the timer:</p>
<pre><code>function decreaseSeconds() {
    // get current seconds value
    var secs = seconds.get("innerHTML");

    if (secs === "00") {
        // move to 59
        secs = 59;
        decreaseMinutes();
    } else {
        secs--;
        if (secs &lt; 10) {
            secs = "0" + secs;
        }
    }

    if (!liftOff) {
        seconds.set("innerHTML", secs);
    }
}

timer = Y.later(1000, null, decreaseSeconds, [], true);</code></pre>
<p>Instead of talking about the program logic, which should be pretty straight forward, I would like to highlight YUI3 specific things here:</p>
<ul>
<li>Setting up the timer using <span class="code">Y.later</span> is pretty easy and comparable to <span class="code">YAHOO.later</span> in YUI2.</li>
<li>As the node returned by <span class="code">Y.get</span> is not the DOM node, doing something like <span class="code">seconds.innerHTML</span> does not work. In fact, it will return &#8216;undefined&#8217;. If you do a <span class="code">console.dir(seconds)</span> you will discover that this does not look like a DOM object at all, but is, as stated above, a YUI node instance wrapping the DOM element with id=&#8221;sec&#8221;. So instead of doing <span class="code">.innerHTML</span>, we need to use <span class="code">seconds.get(&#8220;innerHTML&#8221;)</span> to access the content between the opening and closing tag.</li>
<li>Likewise, to set content using innerHTML, we need to do <span class="code">seconds.set(&#8220;innerHTML&#8221;, secs)</span>.</li>
</ul>
<p>This is something to get used to at first. Because in YUI2, people (including me) were used to have the actual DOM object at hand and perform native DOM operations on it. <del>This is not possible anymore with YUI3</del>. It is still possible to access the underlying DOM objects, see <a href="/archives/2009/07/20/first-steps-with-yui3/#comment-22211">Luke&#8217;s comment</a>.</p>
<p>After <a href="/lab/yui3/countdown/vars_and_funct.html">setting this up</a>, we can move on to adding the functionality for decreasing the minutes and making the countdown work.</p>
<h3>Making it work</h3>
<p>Here is the code and logic for decreasing the minutes and canceling the timer if 0 is reached:</p>
<pre><code>function decreaseMinutes() {
    var mins = minutes.get("innerHTML");

    if (mins &gt; 0) {
        mins--;
        if (mins &lt; 10) {
            mins = "0" + mins;
        }
        minutes.set("innerHTML", mins);
    } else {
        timer.cancel();
        liftOff = true;
    }
}</code></pre>
<p>Pretty straight forward and also uses the wrapper methods to access DOM functionality. <a href="/lab/yui3/countdown/almost_there.html">It works now</a>, but we are not quite finished yet.</p>
<h3>Modularizing</h3>
<p>As you can see, all the code is currently inline on the page and gets executed as soon as the page loads. This is suboptimal. What I used to do using YUI2 is creating a module specific namespace and then call a public method (made available through the use of the Module Pattern) on the page that needed that functionality. So for this the module would be, e.g.:</p>
<pre><code>YAHOO.Klaus.Countdown = function () {
    ... my code ...
    return {
         init: init
    };
}();</code></pre>
<p>And then, on whatever page I want to use it, do:</p>
<pre><code>YAHOO.Klaus.Countdown.init();</code></pre>
<p>I was curious how to achieve something like this in YUI3. </p>
<p>I came up with a solution but I am not sure if this is the suggested way of doing this. I hope it is, as I couldn&#8217;t find a different way of doing it. The secret is to add the &#8220;module&#8221; you created as a module to YUI3, like:</p>
<pre><code>Y.add("Klaus.Countdown", init);</code></pre>
<p>The second argument is a function name to be executed when the module is being invoked used the <span class="code">use()</span> function.</p>
<p>So what is left to do is saving the countdown code to a separate file and then call the module from within a script block on the page:</p>
<pre><code>&lt;script type="text/javascript"&gt;
    YUI().use("Klaus.Countdown");
&lt;/script&gt;</code></pre>
<p>So we are done and hopefully happy with our <a href="/lab/yui3/countdown/countdown.html">first steps</a> in YUI3. </p>
<h2>Conclusion</h2>
<p>I have deliberately chosen a simple example to start with to avoid frustrations coming out of having to learn and getting used to too many things at once. Like with every new piece of software, getting started &#8220;somehow&#8221; in the first place is critical and finding out how to achieve things without running into too many roadblocks at once. How easy or hard it is to use YUI3, I have yet to determine when probably facing more complex examples, but I believe this simple examples gives a sneak peak into what awaits at the end of the line.</p>
<h2>Resources</h2>
<ul>
<li><a href="http://developer.yahoo.com/yui/3/">YUI3 on YDN</a></li>
<li><a href="http://developer.yahoo.com/yui/3/api/">YU3 API Doc</a></li>
<li><a href="http://yuiblog.com/">YUI Blog</a></li>
<li><a href="http://www.fatcow.com/edu/first-steps-with-yui3-be/">Belorussian translation of this article</a> kindly provided by Patricia Clausnitzer and <a href="http://www.fatcow.com/">http://www.fatcow.com/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.klauskomenda.com/archives/2009/07/20/first-steps-with-yui3/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Book Review: Object-Oriented JavaScript</title>
		<link>http://www.klauskomenda.com/archives/2009/04/25/book-review-object-oriented-javascript/</link>
		<comments>http://www.klauskomenda.com/archives/2009/04/25/book-review-object-oriented-javascript/#comments</comments>
		<pubDate>Sat, 25 Apr 2009 16:07:34 +0000</pubDate>
		<dc:creator>Klaus</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.klauskomenda.com/?p=752</guid>
		<description><![CDATA[If you ever wanted a JavaScript book that talks about intermediate to advanced, cutting-edge and state-of-the-art techniques, this is the one. Your newly acquired knowledge might also get you nice looks from all the ladies at the next YUI party. Who knows.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.packtpub.com/object-oriented-javascript-applications-libraries/book/mid/030309lf8ofn"><img src="/wp-content/uploads/2009/03/oo_js_cover.jpg" width="235" height="298" class="img-right" /></a>It has been a while since the late nineties in which JavaScript was (ab)used in a very hacky way, i.e. having to work around browser vendor proprietary code (Internet Explorer and Netscape) and, because it provided such a nice variation to otherwise static pages, adding the most useless features to a webpage. Anyone remember the snowflakes following the mouse cursor? Quite some time passed since then and thankfully, JavaScript grew out of puberty and has, in recent years, reached a quite significant stage of adulthood.</p>
<p>Stoyan Stefanov, a colleague of mine at <a href="http://yahoo.com">Yahoo!</a>, recently published <a href="http://www.packtpub.com/object-oriented-javascript-applications-libraries/book/mid/030309lf8ofn">Object-Oriented JavaScript</a>. Personally, the book about JavaScript I was waiting for. A while back, I read and reviewed Jeremy Keith&#8217;s <a href="/library/jeremy-keith/dom-scripting-web-design-with-javascript-and-the-document-object-model/">DOM Scripting</a>, which is the perfect introduction as to how developers should use JavaScript these days in a browser environment. Progressive Enhancement was one of the key concepts in there. So after getting the basics covered, my expectation was that Stoyan&#8217;s book provides me with supporting material for intermediate to advanced JavaScript programming tasks. Does it deliver? We will come to that very shortly.</p>
<h2>Contents</h2>
<p>Chapters 1 to 4 in his book cover a brief history about JavaScript and the basic elements of the language, like variables, primitive data types, conditions and loops as well as functions and objects. The latter already have their specialties in JavaScript and Stoyan explains those special characteristics. </p>
<p>Chapters 5 and 6 are devoted to prototype and how inheritance works in JavaScript, a very essential thing to cover when we are talking about advanced techniques. </p>
<p>Chapter 7 talks about what readers of DOM Scripting might still remember, namely how JavaScript can be used to access and manipulate specific elements in the DOM. The author also takes a look at Events and the ever popular XMLHttpRequest.</p>
<p>And finally, the highlight comes last, Chapter 8 deals with what hardcore programmers were waiting for: Coding and Design Patterns. <a href="/code/javascript-programming-patterns/">Having done a little research about this myself</a>, I found it great that Stoyan documents concepts that have become good practice in the JavaScript world, like namespacing and creating public and private properties and methods. In the design patterns part, he talks about Singletons amongst various other patterns at the programmers disposal. </p>
<p>The book closes with a quite comprehensive appendix, which includes listing reserved words, referencing built-in functions and objects and regular expressions in JavaScript. </p>
<h2>Rating and Reasoning</h2>
<h3 title="My Rating: 9 out of 10" class="rating rating-level-9">My Rating: 9 out of 10</h3>
<p>Even though it states that &#8220;no prior JavaScript knowledge is required&#8221;, I would say that is a bit of an understatement. If DOM Scripting was your first JavaScript book then I would put the following equation on the board: DOM Scripting + experience with these techniques in The Real World (meaning on actual live projects) = ready for Object-Oriented JavaScript. Don&#8217;t get me wrong, Stoyan covers the basics (variables, conditions etc.) in the first few chapters, but after that, the learning curve gets pretty steep and I believe it is safe to say, without <em>any</em> prior knowledge, you will put this book back on the shelf, left frustrated. </p>
<p>I have worked on a couple of minor web projects before <a href="http://uk.yahoo.com">Yahoo! Europe</a> hired me in May 2007, so to this date, I believe I was able to acquire some experience when it comes to using JavaScript on high-scale websites. From my perspective, the first couple of chapters was a nice refresh on the topic, but only then, in Chapters 5 to 8, things got interesting with bits and pieces in there that helped me closing some knowledge gaps about certain concepts, which is really great. This, again, supports my feeling that this book is not meant for <em>every</em> JavaScript developer out there, independent of whether it is a newbie or an advanced developer. I feel that people with probably a couple of years experience might get more out of it than someone who just delved into JavaScript a month ago. </p>
<p>It is difficult to come up with concrete examples to explain this, and this observation is highly subjective of course, but I feel that the way the book is done and written, it feels a lot &#8220;drier&#8221; and less &#8220;exciting&#8221; to read compared to DOM Scripting. Which, again, if this targets JavaScript beginners, should not be the case. But I believe the more complex the material gets, the harder the job becomes of having to thrill and excite the reader. </p>
<p>What I really like about the book is that basically all the examples Stoyan gives, you can type into the Firebug console right away to try out for yourself. As I am a believer that you learn new skills most effectively by actually <em>doing</em> something and play with it, I am pretty sure this is a good way of imparting knowledge. </p>
<h2>Conclusion</h2>
<p>If you are a Web Developer with several years of experience on the job and with JavaScript and you want to move your knowledge level up a notch or two, this book is for you. If you want to play with the cool kids, then <a href="http://www.packtpub.com/object-oriented-javascript-applications-libraries/book/mid/030309lf8ofn">get this book</a>. If you are more or less new to the JavaScript world, you might want to consider starting with DOM Scripting first and getting experience using those techniques on real world projects, before diving into the advanced concepts discussed in Object-Oriented JavaScript.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.klauskomenda.com/archives/2009/04/25/book-review-object-oriented-javascript/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CSS Reviewr</title>
		<link>http://www.klauskomenda.com/archives/2008/12/20/css-reviewr/</link>
		<comments>http://www.klauskomenda.com/archives/2008/12/20/css-reviewr/#comments</comments>
		<pubDate>Sat, 20 Dec 2008 20:17:58 +0000</pubDate>
		<dc:creator>Klaus</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.klauskomenda.com/?p=740</guid>
		<description><![CDATA[Check your CSS code against certain standards and best practices. Brought to you by Santa Klaus. Merry Christmas. ]]></description>
			<content:encoded><![CDATA[<p>There is <a href="http://www.jslint.com/">JSLint</a> for JavaScript, <a href="http://pear.php.net/package/PHP_CodeSniffer">PHP_CodeSniffer</a> for PHP&#8230;why not have some sort of code checking tool for CSS? Based on the outcome of several code reviews we had at <a href="http://uk.yahoo.com/">Yahoo! Europe</a>, I thought that it would come in handy having a tool that would catch findings automatically. So over the last couple of months I was working on such a tool and called it <a href="http://www.klauskomenda.com/tools/cssreviewr/">CSS Reviewr</a>.</p>
<p><a href="http://www.klauskomenda.com/tools/cssreviewr/"><img alt="Try out CSS Reviewr" src="http://www.klauskomenda.com/wp-content/uploads/2008/12/cssreviewr_logo.gif" alt="" width="291" height="50" class="img-right" /></a>It is quite similar to a couple of tools that are already out there. JSLint looks for issues in JavaScript code and checks for adherence to a certain set of code standards. PHP_CodeSniffer, a <a href="http://pear.php.net/">PEAR</a> package, provides similar functionality for PHP files (but is also able to check JavaScript and CSS). Then there is <a href="http://csstidy.sourceforge.net/">CSSTidy</a>, a parser and optimiser for CSS, which e.g. compresses hex values for color declarations and provides different levels of minification (removing comments, whitespace etc.). </p>
<p>Essentially, what I wanted to achieve with CSS Reviewr is to not only point out issues in the code based on the experiences and the reviews we conducted at work, but also to provide explanatory text for each finding (much like how the <a href="http://validator.w3.org/">W3C Validator</a> does it for HTML). In one or two sentences, I wanted to explain why this is an issue and how it can be resolved. From my perspective, this is ideal for a developer who might not be familiar with a certain best practice or convention. By reading the explanation and maybe following a link to a page that provides more details, it has a certain learning effect to it. </p>
<p>CSS Reviewr, as it is stated on the page, is <em>not</em> a validator. It is encouraged to run your code through the <a href="http://jigsaw.w3.org/css-validator/">W3C CSS Validator</a> first, before checking it using CSS Reviewr.</p>
<p>Last, but not least, I would like to thank the real brain behind this: <a href="http://samriley.net/">Sam Riley</a>. I had the pleasure of working with him on <a href="http://answers.yahoo.com/">Yahoo! Answers</a> and I was and am still really impressed by his sheer endless knowledge of the ins and outs of CSS. Knowing that I would not be able to just turn to the side and ask him whenever I have a question related to CSS (because I relocated from London to California), I wrote this tool also to store his CSS knowledge somewhere for myself, so I could still use it here in the US <img src='http://www.klauskomenda.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  So a big thanks to Sam!. Also thanks to <a href="http://www.evalotta.net/">Eva-Lotta</a>, who kindly offered to do some visual design work for this in her spare time. </p>
<p>The tool is in beta right now and I have already identified <a href="http://www.klauskomenda.com/tools/cssreviewr/package/BUGS">some bugs</a> myself that I need to fix at some point, providing I find time for this. Getting some early feedback from colleagues, I have also received the following feature requests:</p>
<ul>
<li>Indentation check (selectable option)</li>
<li>Check (background) images used in the code are akamized/on a content delivery network (CDN)</li>
<li>Fonts should not use uppercase characters (e.g &#8220;Arial&#8221; should be &#8220;arial&#8221;)</li>
<li>Limit the amount of errors shown to 50 to prevent browser (FF2) from crashing. Add something like: &#8220;More than 50 issues found. Fix the issues above first before checking your code again.&#8221;</li>
<li>Having a &#8216;Do it!&#8217; button by each issue to make the suggested modification to the code, and then have a textarea at the bottom where you could copy out the fixed version</li>
</ul>
<p>Suggestions, bug reports and all kinds of feedback welcome. Just leave a comment below. Thanks and happy holidays!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.klauskomenda.com/archives/2008/12/20/css-reviewr/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>WordPress Plugin: Shrinkr</title>
		<link>http://www.klauskomenda.com/archives/2008/10/22/wordpress-plugin-shrinkr/</link>
		<comments>http://www.klauskomenda.com/archives/2008/10/22/wordpress-plugin-shrinkr/#comments</comments>
		<pubDate>Wed, 22 Oct 2008 19:55:20 +0000</pubDate>
		<dc:creator>Klaus</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.klauskomenda.com/?p=683</guid>
		<description><![CDATA["More power!", as Tim Taylor from the TV sitcom "Home Improvement" would say. Don't we all want more power, more performance from our web sites? I was working on a WordPress plugin that enables you to bump up the speed of your site by minification of your CSS and JavaScript files. And now finally found time to release it.]]></description>
			<content:encoded><![CDATA[<p>With higher expectations, both in terms of design and interaction of websites, which are more like web applications these days, the amount and size of JavaScript and CSS files used have increased dramatically during the last couple of years. Ajax, Drag &amp; Drop, Animation&#8230;if your site doesn&#8217;t keep up with the latest trend, you might be left out. But bigger file sizes (and more files) also mean more HTTP requests and having to download more data from the server over an Internet connection, which means slower loading of the page. <a href="http://www.klauskomenda.com/code/wordpress-plugin-shrinkr/">Shrinkr</a> helps you to tackle that problem.</p>
<h2>Description</h2>
<p>Shrinkr does two things:</p>
<ol>
<li>It reduces the file-size of your CSS and JavaScript files through <a href="http://en.wikipedia.org/wiki/Minify">minification</a>, i.e. stripping out unnecessary content like white-space and comments</li>
<li>It then takes those files and concatenates them into one single CSS and one single JavaScript file</li>
<li>Those files are then getting stored as css-min-[timestamp].css and js-min-[timestamp].js on your server. The reason for the timestamp is that whenever Shrinkr creates a new file, it is ensured that a user agent doesn&#8217;t still use a cached version of the previous files but, because the name of the file has changed, retrieves the latest version from the server</li>
</ol>
<p>The first measure reduces the file-size by stripping out things from files that are not needed by the browser in order to interpret them. Whitespace and comments are for developers, not for the browser. They can safely be removed, which reduces the file-size and thus the consumption of bandwidth.</p>
<p>In the <a href="http://developer.yahoo.com/performance/rules.html">Yahoo! Exceptional Performance Rules</a>, it says that one should aim to <a href="http://developer.yahoo.com/performance/rules.html#num_http">reduce the number of HTTP requests</a> in order to make a page load as fast as possible. Shrinkr does that by concatenating all the files into one single file (one for CSS and one for JS). So instead of having 10 CSS files, you will end up having only one.</p>
<p>Shrinkr also adds an action to wp_head and wp_footer in order to tell WordPress to include those files upon page load in the appropriate section of the page. <a href="http://developer.yahoo.com/performance/rules.html#css_top">CSS files should be included in the head of the page</a>, <a href="http://developer.yahoo.com/performance/rules.html#js_bottom">JS at the very bottom</a> as per the Yahoo! Exceptional Performance Rules. </p>
<p>Because of the fact that you will end up having all your CSS and JavaScript in one file and on one line (because all the carriage returns etc. have been stripped out), it makes debugging kind of difficult. For that reason, you should only activate that plugin on the live version of your site and keep the files separated on your development box.</p>
<p>Further details about the plugin can be found on the <a href="http://www.klauskomenda.com/code/wordpress-plugin-shrinkr/">Shrinkr plugin page</a>. It would be great if you could try it out and give me feedback, either by leaving a comment here or using the <a href="/contact/">contact form</a>. Thanks!</p>
<h2>Resources</h2>
<ul>
<li><a href="http://developer.yahoo.com/performance/rules.html">Best Practices for Speeding Up Your Web Site</a></li>
<li><a href="http://developer.yahoo.com/yui/compressor/">Yahoo! UI Library: YUI Compressor</a></li>
<li><a href="http://www.crockford.com/javascript/jsmin.html">JSMIN, The JavaScript Minifier</a></li>
<li><a href="http://code.google.com/p/minify/">Minify!</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.klauskomenda.com/archives/2008/10/22/wordpress-plugin-shrinkr/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Favicons&#8212;demystified</title>
		<link>http://www.klauskomenda.com/archives/2008/10/07/faviconsdemystified/</link>
		<comments>http://www.klauskomenda.com/archives/2008/10/07/faviconsdemystified/#comments</comments>
		<pubDate>Tue, 07 Oct 2008 20:45:34 +0000</pubDate>
		<dc:creator>Klaus</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.klauskomenda.com/?p=622</guid>
		<description><![CDATA[Once for every project you do you stumble upon them: favicons. And every time I struggle to remember what it is I need to pay attention to when creating them. So here is another guide for the next time I come across the to-do item "Create a favicon". ]]></description>
			<content:encoded><![CDATA[<p>One of the few things you only come across once in a while is creating a <a href="http://en.wikipedia.org/wiki/Favicon">favicon</a>. It only needs to be done once, doesn&#8217;t need any ongoing maintenance or debugging. Do it once, done. That&#8217;s the reason, at least in my case, that every time I get to the task &#8220;Create a favicon for the page&#8221;, I try to remember how exactly they need to be created and what to pay attention to. So this is another &#8220;remember for next time&#8221; article. </p>
<p>There are three ways to generate a favicon:</p>
<ul>
<li>Photoshop (or any other graphics editing program)</li>
<li>Online tools</li>
<li>On the fly</li>
</ul>
<h2>Photoshop</h2>
<p>I say Photoshop here, because that is what I am used to, but essentially you could use any graphics editing program out there. Essentially, when you have your graphic ready, you could just simply save it as a PNG or GIF. Well, you can do that, but that won&#8217;t work in Internet Explorer. </p>
<p>To make your favicon display in every browser, you need to create an <a href="http://en.wikipedia.org/wiki/ICO_(icon_image_file_format)">ICO</a> file. To do that with Photoshop, you can install a plugin that helps you do so. </p>
<h3>Installing the plugin</h3>
<p>First you need to download the plugin from <a href="http://www.telegraphics.com.au/sw/">Telegraphics</a> for whichever version of Photoshop you are using. Extract the ZIP file and move the plugin file into the &#8220;File Formats&#8221; folder inside your Photoshop Plugins folder:</p>
<ul>
<li>On Windows, ICOFormat.8bi (the path should be similar to: C:\Program Files\Adobe\Adobe Photoshop CS2\Plug-Ins\File Formats\)</li>
<li>On OS X/Classic, icoformat (CS2/Mac version is ICOFormat_cs2.plugin)</li>
</ul>
<p>After you have done that quit and relaunch Photoshop, if it&#8217;s already running. To check if the plugin is installed correctly, go to Help &gt; About Plug-ins. In this list, the ICO plugin should appear.</p>
<h3>Saving your graphic in ICO format</h2>
<p>There are some constraints as to which images are eligible to be saved in ICO format:</p>
<ul>
<li>The ICO format does not allow images more than 255 pixels high or wide.</li>
<li>Only Bitmap, Grey Scale, Indexed and RGB mode images, no more than 8 bits per channel, can be saved as ICO.</li>
</ul>
<p>If the graphic you created meets those requirements, you can go to &#8220;Save&#8221; or &#8220;Save As&#8230;&#8221; and select &#8220;ICO (Windows Icon) *.ICO&#8221; from the list of available file formats. The size of the final image should either be 16&#215;16 or 32&#215;32 pixels, larger images would just need to be scaled down by the browser.</p>
<h2>Online tools</h2>
<p>Following is a list of tools on the web that make it even easier to create favicons. In principle, you can upload an image file that you already have to the service, which will create a favicon file from that image. </p>
<ul>
<li><a href="http://favicon-generator.org/">Favicon Generator</a></li>
<li><a href="http://favikon.com/">Favikon</a></li>
<li><a href="http://www.favicon.cc/">favicon.ico Generator</a></li>
<li><a href="http://www.chami.com/html-kit/services/favicon/">FavIcon from Pics</a></li>
</ul>
<h2>On the fly</h2>
<p>Using the <a href="http://en.wikipedia.org/wiki/Data:_URI_scheme">data URI scheme</a>, it is possible to include data items, such as an image, inline on a webpage, without actually referencing it as an external resource. The format for that URI scheme is:</p>
<pre><code>data:[&lt;MIME-type&gt;][;base64],&lt;data&gt; </code></pre>
<p>The <a href="http://validator.w3.org/">W3C Validator</a> for example makes use of this. If your markup validation fails, the red square displayed in the address bar is referenced as:</p>
<pre><code>&lt;link rel="icon" href="data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%10%00%00%00%10%08%02%00%00%00%90%91h6%00%00%00%19IDAT(%91c%BCd%AB%C2%40%0A%60%22I%F5%A8%86Q%0DCJ%03%00%DE%B5%01S%07%88%8FG%00%00%00%00IEND%AEB%60%82" type="image/png" /&gt;</code></pre>
<p>In the example from the W3C Validator, the data for the favicon is represented using <a href="http://en.wikipedia.org/wiki/ASCII">ASCII</a> encoding, but could also be encoded as <a href="http://en.wikipedia.org/wiki/Base64">base64</a>, which would then look like this in the HTML source:</p>
<pre><code>&lt;link rel="icon" href="data:image/png;base64,/9j/4AAQ..." type="image/png" /&gt;</code></pre>
<h2>Referencing it in HTML</h2>
<p>When you have your favicon file, place it somewhere on your webspace of your site (it does not have to be the root directory) and then reference the file in HTML (in the head of the document) like so:</p>
<pre><code>&lt;link rel="Shortcut Icon"
      href=""http://example.com/favicon.ico"
      type="image/x-icon"&gt;</code></pre>
<p>If you now go to your site and refresh the browser, you should see your icon showing up in the address bar.</p>
<p>On a sidenote: if you ever wanted to play <a href="http://en.wikipedia.org/wiki/Defender_(video_game)">Defender</a> displayed in a 16&#215;16 pixels favicon, <a href="http://www.p01.org/releases/DHTML_contests/files/DEFENDER_of_the_favicon/">you can do so now</a>. Not necessarily useful for everyday websites, but a great demo of what can be done with favicons.</p>
<h2>Resources</h2>
<ul>
<li><a href="http://www.w3.org/2005/10/howto-favicon">How to Add a Favicon to your Site &#8211; QA @ W3C</a></li>
<li><a href="http://www.photoshopsupport.com/tutorials/jennifer/favicon.html">Mysteries Of The Favicon.ico — How To Create A Favicon In Photoshop</a></li>
<li><a href="http://www.amenco.com/golivein24//tips/favicon/">Creating favicons with Adobe Photoshop and GoLive</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.klauskomenda.com/archives/2008/10/07/faviconsdemystified/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing Apache, MySQL and PHP on Leopard</title>
		<link>http://www.klauskomenda.com/archives/2008/10/07/installing-apache-mysql-and-php-on-leopard/</link>
		<comments>http://www.klauskomenda.com/archives/2008/10/07/installing-apache-mysql-and-php-on-leopard/#comments</comments>
		<pubDate>Tue, 07 Oct 2008 18:11:21 +0000</pubDate>
		<dc:creator>Klaus</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.klauskomenda.com/?p=611</guid>
		<description><![CDATA[Having a proper Web Development environment set up on your development machine is essential to test and, well, develop. As I had to go through that process again recently, I thought that documenting it for future reference might be a good idea.]]></description>
			<content:encoded><![CDATA[<p>Working in Web Development means you have to have a development environment installed on your local machine, in order to test and develop dynamic pages, using a web server (<a href="http://httpd.apache.org/">Apache,</a>), a database (<a href="http://www.mysql.com/">MySQL</a>) and a scripting language (<a href="http://www.php.net/">PHP</a>). There are ways of getting those components installed in a bundle, like <a href="http://en.wikipedia.org/wiki/WAMP">WAMP</a>, <a href="http://en.wikipedia.org/wiki/LAMP_(software_bundle)">LAMP</a> or <a href="http://en.wikipedia.org/wiki/MAMP">MAMP</a>. But as a developer, you are more the manual type, right? So as I had to go through that installation process recently, this article documents the steps I went through. </p>
<h2>Apache</h2>
<p><a href="http://www.apple.com/macosx/">OSX</a> already comes with Apache installed, it is just a matter of starting the server. You can do this if you go to System Preferences &gt; Sharing and check &#8220;Web Sharing&#8221;. The Apache default page should now be displayed at </p>
<pre><code>http://localhost</code></pre>
<p>Later on, you can use the following commands to start, stop or restart Apache:</p>
<p><kbd>$ sudo apachectl start<br />
$ sudo apachectl stop<br />
$ sudo apachectl restart<br />
</kbd></p>
<p>If you would like to change the DocumentRoot of the server, you need to edit the httpd.conf file:</p>
<p><kbd>$ sudo vi /etc/apache2/httpd.conf</kbd></p>
<p>In here, you need to change the DocumentRoot setting:</p>
<pre><code>DocumentRoot "/Users/myUser/myNewWebroot/"
&lt;Directory "/Users/myUser/myNewWebroot/"&gt;
...
&lt;/Directory&gt;</code></pre>
<h2>PHP</h2>
<p>PHP comes bundled up with Leopard as well. The important things to know here are where it got installed and where to find the configuration file. </p>
<p>Most likely, it got installed to:</p>
<div class="code">
/usr/local/php5
</div>
<p>The configuration file should be located at:</p>
<div class="code">
/private/etc/php.ini
</div>
<p>You only need to make sure that Apache knows that PHP is available, so edit httpd.conf:<br />
<kbd>$ sudo vi /etc/apache2/httpd.conf</kbd></p>
<p>And add the following lines (in the appropriate sections, to keep things tidy):</p>
<div class="code">
AddType application/x-httpd-php .php<br />
AddType application/x-httpd-php-source .phps<br />
&#8230;<br />
LoadModule php5_module        libexec/apache2/libphp5.so
</div>
<p>Finished with that, restart Apache, empty the browser cache and then load a php file for testing if it is correctly interpreted. </p>
<h2>MySQL</h2>
<p>Download the <a href="http://dev.mysql.com/downloads/mysql/5.0.html#macosx-dmg">most recent dmg image</a> from the MySQL site.</p>
<p>Before actually installing MySQL, I found it helps to restart the computer before proceeding with the installation. When running through the installation wizard, MySQL will get installed to:</p>
<div class="code">
/usr/local/mysql-VERSION
</div>
<p>So, for example:</p>
<div class="code">
/usr/local/mysql-5.0.51b-osx10.5-x86/
</div>
<p>Also, a symlink should have been created:</p>
<div class="code">
/usr/local/mysql -> mysql-5.0.51b-osx10.5-x86
</div>
<p>You should also install the Preference Pane, which comes with the installation package as <span class="code">MySQL.prefPane</span></p>
<p>To start MySQL manually, run the following command:<br />
<kbd>$ sudo /Library/StartupItems/MySQLCOM/MySQLCOM start</kbd></p>
<p>You should also add MySQL to $PATH:<br />
<kbd>$ vi ~/.profile<br />
$ export PATH=$PATH:/usr/local/mysql/bin<br />
$ source ~/.profile<br />
</kbd></p>
<p>To check whether that was successful, run:<br />
<kbd>$ echo $PATH</kbd></p>
<p>The default settings for the root user are:</p>
<ul>
<li>Username: root</li>
<li>Password: [leave blank]</li>
</ul>
<h2>Add-on: PHPmyAdmin</h2>
<p>To get <a href="http://www.phpmyadmin.net/">PHPmyAdmin</a> installed, which comes in handy for managing your database(s), download the latest package from <a href="http://www.phpmyadmin.net/home_page/downloads.php">their download page</a>. Extract that package to a directory somewhere in your DocumentRoot.</p>
<p>Open <span class="code">config.sample.inc.php</span> with an editor of your choice and add the following details for your MySQL installation:</p>
<pre><code>/*
 * This is needed for cookie based authentication to encrypt password in
 * cookie
 */
$cfg['blowfish_secret'] = 'whatever'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */

$cfg['Servers'][$i]['user']          = 'root';
$cfg['Servers'][$i]['password']      = ''; // use here your password</code></pre>
<p>After you made those changes, save the file as <span class="code">config.inc.php</span>.</p>
<h2>PEAR</h2>
<p><a href="http://pear.php.net/">PEAR</a> should also already be available on your Mac. The location is probably:</p>
<div class="code">
/usr/local/php5/bin/pear
</div>
<p>It is a good idea to add the path to PEAR to $PATH, similar to setting the path for MySQL (see above). In addition, upgrade PEAR to the latest version like so:</p>
<p><kbd>$ sudo pear channel-update pear.php.net<br />
$ sudo pear upgrade PEAR<br />
</kbd></p>
<h2>Resources</h2>
<ul>
<li><a href="http://dev.mysql.com/doc/refman/5.0/en/mac-os-x-installation.html">Installing MySQL on Mac OS X (MySQL Reference Manual)</a></li>
<li><a href="http://unlettered.org/2007/11/14/installing-mysql-50-on-mac-os-x-105-client/">Installing MySQL 5.0 on Max OS X 10.5 client</a></li>
<li><a href="http://switch.richard5.net/isp-in-a-box-v2/installing-mysql-on-mac-os-x/">Installing MySQL on Mac OS X</a></li>
</li>
]]></content:encoded>
			<wfw:commentRss>http://www.klauskomenda.com/archives/2008/10/07/installing-apache-mysql-and-php-on-leopard/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
	</channel>
</rss>

