<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"> <channel><title>SitePoint » Learn CSS | HTML5 | JavaScript | Wordpress | Tutorials-Web Development | Reference | Books and More</title> <link>http://www.sitepoint.com</link> <description /> <lastBuildDate>Tue, 15 May 2012 15:45:36 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" /> <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/SitepointFeed" /><feedburner:info uri="sitepointfeed" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>Two New Proposals to Solve the CSS3 Vendor Prefix Crisis</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/jvswTdgA9NU/</link> <comments>http://www.sitepoint.com/css3-vendor-prefix-crisis-solutions-2/#comments</comments> <pubDate>Tue, 15 May 2012 15:41:07 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[CSS Tutorials]]></category> <category><![CDATA[CSS3]]></category> <category><![CDATA[Discussion]]></category> <category><![CDATA[HTML & CSS]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[News & Trends]]></category> <category><![CDATA[Web Tech]]></category> <category><![CDATA[CSS]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[HTML5 Tutorials & Articles]]></category> <category><![CDATA[vendor prefixes]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54609</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/02/641-css-vendor-prefix-crisis-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="641-css-vendor-prefix-crisis" title="641-css-vendor-prefix-crisis" />Craig discusses two new proposals which could prevent the CSS3 vendor prefix catastrophe before it begins.]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/02/641-css-vendor-prefix-crisis-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="641-css-vendor-prefix-crisis" title="641-css-vendor-prefix-crisis" /><p></p><p>Web developers have been concerned about the <a
href="http://www.sitepoint.com/w3c-css-webkit-prefix-crisis/">vendor prefix crisis</a> since February 2012. To summarize the issue, this is what should happen in an ideal world:</p><ol><li>Vendors implement experimental CSS3 properties using their own prefix, e.g. -webkit-transform, -moz-transform, -ms-transform, -o-transform.</li><li>Developers can use the technologies today without breaking cross-browser compatibility. Properties can be listed with their prefixed and unprefixed names to ensure they work everywhere.</li><li>Once a property becomes a W3C recommendation, all browser vendors can provide a stable unprefixed property, e.g. transform.</li><li>Optionally, developers can remove the prefixed properties from their stylesheets. However, it&#8217;s not strictly necessary if the unprefixed property is defined last and CSS cascade rules apply.</li></ol><p>This is what occurs in the real world:</p><ol><li>Vendors implement experimental CSS3 properties using their own prefix. In some cases, vendors promote them as an HTML5 <em>&#8220;standard&#8221;</em> even if they&#8217;re device-specific or never submitted to the W3C.</li><li>Some developers use the proprietary property from a single vendor, e.g. only -webkit-transform. This might be owing to ignorance, laziness or because they&#8217;re testing a limited number of devices.</li><li>Once a property becomes a W3C recommendation, all browser vendors can provide a stable unprefixed property, e.g. transform&hellip;</li><li>but developers neglect to change their stylesheets. The site looks good in some browsers but worse in others even when they support the standard W3C specification.</li><li>The vendors become concerned and add support for other prefixes into their browser, i.e. <a
href="http://www.sitepoint.com/opera-css3-webkit-prefix/">Opera implements the -webkit prefix for some properties</a>. The prefix process is broken and, while it&#8217;s too early to predict the outcome, the majority of developers consider it to be a bad move.</li></ol><p>We have discussed the issues at length on SitePoint; <a
href="http://www.sitepoint.com/css3-vendor-prefix-crisis-solutions/" class="broken_link">there are no easy solutions</a>. However, two interesting proposals have been raised by W3C members during the past week.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><h2>Option 1: Unprefixed Properties are Supported From Day One</h2><p>The first proposal comes from Florian Rivoal, Opera&#8217;s W3C representative:</p><blockquote><p> When a browser vendor implements a new CSS feature, it should support it, from day 1, both prefixed and unprefixed, the two being aliased. If a style sheet contains both prefixed and unprefixed, the last one wins, according to the cascade.</p><p>Authors should write their style sheets using the unprefixed property, and only add a prefixed version of the property (below the unprefixed one) if they discover a bug or inconsistency that they need to work around in a particular browser.</p><p>If a large amount of content accumulates using the a particular vendor prefix to work around an issue with the early implementation in that browser, the vendor could decide to freeze the behavior of the prefixed property while continuing to improve the unprefixed one.</p></blockquote><p>For example, you could use the following transform code in your CSS:</p><pre><code>
transform: rotate(30deg);
</code></pre><p>The property would be ignored by all browsers which had not implemented transforms. If there were a difference between two or more implementations, e.g. webkit browsers rotated anti-clockwise by default, you could override the property accordingly, e.g.</p><pre><code>
transform: rotate(30deg);
-webkit-transform: rotate(-30deg);
</code></pre><p>It&#8217;s a simple solution and easy to implement. Most existing stylesheets would continue to work and prefixed properties would rarely be necessary. In most cases, you would never need to update your CSS again.</p><p>However, what would happen if webkit changed rotation to the W3C-approved clockwise direction? Developers would need to fix their stylesheets by removing or rearranging the <code>-webkit-transform: rotate(-30deg);</code> property. Unfortunately, not everyone uses the same version of the webkit engine at the same time. You could encounter a situation where your site works in Chrome but not in Safari for several months.</p><h2>Option 2: A New Vendor-Draft Modifier</h2><p>The second proposal comes from Fran&ccedil;ois Remy:</p><blockquote><p> Let&#8217;s introduce the &#8220;!vendor-draft&#8221; value modifier. I propose we use unprefixed properties from start, but with a token explaining which version of the property we built our CSS for:<br
/> <code>border-radius: 3px !webkit-draft;</code></p><p>Any browser which is not webkit but implemented border-radius in a way that is compatible with the &#8220;webkit draft&#8221; can support the declaration. This is different from vendor prefixes: other browsers don&#8217;t impersonate webkit, they just acknowledge they support one specific property the way the webkit draft defines it. Browsers which are not compatible with that draft will just ignore the declaration. Browsers that change their implementation of a property are encouraged to iterate their &#8220;!vendor-draft&#8221; flag (using a version number, if appropriate).</p></blockquote><p>This solves the issue by changing the property value rather than its name (in a similar way to the <code>!important</code> modifier). Again, the following transform code could be used:</p><pre><code>
transform: rotate(30deg);
</code></pre><p>But a default anti-clockwise rotation could be fixed in any browser adhering to a webkit specification:</p><pre><code>
transform: rotate(30deg);
transform: rotate(-30deg) !webkit-draft;
</code></pre><p>If a browser subsequently supported the W3C specification, the second property would be ignored.</p><p>It would also be possible to implement draft versioning, e.g.</p><pre><code>
transform: rotate(30deg);
transform: rotate(-30degrees) !webkit-draft;
transform: rotate(-30deg) !webkit-draft-2;
</code></pre><p>It&#8217;s a flexible solution which finally addresses the issue of properties evolving over time.</p><p>Unfortunately, it&#8217;s more difficult to implement and could take months to appear in browsers even if all vendors agreed today. It may be technically better, but it&#8217;s a fundamentally different approach which could break existing stylesheets. In the short term, vendors would probably support both prefixes and value modifiers &#8212; and that would lead to confusion.</p><p>I like both solutions. From a coding perspective, vendor-draft modifiers seems the most logical option but I doubt it can be considered until vendors <em>&#8220;complete&#8221;</em> CSS3 and begin work on CSS4.</p><p>Supporting unprefixed properties is more practical but will certainly cause versioning issues which couldn&#8217;t be fixed in CSS alone. But perhaps that&#8217;s the price you pay for using experimental technology?</p><p>Do you have a preference for either of these options? Or is it too late to prevent a vendor prefix catastrophe?</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=jvswTdgA9NU:ikOCNkvrzRI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=jvswTdgA9NU:ikOCNkvrzRI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=jvswTdgA9NU:ikOCNkvrzRI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=jvswTdgA9NU:ikOCNkvrzRI:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/jvswTdgA9NU" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/css3-vendor-prefix-crisis-solutions-2/feed/</wfw:commentRss> <slash:comments>2</slash:comments> <feedburner:origLink>http://www.sitepoint.com/css3-vendor-prefix-crisis-solutions-2/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=css3-vendor-prefix-crisis-solutions-2</feedburner:origLink></item> <item><title>An Overview of the Web Storage API</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/6YgqxQxVO1U/</link> <comments>http://www.sitepoint.com/an-overview-of-the-web-storage-api/#comments</comments> <pubDate>Tue, 15 May 2012 15:00:11 +0000</pubDate> <dc:creator>Colin Ihrig</dc:creator> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54156</guid> <description><![CDATA[<img
width="50" height="32" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/shutterstock_59314054-50x32.jpg" class="attachment-thumbnail wp-post-image" alt="shutterstock_59314054" title="shutterstock_59314054" />Web developers have long yearned for a way to store data long term.  Cookies are an option, but they can only store 4KB of data.  Additionally, cookies are sent to the server with each HTTP request.  This means that cookies, especially large ones, can consume considerable network bandwidth.  There have been other attempts to implement [...]]]></description> <content:encoded><![CDATA[<img
width="50" height="32" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/shutterstock_59314054-50x32.jpg" class="attachment-thumbnail wp-post-image" alt="shutterstock_59314054" title="shutterstock_59314054" /><p></p><p
style="text-align: justify" dir="ltr">Web developers have long yearned for a way to store data long term.  Cookies are an option, but they can only store 4KB of data.  Additionally, cookies are sent to the server with each HTTP request.  This means that cookies, especially large ones, can consume considerable network bandwidth.  There have been other attempts to implement storage techniques, but for the most part they have been hacks.  Then, along came HTML5 and the <a
title="Web Storage" href="http://dev.w3.org/html5/webstorage/" target="_blank">Web Storage API</a> to the rescue.</p><p
style="text-align: justify">The Web Storage API defines two types of storage areas ― local storage and session storage.  Local storage is persistent data which remains until it is explicitly deleted, or until the browser&#8217;s cache is cleared.  According to the specification, browsers should allocate at least 5MB of local storage per domain.  The second storage type, session storage, is also persistent data, however the data is tied to a &#8220;top-level browsing context&#8221; (i.e. a browser tab or window).  Session data remains until it is either deleted or the browsing context is closed.  Session storage is particularly useful when a user is interacting with multiple instances of the same website.  In such a situation, using local storage could result in the different instances overwriting each others data.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p
style="text-align: justify">The two types of storage areas are accessed through global objects named &#8220;localStorage&#8221; and &#8220;sessionStorage&#8221;.  Both storage areas implement the exact same API.  Data is stored as key/value pairs, and all data is stored in string form.  When adding data to storage, it is implicitly converted to a string.  However, when the string data is retrieved from storage it needs to be explicitly converted to the appropriate data type using functions such as <a
title="parseInt() Documentation" href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/parseInt" target="_blank">parseInt()</a>.  When dealing with objects, the <a
title="Native Browser Support for JSON (Part 1 of 2)" href="http://cjihrig.com/blog/native-browser-support-for-json-part-1/" target="_blank">JSON.parse()</a> and <a
title="Native Browser Support for JSON (Part 2 of 2)" href="http://cjihrig.com/blog/native-browser-support-for-json-part-2-of-2/" target="_blank">JSON.stringify()</a> methods should be used for serialization and deserialization.</p><h1>Detecting Storage Support</h1><p
style="text-align: justify" dir="ltr">The Web Storage API, like many other HTML5 features, is not supported by all browsers.  To check if a browser supports storage, use the function shown below.  The function checks for the existence of the global &#8220;localStorage&#8221; object.  A similar function could be created to check for session storage, but it can be safely assumed that if one storage area exists, then so does the other.</p><pre>function localStorageSupported() {
  try {
    return "localStorage" in window &amp;&amp; window["localStorage"] !== null;
  } catch (e) {
    return false;
  }
}</pre><h1 style="text-align: justify">Storing Data</h1><p
style="text-align: justify">Data is added to storage using the setItem() method.  setItem() takes a key and value as arguments.  If the key does not already exist in storage, then the key/value pair is added.  If the key is already present, then the value is updated.  Several example setItem() usages are shown below.  The examples show how to add data of various types to local and session storage.  Notice that the &#8220;key&#8221; argument must always be a string, while the type of &#8220;value&#8221; can vary.</p><pre style="text-align: justify">localStorage.setItem("key", "value");
sessionStorage.setItem("foo", 3.14);
localStorage.setItem("bar", true);
sessionStorage.setItem("baz", JSON.stringify(object));</pre><p
style="text-align: justify" dir="ltr">Data can also be added to storage using object property assignment statements.  The previous setItem() examples have been rewritten below using assignment statements. Note that the assignment to &#8220;key&#8221; on the first line will fail silently.  This is because the storage areas have a built in function named key() that will be covered later.  For this reason, the API methods are the preferred way to access storage.</p><pre style="text-align: justify">localStorage.key = "value"; // this fails silently
sessionStorage.foo = 3.14;
localStorage["bar"] = true;
sessionStorage["baz"] = JSON.stringify(object);</pre><p
style="text-align: justify">If a site attempts to store too much data, eventually the browser’s storage quota will be exceeded and an exception will be thrown.  To handle this case, try-catch blocks should be used when storing data.  An example of this is shown below.</p><pre>try {
  localStorage.setItem("key", "value");
} catch (e) {
  alert("Exceeded Storage Quota!");
}</pre><h1 style="text-align: justify">Reading Stored Data</h1><p
style="text-align: justify">To read data from storage, the getItem() method is used.  getItem() takes a lookup key as its sole argument.  If the key exists in storage, then the corresponding value is returned.  If the key does not exist, then null is returned.  The following examples use the getItem() method to retrieve the data stored in the setItem() examples.</p><pre style="text-align: justify">var string = localStorage.getItem("key");
var number = sessionStorage.getItem("foo");
var boolean = localStorage.getItem("bar");
var object = JSON.parse(sessionStorage.getItem("baz"));</pre><p
style="text-align: justify">Stored data can also be accessed by reading properties of the &#8220;localStorage&#8221; and &#8220;sessionStorage&#8221; objects.  The previous getItem() examples have been rewritten below using object property syntax.</p><pre style="text-align: justify">var string = localStorage.key;
var number = sessionStorage.foo;
var boolean = localStorage["bar"];
var object = JSON.parse(sessionStorage["baz"]);</pre><h1 style="text-align: justify">Iterating Over Stored Data</h1><p
style="text-align: justify">Often times, it is necessary to programmatically loop over all of the items in storage.  The loop&#8217;s upper bound is determined by the &#8220;length&#8221; property of the particular storage area.  The stored keys can be retrieved one at a time using the key() method.  key() takes a single integer parameter that acts as an index to the storage area.  An example of looping over each key/value pair in &#8220;localStorage&#8221; is shown below.  Of course, session storage can be processed in a similar fashion by substituting &#8220;sessionStorage&#8221; for &#8220;localStorage&#8221;.</p><pre style="text-align: justify">for (var i = 0; i &lt; localStorage.length; i++) {
  var key = localStorage.key(i);
  var value = localStorage.getItem(key);
  // do something with the key and value
}</pre><h1 style="text-align: justify">Deleting Stored Data</h1><p
style="text-align: justify">When data is no longer needed, it should be explicitly removed.  This is especially true for local storage, as it will persist even after the browser is closed.  To delete individual key/value pairs from storage, the removeItem() method is used.  The removeItem() method takes the key to be deleted as its only parameter.  If the key is not present then nothing will happen.  Examples of the removeItem() method are shown below.</p><pre style="text-align: justify">localStorage.removeItem("key");
sessionStorage.removeItem("foo");
localStorage.removeItem("bar");
sessionStorage.removeItem("baz");</pre><p
style="text-align: justify">The delete operator can also be used to remove stored data.  The previous example is rewritten below using delete instead of removeItem().</p><pre style="text-align: justify">delete localStorage.key;
delete sessionStorage.foo;
delete localStorage["bar"];
delete sessionStorage["baz"];</pre><p
style="text-align: justify" dir="ltr">While removeItem() is used to delete individual pieces of data, the clear() method is used to delete all stored data.  Usages of the clear() method are shown below.</p><pre style="text-align: justify">localStorage.clear();
sessionStorage.clear();</pre><h1 style="text-align: justify">The storage Event</h1><p
style="text-align: justify">A user can potentially have several instances of the same site open at any given time.  Changes made to a storage area in one instance need to be reflected in the other instances.  The Web Storage API accomplishes this synchronization using the &#8220;storage&#8221; event.  When a storage area is changed, a &#8220;storage&#8221; event is fired for any other tabs/windows that are sharing the storage area.  Note that a &#8220;storage&#8221; event is <em>not</em> fired for the tab/window that changes the storage area.</p><p
style="text-align: justify">Storage areas can be changed by calls to setItem(), removeItem(), and clear().  However, not all calls to these methods actually change the storage area.  For example, calling clear() on an empty storage area or removeItem() on a key that does not exist will not change the storage area, and therefore will not fire an event.</p><p
style="text-align: justify">The &#8220;storage&#8221; event object has several fields of interest which are described below.  Following the description of the fields is an example &#8220;storage&#8221; event handler.</p><ul
style="text-align: justify"><li>&#8220;key&#8221; ― This field is the key argument of setItem() or removeItem(), or null when clear() caused the event to be fired.</li><li>&#8220;newValue&#8221; ― The &#8220;value&#8221; argument to setItem() is reflected in this field.  Calls to removeItem() and clear() cause this field to be null.</li><li>&#8220;oldValue&#8221; ― This field holds the key&#8217;s value prior to a call to setItem() or removeItem().  Calls to clear() cause this field to be null.</li><li>&#8220;url&#8221; ― The &#8220;url&#8221; field stores the address of the page whose storage area was affected.</li><li>&#8220;storageArea&#8221; ― The &#8220;storageArea&#8221; field corresponds to the local or session storage area that was changed.</li></ul><pre style="text-align: justify">window.addEventListener("storage", function(event) {
  var key = event.key;
  var newValue = event.newValue;
  var oldValue = event.oldValue;
  var url = event.url;
  var storageArea = event.storageArea;
  // handle the event
});</pre><h1 style="text-align: justify">Example Page</h1><p
style="text-align: justify">The following code implements a sample page for manipulating local storage.  The page is also available online <a
title="Web Storage Example" href="http://www.cjihrig.com/development/html5/storage.htm" target="_blank">here</a>.  The example covers the entire local storage API, including the &#8220;storage&#8221; event.  In order to see the &#8220;storage&#8221; event in action, the page must be open in at least two separate tabs/windows of the same browser.  The &#8220;storage&#8221; event will also only work if the page is served over HTTP (i.e. the file:// protocol will not work).</p><pre style="text-align: justify">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;Web Storage Example&lt;/title&gt;
  &lt;meta charset="UTF-8" /&gt;
  &lt;script&gt;
    "use strict";
    window.addEventListener("load", function(event) {
      var key = document.getElementById("key");
      var value = document.getElementById("value");
      var add = document.getElementById("add");
      var remove = document.getElementById("remove");
      var clear = document.getElementById("clear");
      var content = document.getElementById("content");
      add.addEventListener("click", function(event) {
        if (key.value !== "") {
          try {
            localStorage.setItem(key.value, value.value);
          } catch (e) {
            alert("Exceeded Storage Quota!");
          }
          refreshContents();
        }
      });
      remove.addEventListener("click", function(event) {
        if (key.value !== "") {
          localStorage.removeItem(key.value);
          refreshContents();
        }
      });
      clear.addEventListener("click", function(event) {
        localStorage.clear();
        refreshContents();
      });
      window.addEventListener("storage", function(event) {
        var k = event.key;
        var newValue = event.newValue;
        var oldValue = event.oldValue;
        var url = event.url;
        var storageArea = event.storageArea;
        alert("EVENT:\n" + k + "\n" + newValue + "\n" + oldValue + "\n" + url + "\n" + storageArea);
        refreshContents();
      });
      function refreshContents() {
        var str = "";
        for (var i = 0, len = localStorage.length; i &lt; len; i++) {
          var k = localStorage.key(i);
          var v = localStorage.getItem(k);
          str += "'" + k + "' = '" + v + "'&lt;br /&gt;";
        }
        key.value = "";
        value.value = "";
        content.innerHTML = str;
      }
      refreshContents();
    });
  &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
  Key:  &lt;input type="text" id="key" /&gt;&lt;br /&gt;
  Value: &lt;input type="text" id="value" /&gt;&lt;br /&gt;
  &lt;input type="button" id="add" value="Add to Storage" /&gt;&amp;nbsp;
  &lt;input type="button" id="remove" value="Remove from Storage" /&gt;&amp;nbsp;
  &lt;input type="button" id="clear" value="Clear Storage" /&gt;&lt;br /&gt;
  Contents of Local Storage:&lt;br /&gt;
  &lt;span id="content"&gt;&lt;/span&gt;
&lt;/body&gt;
&lt;/html&gt;</pre><h1 style="text-align: justify">Things to Remember</h1><ul><li>Local storage persists until it is explicitly deleted or the browser&#8217;s cache is cleared.</li><li>Session storage persists until it is explicitly deleted or the browsing context is closed.</li><li>Data stored by one browser is not accessible by another browser.  For example, data stored by Chrome is not seen by Firefox.</li><li>Objects should be stored as JSON strings.</li><li>For security reasons, sensitive data should not be stored, especially in local storage.</li><li>Changes to a storage area cause a &#8220;storage&#8221; event to be fired.</li><li>As with many other HTML5 features, web storage is not yet implemented consistently.</li></ul><p><small><a
href="http://www.shutterstock.com/cat.mhtml?lang=en&#038;search_source=search_form&#038;version=llv1&#038;anyorall=all&#038;safesearch=1&#038;searchterm=storage&#038;search_group=#id=59314054&#038;src=e0f1864e9ad3dfdce4483f891a30273f-1-0">Storage</a> image via Shutterstock</small></p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=6YgqxQxVO1U:zAJuAcBPIDA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=6YgqxQxVO1U:zAJuAcBPIDA:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=6YgqxQxVO1U:zAJuAcBPIDA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=6YgqxQxVO1U:zAJuAcBPIDA:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/6YgqxQxVO1U" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/an-overview-of-the-web-storage-api/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://www.sitepoint.com/an-overview-of-the-web-storage-api/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=an-overview-of-the-web-storage-api</feedburner:origLink></item> <item><title>Ubuntu 12.04 LTS Precise Pangolin: Networking tips and tricks</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/t7q0amNT1IQ/</link> <comments>http://www.sitepoint.com/ubuntu-12-04-lts-precise-pangolin-networking-tips-and-tricks/#comments</comments> <pubDate>Mon, 14 May 2012 15:00:50 +0000</pubDate> <dc:creator>Jonathan Hobson</dc:creator> <category><![CDATA[Web Tech]]></category> <category><![CDATA[WebOS]]></category> <category><![CDATA[Ubuntu]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54343</guid> <description><![CDATA[<img
width="50" height="39" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/04/ubuntu-50x39.png" class="attachment-thumbnail wp-post-image" alt="ubuntu" title="ubuntu" />Networking is often regarded to be complicated and very difficult to manage but as it forms an essential role in the day-to-day use of your computer the purpose of this article is to expose a few &#8216;tips and tricks&#8217; that will serve to improve your computers connectivity and overall performance by showing you how easy [...]]]></description> <content:encoded><![CDATA[<img
width="50" height="39" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/04/ubuntu-50x39.png" class="attachment-thumbnail wp-post-image" alt="ubuntu" title="ubuntu" /><p></p><p>Networking is often regarded to be complicated and very difficult to manage but as it forms an essential role in the day-to-day use of your computer the purpose of this article is to expose a few &#8216;tips and tricks&#8217; that will serve to improve your computers connectivity and overall performance by showing you how easy it is to take control of Ubuntu 12.04, LTS Precise Pangolin.</p><p>So let&#8217;s get started &#8230;</p><h2>What is my local IP address</h2><p>It may be a easy question to begin with, but in a world of complexity it is often the simple questions that get overlooked.</p><h3>Using the graphical tools:</h3><p>Right click on the &#8216;networking icon&#8217; in the top panel of the Ubuntu desktop and choose &#8216;Connection Information&#8217; as shown below:</p><p><a
href="http://www.sitepoint.com/?attachment_id=54344" rel="attachment wp-att-54344" class="broken_link"><img
class="alignnone size-full wp-image-54344" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/u1.jpg" alt="" width="500" height="486" /></a></p><p>The resulting dialogue box will then provide feedback on your current settings.</p><h3>Using the command line interface:</h3><p>On the other hand, for those individuals who are beginning to enjoy the power of Terminal or for those of you who use a server (via the Console or Putty or similar).<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>If you have a wireless based connection, run:</p><pre>iwconfig</pre><p>If you have a &#8216;wired&#8217; connection, run</p><pre>ifconfig</pre><p>The results for &#8216;ifconfig&#8217; will look something like this:</p><pre>eth0      Link encap:Ethernet  HWaddr 00:1d:92:65:09:e1
          inet addr:192.168.1.100  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::21d:92ff:fe65:9e1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:510 errors:0 dropped:0 overruns:0 frame:0
          TX packets:315 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:80353 (80.3 KB)  TX bytes:38731 (38.7 KB)
          Interrupt:42 Base address:0xa000
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:108 errors:0 dropped:0 overruns:0 frame:0
          TX packets:108 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:8176 (8.1 KB)  TX bytes:8176 (8.1 KB)</pre><p>And because the command line provides us with additional opportunities, if you would like to quickly identify all the available ethernet devices on your computer, you can run</p><pre>ifconfig -a | grep eth</pre><p>The result will look something like this:</p><pre>eth0      Link encap:Ethernet  HWaddr 00:1d:92:65:09:e1</pre><p>Well done, but just before we finish-up I would like to take this opportunity to show you another useful command that can help identify all the network interfaces available to your system. Known as the &#8216;lshw&#8217; command, this tool will not only detail your ethernet devices but it will also provide a plethora of information on your hardware&#8217;s &#8216;other&#8217; capabilities.</p><p>To use this tool, simply run the following command and wait a few seconds whilst Ubuntu quieries your devices:</p><pre>sudo lshw -class network</pre><p>And the result will look something like this:</p><pre>  *-network
       description: Ethernet interface
       product: RTL8111/8168B PCI Express Gigabit Ethernet controller
       vendor: Realtek Semiconductor Co., Ltd.
       physical id: 0
       bus info: pci@0000:02:00.0
       logical name: eth0
       version: 01
       serial: 00:1d:92:65:09:e1
       size: 100Mbit/s
       capacity: 1Gbit/s
       width: 64 bits
       clock: 33MHz
       capabilities: pm vpd msi pciexpress bus_master cap_list rom ethernet physical tp mii 10bt 10bt-fd 100bt 100bt-fd 1000bt 1000bt-fd autonegotiation
       configuration: autonegotiation=on broadcast=yes driver=r8169 driverversion=2.3LK-NAPI duplex=full firmware=N/A ip=192.168.1.160 latency=0 link=yes multicast=yes port=MII speed=100Mbit/s
       resources: irq:43 ioport:d800(size=256) memory:feaff000-feafffff memory:feac0000-feadffff</pre><p>Sometimes you&#8217;ve just &#8216;gotta&#8217; love the details, but now we know something about our computer we can begin to take control :-)</p><h2>How do I create a static IP address with the Network Manager</h2><p>The following instruction shows you how to create a fixed (or static) IP address with the Network Manager.</p><p>This approach is best suited to all desktop users who may require the need to keep the functionality of the Network Manager or for those that use netbooks, laptops and and other wireless connections that may require a DHCP based option in the future. Don&#8217;t worry, it is all very simple:</p><p>Click the network menu on the top panel (the &#8216;up/down&#8217; arrows icon) and select &#8216;Edit Connections&#8217;.</p><p>Alternatively you can choose System Settings &gt; Network &gt; Choose your &#8216;Network Connection&#8217; from the left hand panel and select &#8216;Options&#8217;.</p><p><a
href="http://www.sitepoint.com/?attachment_id=54345" rel="attachment wp-att-54345" class="broken_link"><img
class="alignnone size-full wp-image-54345" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/u2.jpg" alt="" width="500" height="400" /></a></p><p>Now choose the relevant connection and click edit.</p><p>For example, if you are using a &#8216;wired connection&#8217;, choose the &#8216;wired&#8217; tab to find your connection.</p><p><a
href="http://www.sitepoint.com/?attachment_id=54346" rel="attachment wp-att-54346" class="broken_link"><img
class="alignnone size-full wp-image-54346" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/u3.jpg" alt="" width="500" height="583" /></a></p><p>In the resulting dialogue box you should:</p><ul><li>Select the &#8216;IPv4 Settings&#8217; tab and change the &#8216;Method&#8217; to &#8216;Manual&#8217;.</li><li>Click Add and complete each field with your IP address, network mask and default gateway.Always press the &#8216;Enter/Return&#8217; when you&#8217;ve finished typing each address otherwise the dialogue will fail to accept your new settings and the &#8216;save&#8217; button will remain inactive/greyed-out.</li><li>Include the IP addresses of the DNS servers. Multiple addresses should be separated by commas.</li><li>Click Save and close the remaining dialogue boxes.</li></ul><p>And there you go &#8230;</p><p>If all is well you should be able to view web sites and/or view your local network but in some situations and depending on your network topology a reboot may be necessary.</p><p>To confirm your new settings, simply check your connection settings as shown previously (see above)</p><p><strong>But what if I need DHCP again?</strong><br
/> If you ever need to return to a dynamically assigned IP address simply re-run the previous steps. Find your current connection, select the &#8216;IPv4 Settings&#8217; tab and change the &#8216;Method&#8217; to &#8216;Automatic (DHCP)&#8217;. To finalise this reversal click save and reboot (depending on the network conditions and how the DHCP server is configured).</p><h2>Disable the Network Manager and &#8216;hard-code&#8217; a static IP address</h2><p>This solution explains how to create a fixed (or static) IP address without using the Network Manager.</p><p>The Network Manager is a very nice feature, but only suitable for individuals who require dynamically assigned connections or those who require wireless connectivity. Yes, it is true to say that these are both very popular in homes and offices throught the world but for those of us who use and prefer the benefit of a &#8216;wired connection&#8217; using the Network Manager does come at the cost of performance. So this solution uses the traditional approach to &#8216;hard-coding&#8217; your network connection and it is most suitable to those individuals who demand maximum performance or absolute stability.</p><blockquote><p>By using this approach you should note that we will not be removing the Network Manager, merely disabling it with the intention to capitalise on the performance gains by by-passing or side-stepping this device. These performance gains will not only be noticed in terms of network speed but also in terms of the computer in general.</p></blockquote><p>Again, don&#8217;t worry, the process to disable the Network Manager is very simple but it will require us to run various &#8216;commands&#8217; in Terminal in order to complete some steps.</p><p>So let&#8217;s begin by making a backup of our original file.</p><p>In Terminal type:</p><pre>sudo cp /etc/NetworkManager/NetworkManager.conf /etc/NetworkManager/NetworkManager.conf.bak</pre><blockquote><p>This will serve to back-up our original file to &#8216;/etc/NetworkManager/NetworkManager.conf.bak&#8217;. Hopefully you will not need it, but if you ever need to restore the original file simply open Terminal and reverse the command like so: &#8216;sudo cp /etc/NetworkManager/NetworkManager.conf.bak /etc/NetworkManager/NetworkManager.conf&#8217; and reboot.</p></blockquote><p>And with the confidence that we are fully backed-up we shall now proceed to disable the Network Manager.</p><p>In Terminal, type:</p><pre>sudo gedit /etc/NetworkManager/NetworkManager.conf</pre><p>This will open the &#8216;NetworkManager.conf&#8217; file in our text editor.</p><p>Now change:</p><p>managed=false</p><p>to</p><p>managed=true</p><p>So it looks like this:</p><p><a
href="http://www.sitepoint.com/?attachment_id=54347" rel="attachment wp-att-54347" class="broken_link"><img
class="alignnone size-full wp-image-54347" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/u4.jpg" alt="" width="500" height="409" /></a></p><p>When done, save the file and close it.</p><blockquote><p>You can re-enable the network manager at any time by simply reversing the steps shown above or by restoring your back-up file. Remember to reboot in order to apply these changes.</p></blockquote><p>Now we have successfully disabled the Network Manager we can proceed to create our Static IP address by making some direct changes to the &#8216;interface&#8217; file; but with safety in mind let&#8217;s begin by making a backup of our original file.</p><p>In Terminal and type:</p><pre>sudo cp /etc/network/interfaces /etc/network/interfaces.bak</pre><blockquote><p>This will back-up our original file to /etc/network/interfaces.bak. Again, it is not expected that we will need it but if you ever need to restore it open Terminal and reverse the command like so: sudo cp /etc/network/interfaces.bak /etc/network/interfaces</p></blockquote><p>Now lets add our static IP address.</p><p>In Terminal type:</p><pre>sudo gedit /etc/network/interfaces</pre><p>Authenticate yourself in the usual way and then replace the file contents as shown below, where xxx represents values relevant to your needs:</p><pre>auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
	address 	xxx.xxx.xxx.xxx
	netmask 	xxx.xxx.xxx.xxx
	network 	xxx.xxx.xxx.xxx
	broadcast 	xxx.xxx.xxx.xxx
	gateway 	xxx.xxx.xxx.xxx</pre><p>And to help you out, here is an example with an explanation of the values concerned:</p><pre>auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
	address 	192.168.1.100 	(this is my computers IP address)
	netmask 	255.255.255.0 	(this is my subnet mask)
	network 	192.168.1.0	(this is my network base address)
	broadcast 	192.168.1.255	(this is my broadcast address)
	gateway 	192.168.1.254	(this is my gateway/router's ip address)</pre><p>When complete, simply save and close the file and reboot your computer to complete these steps.</p><p>We are re-booting our computer at this point in order to &#8216;dis-engage&#8217; the Network Manager, and once complete you can always re-configure your IP address at any time by making the necessary changes to the &#8216;interfaces&#8217; file (shown above) and using the following command to restart your networking service: &#8216;sudo /etc/init.d/networking restart&#8217;.</p><p>After you restart your computer you will discover (visually) that nothing has changed but as a consequence you should be experiencing a &#8216;more&#8217; responsive computer and network connection.</p><blockquote><p>Should you ever want to re-enable the Network Manager. Simply reverse the steps we have taken above and/or restore you back-up files and reboot and as we created them with the &#8216;cp&#8217; or copy command &#8211; unless you delete them, your original backup files will always remain for future reference.</p></blockquote><h2>Create Virtual Network Adapters (add more than 1 IP address to a single ethernet card)</h2><p>In some situations this can be very useful and as an extension to our previous solution of &#8216;disabling the network manager and hard-coding a static IP address&#8217; I will now show you how to assign more than one IP address to the same ethernet card:</p><p>In Terminal type:</p><pre>sudo gedit /etc/network/interfaces</pre><p>Authenticate yourself and then replace the file contents like so, where xxx represents values relevant to your needs:</p><pre>auto lo
iface lo inet loopback
auto eth0
iface eth0 static
	address 	xxx.xxx.xxx.xxx
	netmask 	xxx.xxx.xxx.xxx
	network 	xxx.xxx.xxx.xxx
	broadcast 	xxx.xxx.xxx.xxx
	gateway 	xxx.xxx.xxx.xxx
auto eth0:0
iface eth0:0 static
	address 	xxx.xxx.xxx.xxx
	netmask 	xxx.xxx.xxx.xxx
	gateway 	xxx.xxx.xxx.xxx</pre><p>And to make this as simple as possible, here is an example:</p><pre>auto lo
iface lo inet loopback
auto eth0
iface eth0 static
	address 	192.168.1.100
	netmask 	255.255.255.0
	network 	192.168.1.0
	broadcast 	192.168.1.255
	gateway 	192.168.1.254
auto eth0:0
iface eth0:0 static
	address 	192.168.1.101
	netmask 	255.255.255.0
	gateway 	192.168.1.254</pre><p>By doing this I will be adding two IP addresses to my a single ethernet card. It will not only have the IP address of 192.168.1.100 but it will also have the alternative address of 192.168.1.101 (as a virtual instance).</p><p>The trick is to follow the virtual naming scheme (i.e. eth0:0, eth0:1, eth0:2 etc &#8230;) and to ensure that every instance maintains a unique IP address. In this way you can create as many &#8216;instances&#8217; of an IP address as required.</p><p>To illustrate this point, let&#8217;s add a third IP address to our example:</p><pre>auto lo
iface lo inet loopback
auto eth0
iface eth0 static
	address 	192.168.1.100
	netmask 	255.255.255.0
	network 	192.168.1.0
	broadcast 	192.168.1.255
	gateway 	192.168.1.254
auto eth0:0
iface eth0:0 static
	address 	192.168.1.101
	netmask 	255.255.255.0
	gateway 	192.168.1.254
iface eth0:1 static
	address 	192.168.1.102
	netmask 	255.255.255.0
	gateway 	192.168.1.254</pre><p>When complete, remember to reboot your computer to apply the changes or open Terminal and type:</p><pre>sudo /etc/init.d/networking restart</pre><p>You can then run &#8216;ifconfig&#8217; to view your new settings.</p><p>Have fun ..!</p><h2>Change your computer&#8217;s hostname</h2><p>You may like your current computer name, or you may want to change it.</p><p>In this short recipe I will show you how to view and change your computer name with relative ease &#8230;</p><p>In Terminal type:</p><pre>sudo gedit /etc/hostname</pre><p>The file will probably look something like this:</p><pre>ubuntu-computername</pre><p>To change the name of your computer, simply delete the existing content and replace as required.</p><p>Remember, the actual name can be anything your want as long as you remember some basic principles:</p><ul><li>Desktops generally use a singular name (as shown above) whereas all servers or &#8216;desktops acting as servers&#8217; should be in the format of computername.computerdomain.suffix.</li><li>On a local network computers should refrain from using the standard or typical internet based suffix or TLD unless your local DNS can account for such similarities.</li><li>Use &#8216;internet friendly&#8217; names and do not use a computer name that already exists on your network.</li><li>Do not use spaces or non-internet friendly characters.</li></ul><p>Once complete, simply choose &#8216;save&#8217;, &#8216;close&#8217; the file and reboot your computer to see the changes.</p><p>Your new computer name will be in the top-left hand side of the login screen but if you missed this or need to confirm your current or new hostname at any time.</p><p>Open Terminal and type:</p><pre>sudo hostname</pre><p>And the result should reflect the changes you made &#8230;</p><h2>Managing the Hosts file</h2><p>The hosts file file consists of a list of IP addresses and corresponding hostnames. Most users may never need to touch this area of their computer but there maybe an occasion when you need to edit the hosts file on your machine. This can because of any number of reasons (i.e. reversing the effect of malicious activity) or it can be because your are trying to make your life that little &#8216;quicker&#8217; buy &#8216;hard-coding&#8217; the address of an internal or external web site. Similarly, if your network contains computers whose IP addresses that are not listed in an existing DNS record, then it is recommended that you add them to the hosts file. So with this in mind I will now show you how to manage you hosts file.</p><p>Before you begin, you can make a back-up of this file by simply typing the following command in to Terminal:</p><pre>sudo cp /etc/hosts /etc/hosts.bak</pre><p>Now, to proceed and customise your hosts file simply return to the command line and type:</p><pre>sudo gedit /etc/hosts</pre><p>A typical desktop file will look like this (simply substitue the example values with those relevant to your computer):</p><pre>127.0.0.1			localhost
127.0.1.1			ubuntu-computername
# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters</pre><p>However, having said that and just for the record, for the &#8216;server&#8217; or &#8216;desktop server&#8217; version of the same file should look more like this:</p><pre>127.0.0.1       localhost.localdomain   localhost
192.168.1.100 	ubuntu-computername.ubuntu-domainname.lan  ubuntu-computername
# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters</pre><p>You will notice that my examples include the IPv6 instruction and this is entirely at your discretion as it depends on whether your network supports it.</p><p>For example, you may ignore these values (not include them or comment them out by placing a &#8216;hash&#8217; character at the beginning of the line) like so if your computer does not use IPv6.</p><pre># The following lines are desirable for IPv6 capable hosts
#::1     ip6-localhost ip6-loopback
#fe00::0 ip6-localnet
#ff00::0 ip6-mcastprefix
#ff02::1 ip6-allnodes
#ff02::2 ip6-allrouters</pre><p>Of course, disabling IPv6 is optional and can sometimes improve performance but if you are in doubt, simply ignore them (but as they sometimes say in &#8216;old blighty&#8217; &#8211; &#8216;don&#8217;t fix what ain&#8217;t broke&#8217;).</p><p>So getting back on track &#8230;</p><p>In your hosts file you may want to include a list or pre-identified servers and workstations in order to speed-up name resolution like so:</p><pre>192.168.1.200		servername1 www servername1.localdomain.lan
192.168.1.200		servername2 mail servername2.localdomain.lan</pre><blockquote><p>In my example I have included an alias in addition to the actual names &#8211; i.e. servername1 is also known as www and servername2 is also known as mail. You do not need to do this as my other examples will show.</p></blockquote><p>Windows (and Mac) users should notice that this process very similar to customisng the &#8216;hosts&#8217; file on any Windows/Mac based operating system and the resulting file could look like this:</p><pre>127.0.0.1			localhost
127.0.1.1			ubuntu-computername
# PUT YOU COMMENT AFTER A HASH (#) FOR REFERENCE - NOT REQUIRED BUT USEFUL
192.168.1.200		www.website1.com
192.168.1.201		www.website2.com
# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters</pre><p>Consequently, my computer will now use the IP address for www.website1.com instead of searching a DNS record thereby ensuring that my ability to view the website in question would be quicker than before.</p><p>Taking this one step further &#8230; and by giving it a little twist.</p><p>For those of you who wish to excercise some &#8216;parental power&#8217; you could easily use this as a way to block direct access to some &#8216;unwanted web sites&#8217; by sending someone who expects to go to www.website1.com to www.website2.com, like so:</p><pre>#192.168.1.200	www.website1.com
192.168.1.201		www.website1.com
192.168.1.201		www.website2.com
192.168.1.202		www.website3.com
192.168.1.123		www.website4.com
192.168.1.167		www.website5.com</pre><p>Notice I have commented out the real address of website1 with a hash (#) and that both website1 and website 2 now have the same IP address &#8230; (the IP address being the actual address of website2)</p><p>It isn&#8217;t a perfect of solution by any means but it is food for thought and can serve as a starting point for future development ;-)</p><h2>How to re-configure DNS resolution</h2><p>The purpose of this section is to show you how to configure the appropriate nameserver to use when resolving IP address to hostnames and vice versa. It is not intended to explain how to configure the system as a name server as this is something I will be covering in a future article. You should only affect this file if you are not using the Network Manager and want to use a static IP address.</p><blockquote><p>The resolv.conf file is the resolver configuration file and it is used to configure workstation or server access to the Internet Domain Name System (DNS). This file defines which nameservers to use and in what order they are tried. You should therefore put the most reliable server first. It is convention that up to three name servers are supported. However, if no nameserver option is given, the resolver will attempt to connect to the name server on the local host.</p></blockquote><p>Resolv.conf still does this, but with the release of the Precise Pangolin a few things have changed, and regardless as to whether you are running a desktop or a server your system is probably running the resolveconf program:</p><p>&#8216;Resolveconf&#8217; is a small program that resides in &#8216;/etc/resolvconf&#8217; that dynamically modifies the nameserver information on boot. It is a useful tool, but for our purposes it can be disruptive, so we are going to work around it by simply adding a new entry to our &#8216;/etc/network/interfaces&#8217; file:</p><p>In Terminal type:</p><pre>sudo gedit /etc/network/interfaces</pre><p>Now add the following nameserver line to your file, changing XXX to something more applicable to your needs:</p><pre>dns-nameservers xxx.xxx.xxx.xxx xxx.xxx.xxx.xxx</pre><p>Similar to the example shown above here is the new file using Google&#8217;s public nameservers:</p><pre>auto lo
iface lo inet loopback
auto eth0
iface eth0 static
	address 	192.168.1.100
	netmask 	255.255.255.0
	network 	192.168.1.0
	broadcast 	192.168.1.255
	gateway 	192.168.1.254
        dns-nameservers 8.8.8.8 8.8.4.4</pre><p>When complete, click &#8216;save&#8217;, then &#8216;close&#8217; the file and reboot to apply the changes.</p><p>On reboot, you can see that the new nameserver information has now been applied to our &#8216;resolve.conf&#8217; file by opening Terminal and typing:</p><pre>cat /etc/resolv.conf</pre><p>Which may look something like this:</p><pre># Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 8.8.8.8
nameserver 8.8.4.4
nameserver 127.0.0.1</pre><p>So having made your changes, to query the DNS capabilities of your system, simply return to the command line and type:</p><pre>nslookup www.sitepoint.com</pre><p>or alternatively try</p><pre>dig www.sitepoint.com</pre><p>And that&#8217;s it for now &#8230; but most of all, have fun :-)</p><p>So until next time &#8230;</p><p>I hope that you continue to enjoy using Ubuntu 12.04 LTS Precise Pangolin.</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=t7q0amNT1IQ:ONfIBC2ZYWo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=t7q0amNT1IQ:ONfIBC2ZYWo:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=t7q0amNT1IQ:ONfIBC2ZYWo:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=t7q0amNT1IQ:ONfIBC2ZYWo:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/t7q0amNT1IQ" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/ubuntu-12-04-lts-precise-pangolin-networking-tips-and-tricks/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://www.sitepoint.com/ubuntu-12-04-lts-precise-pangolin-networking-tips-and-tricks/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=ubuntu-12-04-lts-precise-pangolin-networking-tips-and-tricks</feedburner:origLink></item> <item><title>Get Hired</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/LuoEhAAKKOg/</link> <comments>http://www.sitepoint.com/get-hired/#comments</comments> <pubDate>Sun, 13 May 2012 23:00:27 +0000</pubDate> <dc:creator>John Tabita</dc:creator> <category><![CDATA[Business]]></category> <category><![CDATA[Find Clients]]></category> <category><![CDATA[Sell Your Services]]></category> <category><![CDATA[Selling Web Design Services]]></category> <category><![CDATA[Web Pro Business]]></category> <category><![CDATA[clients]]></category> <category><![CDATA[Marketing]]></category> <category><![CDATA[sales]]></category> <category><![CDATA[selling]]></category> <category><![CDATA[selling your services]]></category> <category><![CDATA[small business]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54612</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/handshake-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="handshake" title="handshake" />In this article, John Tabita give you some simple tips to increase your chances of getting hired.]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/handshake-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="handshake" title="handshake" /><p></p><p>In my series on <a
title="Putting a Stop to Abusive Clients" href="http://www.johntabita.com/abusive-clients/" target="_blank">Putting a Stop to Abusive Clients</a>, I&#8217;ve talked a lot from the seller’s perspective. But before I put the final wraps on the series, I’m going to take a slight detour to discuss things from the buyer’s side of the fence. Let&#8217;s talk about how to get hired.</p><p>Over the past few days, I’ve had to post two different job opportunities; one for a full-time sales rep, and the other for some contract web work. The responses I’ve gotten have been interesting, to say the least.</p><p>One of the things I deliberately do is include both an email and my direct phone number as contact points. Which you chose may very well mean the difference between getting hired and getting ignored.</p><p>Within minutes of posting the ad for the contract position, I received a phone call. Shortly afterwards, I received a second call from another firm. Both took the time to find out my objectives and what I’m trying to accomplish before talking up their firm.</p><p>The rest sent an email with some variation of “check out my website“ and “call me back.”<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>Who do you suppose I’m considering?</p><h2>Hiding behind Web 2.0</h2><p>Recently, my son’s scoutmaster left a voice mail message about an upcoming Eagle ceremony for one of the other boys in his troop, and that his attendance was “mandatory.” The only problem was, all he gave us was the name of the church where the ceremony was being held … no address, no city, nada.</p><p>After a Google search turned up just one church with that name several cities over, I asked my son to confirm if this was indeed the right church. So on the day of the ceremony, he made phone calls and left voice mail messages, trying to find out. No one, not the scoutmaster, his patrol leader nor any of the other boys in his troop responded. Finally, out of desperation, he posted the question on Facebook.</p><p>Within 15 minutes, three boys replied. I fear this does not bode well for the future of our youth.</p><p>Too often, we use Web 2.0 tools to avoid direct interaction. For instance, it’s easy to <a
title="Are You Hiding behind Marketing to Avoid Selling?" href="http://www.johntabita.com/hiding-marketing-avoid-selling/" target="_blank">hide behind marketing to avoid selling</a>. Don’t fall into that trap. When I give you the choice, pick up the phone and call me.</p><p>Why would I say that? Two reasons. One: I’m really, really busy. When you call me, you get first-mover advantage, because you’ve taken a task off my all-too-busy plate—the need to follow up on all the emails responses I received. I really don’t have time to “check out your website,” and then “give you a call.” Besides, your website probably contains the same generic fluff as everyone else’s. How about you demonstrate why you’re different and why I ought to hire you? You can do that by picking up the phone and having an actual conversation with me.</p><p>Reason Number Two is: it shows me you have initiative as well as people skills. You see, if I really have a need, I’m going to want to talk with you to determine if you are someone who can fill that need. If I’m the one hiding behind web 2.0 tools, asking you to communicate with me via email or Facebook, I may not be a genuine prospect at all. I might be someone who’s merely “interested,” or not far enough along in <a
title="What’s a Buying Cycle and Why Should I Care?" href="http://www.sitepoint.com/what%e2%80%99s-a-buying-cycle-and-why-should-i-care/" target="_blank">the buying cycle</a> to waste valuable time with. But if I’ve offered my phone number, than means I’d like to speak with a living, breathing person. That person could be you.</p><p>Here’s another tip: When I ask you to follow up if you haven’t heard back from me by such-and-such date, that might be a test. Calling me back shows me you want the gig.</p><p>What I didn’t mention is that there <em>was</em> a third firm that called; but he got the short straw—my voice mail—and never called back. If you have a genuine lead, keep pursuing it, even if they aren’t returning your calls. If you saw my desk, you’d know why I didn’t call you back.</p><p
style="text-align: right"><em><a
href="http://www.sxc.hu/profile/mikecco" target="_blank">Image credit</a></em></p><div
style="border-width: 1px;border-style: solid;border-color: #d5d5d5;padding: 8px;margin-top: 30px;margin-bottom: 30px;background: #e8e8e8">It’s not too late to get my free guide, <strong>27.5 Must-Ask Questions for Consultative Selling</strong>. Just <a
title="Twitter | @johntabita" href="http://twitter.com/johntabita" target="_blank">follow me on Twitter</a> and I’ll send you a link.</div> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=LuoEhAAKKOg:XGRrOKfevG0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=LuoEhAAKKOg:XGRrOKfevG0:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=LuoEhAAKKOg:XGRrOKfevG0:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=LuoEhAAKKOg:XGRrOKfevG0:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/LuoEhAAKKOg" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/get-hired/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://www.sitepoint.com/get-hired/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=get-hired</feedburner:origLink></item> <item><title>What do you need to know about HTML5 video</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/KB27UCF00rE/</link> <comments>http://www.sitepoint.com/what-do-you-need-to-know-about-html5-video/#comments</comments> <pubDate>Sat, 12 May 2012 15:00:55 +0000</pubDate> <dc:creator>Elena Vakhromova</dc:creator> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=51903</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/02/HTML5_video-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="HTML5_video" title="HTML5_video" />HTML5 keeps on stunning the Internet community with revolutionary web features. One of the key HTML5 enhancements is the advanced video support. In this post, I'd like to take a deeper look at HTML5 video element and explain its main points in plain English.]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/02/HTML5_video-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="HTML5_video" title="HTML5_video" /><p></p><p>HTML5 keeps on stunning the Internet community with revolutionary web features. One of the key HTML5 enhancements is the advanced video support. With a new HTML5 standard, users don&#8217;t need any special plugins to stream video in web browsers both on PC or any portable device. Still in spite of the growing popularity of HTML5 standard, most web developers and designers are reluctant to migrate to the new markup language, maybe because of the absence of a complete HTML5 specification or lack of practical information on HTML5 сoding. In this post, I&#8217;d like to take a deeper look at HTML5 video element and explain its main points in plain English.</p><h2>&lt;video&gt; tag vs. &lt;object&gt; tag</h2><p>The <code>&lt;object&gt;</code> tag referrs to an embedded element within a web page: audio, video, Java applet, ActiveX, PDF, or Flash. The markup for this tag is fairly cryptic. Thus, if you wanted to embed a Flash video into a web page, you had to insert the following code:</p><pre>&lt;object id=0 type="application/x-shockwave-flash" data=player_flv_maxi.swf width=420 height=240
&lt;param name="movie" value=player_flv_maxi.swf /&gt;
&lt;param name="wmode" value="opaque" /&gt;
&lt;param name="allowFullScreen" value="true" /&gt;
&lt;param name="allowScriptAccess" value="sameDomain" /&gt;
&lt;param name="quality" value="high" /&gt;
&lt;param name="menu" value="true" /&gt;
&lt;param name="autoplay" value="false" /&gt;
&lt;param name="autoload" value="false" /&gt;
&lt;param name="FlashVars" value="flv=Wildlife.flv&#038;width=420&#038;height=240&#038;autoplay=0&#038;autoload=0&#038;buffer=5&#038;buffermessage=&#038;playercolor=464646&#038;loadingcolor=999898&#038;buttoncolor=ffffff&#038;buttonovercolor=dddcdc&#038;slidercolor=ffffff&#038;sliderovercolor=dddcdc&#038;showvolume=1&#038;showfullscreen=1&#038;playeralpha=100&#038;title=Wildlife.flv&#038;margin=0&#038;buffershowbg=0" /&gt;
</pre><p>To play this, users can&#8217;t do without a Flash player plugin which is ndispensable for all modern browsers except Google Chrome since the player is already pre-installed in the browser.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>HTML5 introduces the new &lt;video&gt; tag which replaces the former &lt;object&gt; tag for Flash video embedment. The benefits of using HTML5 &lt;video&gt; tag are numerous. It brings not only minimalism and simplicity of video code, but also the ease of search bots to properly index your video file. Website developers can add a video to a page in the same way they would add an image, since the basic markup necessary for &lt;/video&gt;&lt;video&gt; in HTML5 is refreshingly simple and straightforward:</p><pre>&lt;/video&gt;&lt;video width="320" height="240" controls autoplay poster="video.jpg"&gt;
 &lt;source src="movie.mp4" type="video/mp4" /&gt;
 &lt;source src="movie.ogg" type="video/ogg" /&gt;
 Your browser does not support the video tag.
&lt;/video&gt;</pre><p>Such code can be easily composed even by a not tech-savvy specialist. In the simplest way the code may be reduced to:<code>&lt;video src="movie.mp4" controls width="320" height="480"&gt;&lt;/video&gt;</code></p><h2>Video Attributes</h2><p>As you can see, the &lt;video&gt; tag is used just like any other tags in HTML. Between opening and closing tags you can place various attributes to get the video player you want.</p><p>Several of the attributes are boolean (e.g. controls, loop, muted) &#8211; no value is required. So by including or omitting them, you set the value &#8220;true&#8221; or &#8220;false&#8221; respectively.</p><p>HTML5 specialists also recommend inserting the following line within video tag:<br
/> Video not playing? <code>&lt;a href="pics/video.mp4"&gt;</code><code>Download the file</code><code></code> instead.</p><h2>Controls</h2><p>The browsers supporting HTML5 video have the video players already built-in. All of them include a standard set of controls: Play, Pause, Seek, Volume. However, each browser provides its own look for the video player: from the minimal approach of Chrome and IE to the more elaborate controls of Firefox, Opera and Safari.</p><p>If you want to keep controls the same across all browsers, or integrate the player with our website design, you can create our own controls from scratch. Here are some useful resources:</p><li><a
href="http://videojs.com/">VideoJS</a> is an HTML5 video player built with Javascript and CSS;</li><li><a
href="http://sublimevideo.net/">Sublime Video</a> is a sleek cloud-based HTML5 video player with advanced feature set, a paidware;</li><li><a
href="http://www.projekktor.com/index.php">Projekktor</a> is an open source HTML5 video player built with pure JavaScript; it also uses Flash when there is no native H.264 support;</li><li><a
href="http://dev.opera.com/articles/view/custom-html5-video-player-with-css3-and-jquery/">Tutorial</a> “How to build a custom HTML5 video player with jQuery and CSS3” from Opera developers.</li><h2>Video source</h2><p>The &lt;video&gt; tag allows multiple &lt;source&gt; elements which can link to one and the same video in different formats, for example:</p><pre>       &lt;source src='movie.webm' type='video/webm; codecs="vp8.0, vorbis"'/&gt;
       &lt;source src='movie.ogv' type='video/ogg; codecs="theora, vorbis"'/&gt;
       &lt;source src='movie.mp4' type='video/mp4; codecs="avc1.4D401E, mp4a.40.2"'/&gt;</pre><p>As you see, the source tag has two attributes, src and type. The &#8220;type&#8221; attribute specifies the MIME type and possibly a list of codecs, which helps the browser to determine whether it can decode the file. By default, the browser will use the first recognized format. All modern browsers support at least one HTML5 video format.</p><h2>Browser Support</h2><p>For up to date information on browser support, you can check out the <a
href="http://www.youtube.com/html5">YouTube HTML5 Page</a></p><h2>Codecs</h2><p>There&#8217;s a long debate on which video formats/codecs to pursue and consensus hasn&#8217;t been reached yet. As a result, in the draft of HTML5 specification any references to a particular codec were removed. Instead, the following creteria to the video codec were put forward:</p><li>it should have good compression, good image quality, and low decode processor use;</li><li>be royalty-free;</li><li>feature hardware video decoder</li><p>Three codecs were suggested for HTML5 video element: H.264, OGG Theora, and WebM VP8. Here are their advantages and disadvantages.</p><h2>H.264</h2><p><strong>Pros</strong><br
/> It gives good quality video and small file sizes. It outputs excellent video both for low-bandwidth, low-CPU mobile devices and high-bandwidth, high-CPU modern PCs and everything in between. It&#8217;s free for Internet end-users.</p><p><strong>Cons</strong><br
/> The underlying compression mechanisms in H.264 are patented and adopters have to pay royalties for commercial use to a licensing consortium called MPEG-LA.</p><h2>OGG Theora</h2><p><strong>Pros</strong><br
/> It&#8217;s a royalty-free codec and is not encumbered by any known patents other than the original VP3 patents, which have been licensed royalty-free.</p><p><strong>Cons</strong><br
/> Theora generates high quality videos with comparatively larger file sizes. Plus it is a lot harder to find tools to convert to OGG Theora.</p><h2>WebM VP8</h2><p><strong>Pros</strong><br
/> In 2010, Google acquired On2 – the company behind VP8, and published the video codec specification as open source, and all the patents as royalty-free.</p><p><strong>Cons</strong></p><p>While Google claims that WebM has the highest video quality of all the web codecs, most independent sources find that either H.264 is slightly better or there is very little difference between the two. The problem is that it can be very difficult to find tools to encode video to WebM.</p><p>Until a complete consensus on video codecs issue is reached, web developers have to convert video to all these three formats. There&#8217;s some helpful software which deal with HTML5 video preparing:</p><li>Free Video Converter 3.0 by Freemake.com is a Windows software that encodes both desktop and online video to H.264, WebM and Theora OGG, the resulted videos go together with a sample of HTML5 video embedding;</li><li>alternatively, you can receive HTML5 source files as a result of video conversion with the help of the video tools listed here.</li><p>Some webmasters also combine HTML5 &lt;video&ht; element with Flash-based code, so that a video could be played in any browser, including old IE versions.</p><p>No doubt, HTML5 video still has a lot of benefits if compared to Flash. However, it&#8217;s still debatable whether H.264, WebM and Theora OGG will remain the default video formats supported in the video element. And since the specification of HTML5 video formats depends a lot on the decisions of Apple, Microsoft and Google corporations, the future of  the whole new standard seems vague but still promising.</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=KB27UCF00rE:NYZYQG8s3b8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=KB27UCF00rE:NYZYQG8s3b8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=KB27UCF00rE:NYZYQG8s3b8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=KB27UCF00rE:NYZYQG8s3b8:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/KB27UCF00rE" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/what-do-you-need-to-know-about-html5-video/feed/</wfw:commentRss> <slash:comments>3</slash:comments> <feedburner:origLink>http://www.sitepoint.com/what-do-you-need-to-know-about-html5-video/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=what-do-you-need-to-know-about-html5-video</feedburner:origLink></item> <item><title>Celebrate 20 Years of Wolfenstein 3D in Your Browser</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/88-8YdK3EX8/</link> <comments>http://www.sitepoint.com/wolfenstein-3d-html5-browser-game/#comments</comments> <pubDate>Sat, 12 May 2012 15:00:27 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[Gems]]></category> <category><![CDATA[HTML & CSS]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[News & Trends]]></category> <category><![CDATA[Opinion]]></category> <category><![CDATA[Reviews]]></category> <category><![CDATA[canvas]]></category> <category><![CDATA[game]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[HTML5 Tutorials & Articles]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54596</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/673-wolfenstein-browser-50x50.png" class="attachment-thumbnail wp-post-image" alt="673-wolfenstein-browser" title="673-wolfenstein-browser" />Wolfenstein 3D was released 20 years ago. To celebrate the ground-breaking FPS game, you can now play an HTML5 version in your browser.]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/673-wolfenstein-browser-50x50.png" class="attachment-thumbnail wp-post-image" alt="673-wolfenstein-browser" title="673-wolfenstein-browser" /><p></p><p>Perhaps I&#8217;m showing my age but is it really 20 years since Wolfenstein 3D exploded onto the PC gaming scene? To celebrate that momentous occasion, the full game can now be played online within your browser at:</p><p><a
href="http://wolfenstein.bethsoft.com/"><strong>wolfenstein.bethsoft.com</strong><br
/> <img
src="http://blogs.sitepointstatic.com/images/tech/673-wolfenstein-browser-screen.png" width="500" height="320" alt="Wolfenstein 3D browser version" class="center" style="margin: 5px auto 20px auto" /></a></p><p><em>(Note the game is recommended for those over 12 and banned in Germany and several other countries).</em></p><p>The site states it&#8217;s compatible with IE9, Firefox, Chrome and Safari &#8212; although Opera seems to work if you&#8217;re not too bothered by a few graphical glitches. The game is mouse-enabled (set it within the configuration options) although few PCs had mice in 1992 and you&#8217;ll find keyboard control best.</p><p>Wolfenstein was released as DOS shareware in 1992. The web was largely unknown and bulletin boards were the reserve of rich geeks but, despite a lack of social networks and online file sharing, word spread and so did thousands of 720kB floppy disks. Suddenly, there was a reason to use a PC for more than Lotus-123 spreadsheets.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>So why the fuss? Wolfenstein started the 3D first-person gaming genre. In 1992, there were relatively few 3D games and most resorted to isometric graphics (Marble Madness, Paperboy), wire-frame (Star Wars, Elite, Starglider) or faked overlaid 2D sprites (Outrun, Chase HQ, Space Harrier). True 3D games were available in the arcades (I-Robot, Hard Drivin&#8217;) but they took themselves a little too seriously and couldn&#8217;t be replicated on the 16-bit PCs of the day.</p><p>I remember playing Wolfenstein for the first time; it changed my perceptions about what could be achieved on a PC. While it looks basic today, having the freedom to explore realistic 3D rooms blasting stuff was revolutionary &#8212; and shouldn&#8217;t have been possible given the hardware limitations.</p><p>More importantly, the game was fun; you played a prisoner trying to escape from a Nazi-controlled castle in World War II. The VGA gore was amusing and you could defeat a robotically-enhanced Hitler at the end of the game. That said, not everything was perfect. The walking movement was unrealistically smooth and the corridor map was always rectangular &#8212; combine that with may hours game play and Wolfenstein remains the only game which made me feel genuinely queasy!</p><p>iD Software&#8217;s success with Wolfenstein led to Doom a year later &#8212; it&#8217;s fair to say you wouldn&#8217;t be playing <em>Call of Duty</em> today if it weren&#8217;t for those two ground-breaking games.</p><p>A version of Wolfenstein was released on almost every computer and gaming platform <em>(even Nintendo permitted the gore-fest on their family-friendly consoles, although iD were instructed to replace guard dogs with large rats)</em>. The browser version if faithful to the original DOS version and permits you to play every level. Actually, it probably plays and sounds better than it did on the latest 386 PCs we had in 1992.</p><p>Technically, the game is implemented using JavaScript and HTML5 audio. I first thought it was rendered using a <code>canvas</code> element but, thanks to further investigation by Matt Vaughan (below), it&#8217;s actually 320 horizontally-stacked DIVs which have their background, vertical size and top location modified as you move around. It&#8217;s clever but slightly unusual solution. The full page weight is a little over 800kB of mostly uncompressed JavaScript &#8212; impressive given that most sites use that for their home page.</p><p>But who cares about the technical details &hellip; <a
href="http://wolfenstein.bethsoft.com/"><strong>Happy Birthday Wolfenstein 3D</strong></a> and thanks for 20 great years of great gaming.</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=88-8YdK3EX8:eGbg1kv-cMg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=88-8YdK3EX8:eGbg1kv-cMg:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=88-8YdK3EX8:eGbg1kv-cMg:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=88-8YdK3EX8:eGbg1kv-cMg:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/88-8YdK3EX8" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/wolfenstein-3d-html5-browser-game/feed/</wfw:commentRss> <slash:comments>6</slash:comments> <feedburner:origLink>http://www.sitepoint.com/wolfenstein-3d-html5-browser-game/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=wolfenstein-3d-html5-browser-game</feedburner:origLink></item> <item><title>SitePoint Podcast #162: Taking Google For A Drive</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/_Rm7GsQ7E8w/</link> <comments>http://www.sitepoint.com/podcast-162-taking-google-for-a-drive/#comments</comments> <pubDate>Fri, 11 May 2012 22:15:45 +0000</pubDate> <dc:creator>Karn Broad</dc:creator> <category><![CDATA[Podcast]]></category> <category><![CDATA[Google Drive]]></category> <category><![CDATA[marketshare]]></category> <category><![CDATA[silent upgrades]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54592</guid> <description><![CDATA[Episode 162 of The SitePoint Podcast is now available! This week the panel is made up of 3 of our 4 our regular hosts, Patrick O&#8217;Keefe (@ifroggy), Kevin Dees (@kevindees) and Stephan Segraves (@ssegraves). Listen in Your Browser Play this episode directly in your browser &#8212; just click the orange “play” button below: Download this Episode You [...]]]></description> <content:encoded><![CDATA[<p></p><div><p>Episode 162 of The SitePoint Podcast is now available! This week the panel is made up of 3 of our 4 our regular hosts, Patrick O&#8217;Keefe (<a
href="http://twitter.com/ifroggy">@ifroggy</a>), Kevin Dees (<a
href="http://twitter.com/kevindees">@kevindees</a>) and Stephan Segraves (<a
href="http://twitter.com/ssegraves">@ssegraves</a>).</p><h2>Listen in Your Browser</h2><p>Play this episode directly in your browser &#8212; just click the orange “play” button below:</p><p></p><h2>Download this Episode</h2><p>You can download this episode as a standalone MP3 file. Here’s the link:</p><ul><li><a
href="http://media.libsyn.com/media/sitepoint/sitepointpodcast162.mp3">SitePoint Podcast #162: Taking Google For A Drive</a> (MP3, 44:50, 43.0MB)</li></ul><h2>Subscribe to the Podcast</h2><p>The SitePoint Podcast is on iTunes! <a
href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=296180681&amp;s=143441">Add the SitePoint Podcast to your iTunes player</a>. Or, if you don’t use iTunes, you can <a
href="http://www.sitepoint.com/blogs/?feed=podcast">subscribe to the feed directly</a>.</p><h2>Episode Summary</h2><p>The panel discuss Adobe launching a host of Cloud services to go with CS 6 and also kicks off a new website dedicated to the open web. We also take a moment to remember web design pioneer Hillman Curtis and talk about the future of advertising on the Web.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>Here are the main topics covered in this episode:</p><ul><li><a
href="http://techcrunch.com/2012/05/01/comscore-samsung-widens-lead-as-top-mobile-brand-in-u-s-android-51-of-all-smartphones/">ComScore: Samsung Widens Lead As Top Mobile Brand In U.S., Android 51% Of All Smartphones | TechCrunch</a> via <a
href="http://www.revenews.com/cashing-out/cashing-out-week-of-april-29th-may-5th-2012-in-online-marketing-news/">Mobile Marketshare on Revenews.com</a></li><li><a
href="http://thenextweb.com/apps/2012/05/04/foursquare-launches-a-new-history-page-to-search-all-of-your-past-check-ins/">Foursquare Launches New &#8220;History&#8221; Page</a></li><li><a
href="http://davidwalsh.name/silent-browser-upgrades">Silent Browser Upgrades | David Walsh</a></li><li><a
href="http://googleblog.blogspot.com/2012/05/google-hangouts-on-air-broadcast-your.html">Official Google Blog: Google+ Hangouts On Air: broadcast your conversation to the world</a></li><li><a
href="https://drive.google.com/">Google Drive</a></li></ul><p>Browse the full list of links referenced in the show at <a
href="http://delicious.com/sitepointpodcast/162">http://delicious.com/sitepointpodcast/162</a>.</p><h2>Host Spotlights</h2><ul><li>Patrick: <a
href="http://www.youtube.com/user/blamesocietyfilms/videos">BlameSociety Videos</a></li><li>Stephan: <a
href="http://reviewsindepth.com/2011/04/why-everyone-should-learn-to-program/">Reviews In Depth | Why Everyone Should Learn to Program</a></li><li>Kevin: <a
href="http://webdesignledger.com/inspiration/20-inspiring-examples-of-big-backgrounds-in-web-design">20 Inspiring Examples of Big Backgrounds in Web Design | Inspiration</a></li></ul><h2>Interview Transcript</h2><p><strong>Patrick:</strong> Hello and welcome to another edition of the SitePoint Podcast.  This is Patrick O’Keefe and I’m joined today by my usual co-hosts Kevin Dees and Stephan Segraves; hey guys, how’s it going?</p><p><strong>Kevin:</strong> Howdy, howdy.</p><p><strong>Stephan:</strong> Hi.</p><p><strong>Patrick:</strong> As you may notice we are without our other usual fourth co-host, he usually introduces the show, Louis Simoneau, he’s off with important business-like errands to attend to, or something along those lines, and we’ll be holding the fort down today in his absence.  So I guess let’s go ahead and jump into the stories.<br
/> I’ll take the first story today, on TechCrunch there was a story by Ingrid Lunden that caught my eye, it is about mobile hardware and operating system market share for the three months ending in March, this is according to ComScore and I found this story through Revenues.  So the story has essentially three main numbers, like I said, hardware, software and then also usage through mobile, like use a downloaded app, use the browser, etcetera.  So here are some of the numbers: for hardware you have Samsung in the lead with 26% of the market, that is a gain of .7% from the three months ending in December, in other words the previous three-month period.  LG second with 19.3% with a small loss, Apple is third at 14% with a 1.6% gain, then you have Motorola fourth and HTC 5th, Motorola with 12.8% of the market and HTC with 6.0%, and that represents small losses for both of those brands.<br
/> As far as our branding systems go, Google remains in the lead by a healthy margin with 51% of the market, that is a 3.7% change, and then you have Apple at 30.7%, a gain for them as well of just over a percentage point.  And then you have a big loss from Blackberry from Research in Motion moving down to 12.3%, losing 3.7 percentage points.  Microsoft is in at 3.9, a loss for them, and then Symbian, finally, maintains its ground at 1.4%.<br
/> I don’t know, I guess Symbian is what I have, right?  I don’t know what’s in this small, little, cheap pay-as-you-go phone.</p><p><strong>Kevin:</strong> So, looking at these numbers for the platform specifically, not the hardware but the platform side, it comes to my attention that when you think about like jQuery plugins and CSS tricks and all this stuff, it’s like people tend to move towards the iPhone, and yet Android has continued, or Google, has continued to be the platform of choice, and I understand why, people like the iPhone in development for the reason that it’s fairly consistent across their browser space, whereas Android you have different screen sizes per phone, and all this other stuff that really makes it hard to develop for.  But, I think it is worth drawing attention towards.</p><p><strong>Stephan:</strong> Along those lines, why is the environment so much different then, because you see a lot of development for iPhone apps and very little for Android apps, and not very little in the sense that no one’s developing anything, but because you don’t really hear a lot about Android apps, right, the Instagram app was a big deal.  But I think it comes down to Android users aren’t necessarily willing to pay for apps, right.</p><p><strong>Patrick:</strong> There have been a bunch of different articles suggesting just that, and the numbers bear it out that Apple customers, Apple users, IOS mobile users are just more likely to pay for apps, they’re in Apple’s ecosystem.  Whereas the Android is &#8212; the Android platform is a little more, well, it’s more open, but I mean I guess the downside of that some would say that it’s more disjointed; you know, there are different versions, there are different app market places, you know I’m a Kindle user, Kindle Fire, it’s Android, you know it’s not the current version, it’s the version that Amazon took and made to fit their tablet, and they have their own app marketplace that sells both to the Android platform, in the latest version, but also with a particular focus on the Kindle Fire.  And I download a number of apps, and I downloaded probably hundreds of apps by this point, eh, I would say over a hundred, to be conservative, and I’ve paid for &#8212; I want to say I’ve paid for about 30 apps or so, most of which were on sale or half off or some kind of discount is what prompted me and pushed me to buy them then, you get a lot of the free app of the day and other free apps, but yeah, I don’t know, it’s an interesting dilemma, but as a developer it feels like it’s silly to ignore Android.</p><p><strong>Kevin:</strong> Right, I would agree with you there.  I mean and I guess it’s sort of the point I’m trying to make, but more than that, you know I was focusing a little more towards the Web, the Web side of thing, because that’s what I deal with on a daily basis.</p><p><strong>Patrick:</strong> Right.</p><p><strong>Kevin:</strong> And that part of it is with the iPhone your screen size is always going to be the same, right, and I think that’s really &#8212; I’m harping on this because it is kind of a big deal in that when you create an iPhone app you have a set number of pixels, I believe it’s 320 pixels for the low resolution, and 640, this is Portrait mode I believe, yeah, Portrait mode that you would be in, and so like with Android I mean the array is just massive.  And so I’m mostly referring to things like jQuery mobile and that kind of stuff, which do support Android platforms and that kind of thing, but it’s just interesting for me to like look at these numbers and then see the reflection in like when you see the community talking, right, it’s mostly about the iPhone, you rarely see anything about Android when it comes to Web stuff.<br
/> I think that’s a little bit of sort of the culture of the web design community, right, because everybody that makes websites needs to have ‘The Mac’, you know, you can’t use Windows, kind of thing.</p><p><strong>Patrick:</strong> You can’t be like Patrick.</p><p><strong>Kevin:</strong> But it’s true, though, right?</p><p><strong>Patrick:</strong> Right.</p><p><strong>Kevin:</strong> You do have that little bit of this hatred towards anything other than Apple because in design, right, you want it to be beautiful and to be honest a lot of Windows stuff isn’t just breathtaking.</p><p><strong>Patrick:</strong> Right.  Or at least they have that reputation that continues to follow them.</p><p><strong>Kevin:</strong> Right.  And I think it’s good to look at the numbers and see numbers like this to kind of bring you back to reality because you can get lost in this Apple world.</p><p><strong>Patrick:</strong> And they also said that they are &#8212; was data on the mobile content usage, and there are six categories; send a text message to a phone, that number stays steady, 74.3% of Smart Phone and non-Smart Phone, hello, users sent a text to another phone, 50% used downloaded apps, that’s a 2.4 percentage point change, 49.3% used a browser, that’s a gain also of almost two percentage point, 36.1% access a social networking site or blog, which is just a weird categorization to me; you access a social networking site, or any blog, 36.1%, a gain, played games 32.6%, listened to music on a mobile phone 25.3%, both of those gains of 1.2 and 1.5.  So all actions gained moreorless, but still only less than 50% of the Smart Phone and non-Smart Phone of mobile users age 13 and up in the U.S. used a web browser, so not even 50%.<br
/> Is that surprising?  Is that meaningful in any way?</p><p><strong>Kevin:</strong> Yeah, I think like when you look at these numbers I mean it’s growing, right, and I think that’s the key to pull out of this is that mobile is continuing to grow as statistics have shown, and it will only continue to do that in the future.  And the reason that this even pulls at it even more is these are competitor brands and things like that that we’re talking about, right, so it is a saturated space in that companies are taking it seriously and not just because there’s money in it but because there’s like &#8212; there’s brand awareness in it as well because so many people are using it, I mean Microsoft jumped in the game, right.</p><p><strong>Patrick:</strong> Right.  And you know technically speaking back in November I actually accessed the web browser on my cheap pay-as-you-go phone because someone actually &#8212; Chris Cochran, Christopher Cochran who works for webdevestudios.com, which is the company of Brad Williams who was one of the original four hosts on the SitePoint Podcast here, he had developed a website and it was spitting out what mobile browser you were on and adjusting for that, and so he’s like will it even recognize this?  So we pulled it up and sure enough it recognized it; I forget as what, and it took some time, but I did get to Chris’ website, so &#8211;</p><p><strong>Kevin:</strong> That’s awesome.</p><p><strong>Patrick:</strong> I do have a browser.</p><p><strong>Kevin:</strong> Did he reimburse you for the data usage?</p><p><strong>Patrick:</strong> (Laughs) no, he didn’t.  I don’t know what it cost me, probably &#8212; I don’t know, it probably cost me, hmm, I don’t know, fifty cents or something like that.</p><p><strong>Kevin:</strong> To load a web page?</p><p><strong>Patrick:</strong> (Laughs) well spent.</p><p><strong>Kevin:</strong> That’s a soda out of the soda machine, Patrick.</p><p><strong>Patrick:</strong> Yeah.</p><p><strong>Stephan:</strong> I think this breakdown of mobile content usage it would be interesting if they broke it down even more and said which platforms did what more.</p><p><strong>Patrick:</strong> Right, that’s a good point.</p><p><strong>Stephan:</strong> I think that would be cool to see like if &#8212; are Android users using downloaded apps more than web browser stuff?  And I think that may give us more of a look at how people are actually using the phones and whether we should be developing more and more web apps for Android than say regular native apps.  It’s just interesting to me; I think maybe this all brings us back to developing just responsive web applications that aren’t specific to a platform, right, I don’t know.</p><p><strong>Kevin:</strong> Yeah, definitely.  Especially like when you think about the development of just the desktop platform, right, where a lot of stuff you do would be in apps, but since bandwidth has become increasing like web apps aren’t that uncommon and they’ve become quite popular when you think about 37 Signals and companies like that that are built on it, Twitter, social networks, you know.</p><p><strong>Stephan:</strong> Yeah.</p><p><strong>Kevin:</strong> And that goes into the Smart Phone industry as well, right.  So now with 4G LTE, I believe that’s correct, right; I don’t have LTE here or 4G or anything like that.</p><p><strong>Patrick:</strong> Right, sounds right.</p><p><strong>Kevin:</strong> But that’s high, high speed Internet right there, and with that kind of capability there’s no reason, like you were saying, Stephan, that we can’t come to a place where web apps take over the mobile space above built-in apps, and I’m not saying that that’s actually 100% true because, you know, the phone makers are pushing their marketplaces on the phone, and it’s so easy to buy an app, you know.</p><p><strong>Stephan:</strong> Yeah, yeah, but I think you’re absolutely right, there are certain things now that are easier to do on the phone, and you can make it cross-platform available to everyone without having to distribute the application, right, the websites, the distribution point.  So I think the possibilities there are great, and I hope to see more companies push a web application via the actual web interface and not necessarily through an application, a native application.</p><p><strong>Kevin:</strong> Right.</p><p><strong>Patrick:</strong> On a related note, I just saw a story on The Next Web that was reported today, they are recording May 7th, by Anna Heim, it says that Twitter has updated its mobile web version, <a
href="http://mobile.twitter.com/">mobile.twitter.com</a>, and according to their announcement the purpose of the update was to improve the Twitter experience for users who access the platform from feature phone, low bandwidth networks and older browser, so there you go.  It’s a market they want to tap into.</p><p><strong>Stephan:</strong> Cool.  Speaking of web apps and phone apps, Foursquare today launched a new history page so you can search all of your past check-ins, this is being reported on The Next Web, the writer is Drew Olanoff, and he’s just reporting on the feature, and you can search, it shows a map of all your check-ins, and it basically lets you access all your old history data on Foursquare.  A pretty neat little feature, I’ve played with it a little bit, it doesn’t look like you can actually share it with anybody, which is kind of a feature to me; I don’t know if I want everybody stalking my history.</p><p><strong>Patrick:</strong> Yeah, I was curious about that myself, is that something that you can enable or disable, or is it just something that’s out there for the public?</p><p><strong>Stephan:</strong> I don’t see an option to do it, but what’s odd when I go look at my history I can see old comments on my check-ins and the friends that were at the same locations of those check-ins, so that’s kind of cool.</p><p><strong>Patrick:</strong> Yeah, I’m looking actually &#8212; we must be friends so I’m just going to see.  No, we’re not friends, what the heck?</p><p><strong>Stephan:</strong> Man, Patrick!</p><p><strong>Patrick:</strong> Stephan, man, add me now.</p><p><strong>Kevin:</strong> Tsk, tsk.</p><p><strong>Patrick:</strong> Foursquare.com/ifroggy, I have nine total check-ins, so with my non-Smart Phone, or is it called a feature phone, is that kind of the cool name for it, feature phone?  I don’t really check-in, so, I check in from a browser whenever I check-in; last time I did so was last &#8212; I guess that’s October, the Westin Bonaventure Suites and Hotel in Los Angeles.  I don’t know why that’s funny, but, yeah, that’s the last time I checked in, it was October, or September, I’m sorry, September 2011.</p><p><strong>Kevin:</strong> So, Patrick, you’re looking for &#8211;</p><p><strong>Patrick:</strong> I’m looking at my history now.</p><p><strong>Stephan:</strong> What’s cool about all this, to me at least, is that now a simple check-in allows me to build a map of my travels and things, rather than me having to write something down or take a note in my phone or, you know, I’m kind of anal retentive about all this kind of stuff, just remembering where I was and things, so this is useful to me and it gives me another reason to use Foursquare even if I make it private.</p><p><strong>Patrick:</strong> Right.  And I looked at your profile, I can see the last five history and that’s all.</p><p><strong>Stephan:</strong> Yeah, which is cool, I’m glad, I don’t want you going and stalking my last year’s check-ins; if I want to share that information with you I will.</p><p><strong>Kevin:</strong> So if you show up at a Starbucks at five o’clock in the morning you’ll always run into Patrick, right, according to this history.</p><p><strong>Patrick:</strong> Yeah, you’ll run into me if I’m sleepwalking.</p><p><strong>Kevin:</strong> (Laughs) yeah, it’s an interesting story, it reminds me of Google’s Latitude that they put out a while back where you could track your location and kind of your most common places of interest.</p><p><strong>Stephan:</strong> Yeah, it’s neat, it’s neat, so it’s a step in the right direction, I’m sure people won’t like it or they’ll have some complaint about it, but I think it’s a good step.</p><p><strong>Kevin:</strong> Alright, so I have a story on silent browser upgrades, since Mozilla has released version 12 of their browser it’s now silent upgrading time.  And so this has kind of created a little bit of a stir in the web community, but it’s kind of a new thing but not really since Chrome has been doing it for quite a while, but it’s new for Mozilla and Internet Explorer plans to trail them on this, so it’s becoming the trend of the Web now, for desktop browser specifically here, in that the browsers want their latest version on your computer as soon as possible, and I can’t say I disagree with that.<br
/> So this article kind of goes through step-by-step parts of the reasons why it’s a good thing for this to happen, and I like the story in short because it is short, and because it covers some of the practical things and thoughts behind browser silently upgrading themselves.  Some of the points I like are the Internet Explorer example that it has which basically says that because of Internet Explorer 6 sitting stagnant for so long there’s no way to get that upgraded to Internet Explorer 8 even if you’re on XP because you can’t silently upgrade, and so if they had had that everyone, you know, we would have gotten rid of this Internet Explorer 6 issue a lot sooner.<br
/> And so things like user agent sniffing is gone now in replace of feature detection, things like that that you can do, and that UA detection isn’t as good because like if the browser’s upgrading itself then you have to update your script, and so the best way to really detect what version is through the feature detection.  And there are other things, he points out some things, but those two points I think are the biggest for me which is the Internet Explorer.<br
/> And also, thirdly, he makes his first point which is you have to see past your expertise, right, because we’re all kind of webbies, but the normal person they just say well I just click on the blue E and it takes me to the Internet, right, that’s the Internet, the blue E, like they don’t even know that it’s Internet Explorer, and so like that even furthers the point of, you know what, these people aren’t gonna upgrade their browsers because they don’t even know what it is to begin with, like unless there’s a popup on their screen, which people are already wary of, right, because of viruses, especially if you’re a Windows user, you know, it’s like it’s just one of those things where it’s like it’s about time, it’s a breath of fresh air in my opinion.</p><p><strong>Patrick:</strong> I mean the tricky thing here, and of course the kind of other side of this is that, you know, talking about Microsoft, Google, some might think of them as Big Brother in a way, you know, pushing things down at their leisure into your computer, right, and I guess there are cases where &#8212; this isn’t something we want to see proliferate into every application, right, this isn’t something we want, we don’t necessarily want silent upgrades in every piece of software that we have installed on our machine.</p><p><strong>Kevin:</strong> Correct.</p><p><strong>Patrick:</strong> Web browsers are kind of a special case just because they are used to access the wild, wild, Web, right, the wilderness that could be full of who knows; not only do you have the nefarious things like viruses or malware, and they may exploit an outdated browser, but then you have certainly for our audience, the developer concerns, having as much of a consistent experience as possible for a majority of your visitors regardless of the browser that they are using.  And so ensure that you need people to be using similar standards and adhering to similar practices where the browsers will read a certain piece of code the same way, whether the wide variance that exists between say Internet Explorer 6 and even Internet Explorer 10 or Firefox or Chrome.  You know, but there is that concern there, and like I said, this isn’t something you want to see in everything, is it?</p><p><strong>Kevin:</strong> No, not at all, to be honest there’s not much you can do to get around the malicious type of software that they’re just gonna do this anyways, right, I mean they put themselves on your computer just by visiting a website, you don’t even have to click a button sometimes.</p><p><strong>Patrick:</strong> Right.</p><p><strong>Kevin:</strong> And so there are things that the browsers are doing like, for example, Firefox allows you to stop the automatic updates if you want to, so, you know, for example in the comments there’s one fellow here who uses a CMS but he can’t get it to work on many browsers except for Firefox 3, so what does he do, he turns those off and he’s okay.<br
/> You know something I thought was very interesting is I was using Firefox one day and then all of a sudden it just updated without me asking it to, and so I don’t know what happened there.</p><p><strong>Patrick:</strong> You’re like, oh, Firefox you sly devil.</p><p><strong>Kevin:</strong> Yeah.  So like it would have been interesting to have had like a box to select or something, like maybe I did check it and I just didn’t realize it, sort of like Windows XP had before where you would get automatic updates with I believe service pack 2.</p><p><strong>Patrick:</strong> Yeah, and it’s true what you say about popups, because I can say I use my computer and every time I see a popup to upgrade something oftentimes it is Adobe, something Adobe, Adobe Air or &#8211;</p><p><strong>Kevin:</strong> Flash.</p><p><strong>Patrick:</strong> Flash, right, even Acrobat; and sometimes there’s a prompt for Java, to upgrade to the latest version of Java, since I have those notifications on, and then you have a few other things here and there, I use a program called Malware Bites, and once in a while that’ll prompt me for a new version.  But then I go use the computer that my family has that they use, and that’s my brother and my parents, and they’ll just ignore those popups forever (laughs), they will not touch those things until I get there and see the pile-up of, well, everything needs to be updated outside of Windows because Windows will restart, you know, will say we’re gonna do this, you have four hours if you want, but we really need to do this.<br
/> And so, yeah, I mean it’s funny how that is the case.  So it’s a tricky era that we live in where we’re concerned about so many different areas of privacy and control, certainly Facebook is constantly in the news regarding those issues, you have legislation, SOPA, PIPA, SYSA, SYSPA, and anything else that ends with an A.  And then you have those issues and people are going to have concern about their privacy, and yet, they want to allow some of these major companies that are parties to these legislations, sometimes pro, sometimes against, but just to install things onto the computer.  And, on the other hand, you have people like my family who won’t upgrade anything and might be vulnerable, so I don’t know what the &#8212; I guess it is we have to go down this road, and if any company abuses it, and I don’t think any reasonable company will, but there’s always that chance that there’s that one person who does something, you know, it’s gonna be a major news story, and then we’re gonna have CNN talking about, well, Mozilla, Google, they were pushing updates to your computer without your permission, find out more at 11:00.</p><p><strong>Kevin:</strong> Yeah, and they were stealing your data and all your documents and finding out what you wrote to your ex-wife, kind of thing.</p><p><strong>Patrick:</strong> Right, because it’s an issue that once it’s in the mainstream it’s much like the legislation really, a lot of people will talk about it but very few people will understand it.  And that’s exactly the kind of issue that that would be, you know, the news will grab onto it as a headline and it is newsworthy, and if I a company does abuse it, it deserves to be put out there.  But then you create this fear, and 99%, similar to what Mr. Wall says in this blog post, 99% of users don’t care what browsers they’re using, well, that’s the same 99% that won’t understand this issue if it goes wrong.<br
/> But I don’t know, I don’t see any other way, so actually I’m interested to see the browsers kind of widely adopting this practice, and I have to say I like the logo on this blog; have you put your mouse over it?</p><p><strong>Kevin:</strong> I have not, let me try, ooh.</p><p><strong>Patrick:</strong> Put your mouse over that thing.</p><p><strong>Kevin:</strong> Oh my gosh, that’s kind of rockin’ right there, literally.</p><p><strong>Patrick:</strong> It’s kind of like a vinyl record.  It’s like “wiki wiki wiki”.</p><p><strong>Kevin:</strong> I’m a DJ on this website; check it out, what’s up.  Yeah, I think it’s an interesting story and one to watch for, you know, because part of this also is with the silent update thing, right, what happens when, for example, like silent updates maybe for Internet Explorer 8 versus 9, like you can’t get Internet Explorer 9 on Windows XP.  Now there’s good reason for that, but you know situations like that where it’s more than just them trying to update your computer, it’s like a physical limitation of the device you have, and like the conflicts that that creates.</p><p><strong>Patrick:</strong> Yeah, and I was just looking at operating system percentages for the visitors on one of the communities that I manage, and someone asked other members what they were using, and so I posted the, first of all, the operating system itself, and then they wanted a breakdown of Microsoft and the Windows Operating Systems, and I have 57.54% on 7, 28.60% on XP, 13.3% on Vista, and then small percentages beneath that; Windows server 2003 was .37% and then it kind of went down, and we had one visit from Windows ME, this year.<br
/> So, yeah, I mean you have 28.60% of Windows visitors, which represent a majority, and those people won’t be able to get those newer versions of IE, and you still have to, you know, there’s still a sizable part of the website.  So even with automatic upgrades eventually if they don’t upgrade the operating system it seems like the upgrades will come to an end.<br
/> So, speaking of Google, we have a post here from the Google official blog announcing that Google+ Hangouts on Air is now available worldwide, and previously this was a feature that was in Beta.  Basically it allows you to put a live broadcast out there on the Web in Google+ and on your YouTube channel, if you so desire, hangouts have been around for a while, of course, they are kind of one of the Google+ killer features, if you will, get together with a group of people that you know and talk and have a nice video chat; I’ve actually done that with you Kevin.</p><p><strong>Kevin:</strong> Yes, and we also did Turntable that day I believe.</p><p><strong>Patrick:</strong> Yeah, we actually were on, we just kind of shut down the Internet, we broke the tubes.  So, yeah, we were on Google Hangouts and playing around with <a
href="http://turntable.fm/">turntable.fm</a> listening to music as well, so that was fun and I’ve done a few hangouts, I did one actually for Dell in I believe it was February on Community Manager Appreciation Day they did a community manager kind of one-hour event where we did some presentations for ten minutes each, and I participated in that, and Dell has done a bunch of stuff on their Google+ page.  But so the Google Hangouts on Air take you to a different level allowing you to be live to the world.  And if you have a popular YouTube channel that’s another way to engage with your audience, to have a live stream and to have people actually participating with you and talking with you as you’re doing it, and there’s a million different uses for that, obviously, but the thing that struck me about this is there are entire companies that are built to satisfy this need, UStream comes to mind immediately, there’s one that we use for my other podcast, Copyright 2.0 show called SPRAYcast.<br
/> And they have other features, right, you can display questions on the video player, they record the videos, which Google is doing with Google Hangouts on Air, and you can have two people on the screen at one time, you can have four people on at one time on the same kind of screen looking at all four people, there are a lot of different things that you can do with it; Google+ Hangouts allows you to have people on the screen but only one person gets the main camera.  Those are really small differences, and to me if you can be on YouTube live, no offense to UStream or anyone else, but why would you want to be on UStream live?  Is that a fair thought or what do you think about competition in that kind of live streaming space now that Google is essentially saying we are definitely in?</p><p><strong>Stephan:</strong> So my question is when do we do a live stream of the show on this and try it out.</p><p><strong>Patrick:</strong> I don’t know.  I was thinking about that.</p><p><strong>Stephan:</strong> We should give a test drive; if we’re gonna talk about it we should at least try it out.</p><p><strong>Patrick:</strong> Right, well, you know, I haven’t done Google Hangouts on Air, and that’s an interesting point, and if you’re listening to this and you’d be interested in us doing this show live leave a comment at <a
href="http://sitepoint.com/podcast/">sitepoint.com/podcast</a> on this episode and let us know if that’s something that you’d like to watch.  But, yeah, that’d be fun, but yeah, I mean I don’t know, it’s interesting, I’m planning on doing more video stuff this summer, and I think there’s a great opportunity there for a lot of popular YouTubers to kind of take their channel to another level rather than having to, you know, previously it was kind of weird, you have this kind of divide, right, and I think some might argue that YouTube and Google were kind of slow to it, but maybe they were just waiting for the right time, right, the right network, the right bandwidth to kick this feature out, because it does take a lot of bandwidth, and so you had this divide of services that host video, like YouTube, Blip.tv, and so on, and then you have services that hosted live video, you know, you weren’t uploading videos to them, that live video was all that they do, and we did live SitePoint podcasts at WordCamp Raleigh two years in a row and used UStream in both cases to stream that show out, but you know if we were to do it now I don’t see a reason why we wouldn’t use Google+ instead since they are essentially matching the video hosting, the great functionality they have at YouTube, you know all the little things they do whether it be captioning or links in videos or all the great user features with the functionality that these other dedicated startups already had.</p><p><strong>Stephan:</strong> I think one key thing that will increase the YouTube usage, or increase this feature usage, is I think a lot of people were hesitant to go to websites called blip.tv or UStream, or whatever, without knowing what it was and understanding what a live stream was, and they’ll be much more willing to click on something that says YouTube, watch the YouTube video.</p><p><strong>Kevin:</strong> Yes.</p><p><strong>Stephan:</strong> I think that that’s a big selling point for people, it’s known, it’s in their brains, they’ve used it before and so they’re comfortable.  I think that the other services will struggle to fight that with YouTube and with Google.</p><p><strong>Kevin:</strong> Yeah, it’s hard to create that trust that Google has created with its users over the years, in sites like Blip and that kind of thing, and so you’re exactly right, Stephan, right?</p><p><strong>Stephan:</strong> I hope so (laughter).</p><p><strong>Patrick:</strong> You’re all just so right, but here’s the thing, that’s a good point, it’s brand equity, right, it’s brand capital they’ve built up by being in business for so long and having a generally good reputation, and that’s something that Google brings to any industry, right, when they jump in Smart Phones this is Google Smart Phone, this is Google Android, even though it’s branded as Android and it’s open source and there’s that &#8212; I would say that comfortable division that they create to make people feel comfortable with engaging with that operating system, but it’s Google, and you know when Google jumps in a new industry or a new platform they instantly have that, and that’s true right across the board, and that includes Google Drive which just recently launched.  I mean you have established players who are both super well known companies and not so well known companies, you can think of Amazon as one of the really well known ones with their Cloud drive servers, and then you have a lot of Cloud storage services that are out there, Dropbox is pretty well known, but like I used the example of my family earlier, they don’t know Dropbox, you know my parents don’t know what Dropbox is, but they know Google, they do know what Google is, so even in that case Google Drive has that sort of leg up.<br
/> Have you guys had any opportunity to look at Google Drive?</p><p><strong>Kevin:</strong> So I signed up for the service but I have not used it yet, so now instead of Google Documents whenever I go in the browser it says Drive, and that’s about the extent I have used Google Drive.</p><p><strong>Patrick:</strong> A re-branding.</p><p><strong>Kevin:</strong> Right.  So like it would be fun to try out, but to be honest I’m using Dropbox and I’m happy, and I think this is a good thing to talk about here, because not just about Google Drive but also for Dropbox, right, because Dropbox is fulfilling my needs and I’m very happy with Dropbox, so my incentive to even look at Google Drive like is zero because I’m completely, I’m 100% satisfied with Dropbox, Dropbox does everything that it says it will, and so I have absolutely no need maybe outside of price to look at somewhere else.</p><p><strong>Patrick:</strong> That’s the reason I always give people when they say why do you still use that web browser, and they did that when I used IE for many years, why are you still using that instead of Firefox?  Well, because I have no reason.  And I went over to Firefox and people are like why aren’t you on Chrome? Well, I have no reason, and I’m still on Firefox, but that’s an interesting point.  So I haven’t really used Google Drive either, but their feature page makes it pretty clear what they are doing, it’s not just a stored service, like you said, it ties into Google Docs seamlessly, and it incorporates Google’s very powerful search technology, so that’s a benefit to be able to search those archive files.  You can view things in the browser, they say you can view and open over 30 file types right in your browser, including HD video, Adobe Illustrator and Photoshop, even if you don’t have the program installed on your computer, that’s interesting.  And Google Drive also interacts with a number of different apps and has a very powerful sharing interface where you can share files with just the right files that you want to put them out there with, and there’s some discussion element to files and collaborative documents that might remind some, I don’t know, it looks a little like Google Wave to me, though I haven’t really played around with it too much, that might be an erroneous statement, and also Google Drive tracks the changes that you made to your file, so when you hit a save button a newer version was saved, and that was already true for Google Documents and it seems like it might also be true for files that you put up, but I don’t know if that’s the case or not, but that would be interesting if that was an actual feature.  But Google Drive has been talked about for a long time, and it’s interesting to see them finally get it out the door.<br
/> Do you use &#8212; you know you mentioned Dropbox, do you use anything beyond that for Cloud storage or do you backup to the Cloud, Stephan?</p><p><strong>Stephan:</strong> I use Amazon.</p><p><strong>Patrick:</strong> Cloud Drive.</p><p><strong>Stephan:</strong> The Cloud Drive, yeah, to backup some stuff, and I use a service called Crash Plan.</p><p><strong>Patrick:</strong> Okay, Crash Plan, my brother has that also; I got him hooked up on that when he went to college.</p><p><strong>Stephan:</strong> Yeah, it’s a good service.  The coolest thing I saw on here, on this Google Drive features list, was the photo storage and the search by, it can recognize objects.  So that technology right there is unbelievable, so if you upload a picture of a mountain and it’s Everest, and you do a search and it can tell that it’s Everest, that’s amazing.</p><p><strong>Kevin:</strong> That’s a little too personal for me (laughter).  Hey, look, it’s Kevin in 12 of these photos, don’t you know that guy?  Like Google you shouldn’t know my face, that scares me (laughter).</p><p><strong>Patrick:</strong> The thing is it’s gonna be real scary when they notice just parts of your body, like you search Kevin’s arm, oh, Kevin’s arm appeared in 27 photos (laughter), how many photos are Kevin’s fingerprints visible in, oh, 3,627, oh, we won’t do anything with that information.</p><p><strong>Stephan:</strong> Did you mean to look for the arrest record of Kevin.</p><p><strong>Kevin:</strong> Wow.  No, ‘did you mean’ in Google Docs (laughter)</p><p><strong>Patrick:</strong> That’s very funny.</p><p><strong>Stephan:</strong> So I think that’s really cool, and I think one of the scary parts for me and the reason I’m kind of hesitant to try this out is does it index your drive and where does that information go?  And I can’t find anything on all that information yet, I’ve been looking through the privacy while we’ve been on the call by privacy features, but I haven’t seen anything, so if anyone knows out there, any of the listeners, I would love to know what you found regarding what they do with the indexed data on your computer.</p><p><strong>Patrick:</strong> Kevin, I asked Stephan if he used any similar services, he mentioned Crash Plan and then Amazon Cloud Drive, what about yourself?</p><p><strong>Kevin:</strong> Well, since we’re advertising for people, I use Carbonite, and I use Dropbox, and then I use Google Docs, and then I will soon be using the Adobe Cloud, Creative Cloud.</p><p><strong>Patrick:</strong> I just don’t have the bandwidth to use Carbonite and Back Blaze and Crash Plan; I mean it would take decades to get my stuff up.</p><p><strong>Kevin:</strong> You just leave it running overnight.</p><p><strong>Patrick:</strong> Yeah, I know, overnight for a few decades and we’ll be there, you know literally I’m not kidding.</p><p><strong>Stephan:</strong> Yeah, I mean I’m sitting on about a terabyte of data, and I send it to and offsite hard drive, like I don’t use their actual Cloud storage, I just use their service, so it goes to a friend’s computer, which I’m sure he loves when I like upload a bunch of photos, I’m sure his bandwidth really takes a beating (laughs), but I used to have it at my work, I used to have a hard drive sitting at work and I just left it plugged in.</p><p><strong>Kevin:</strong> What’s to be said, I don’t mean to extend this conversation, but what’s to be said for things like photos and music?  When you think about like the iTunes Cloud or Apple Cloud, whatever, the iCloud I guess it’s called.</p><p><strong>Patrick:</strong> A lot of Clouds.</p><p><strong>Kevin:</strong> Amazon mp3 player and their instant video, do you not think that this is where people are going to store their valuables?  Like why put this equity in something that you really can’t protect, and why not put it in the hands of someone that can, even if you don’t physically own a copy, like that’s what I’ve started doing, like all of my music is in Amazon Cloud, so like I don’t need to backup my music, I don’t really backup much of anything other than my documents folder because everything that’s important to me is backed up online within site services, not necessarily on site drives.</p><p><strong>Patrick:</strong> This is interesting because on the Copyright 2.0 show, the other podcast that I host, the mega upload cases is a big story we talk about every week the different updates and developments, and one of the things that came up recently was people wanting access to the files that were on the service, people who used it as a backup service, as a file locker for their files and their documents.  And it’s an interesting question of exactly what you are entitled to legally and what’s fair for you to be entitled to, right, I mean if you sign up with Crash Plan are you entitled to those files forever, are you entitled to the access for those files for how long, I mean companies go out of business as we know, they have financial trouble, they file for Chapter 11, etcetera.  So obviously best practices you get some notice of that happening, but if the service is run poorly, as may have been the case with Mega Upload, then what happens when they get seized or they get shut down.  Me personally I always think you should have something other than the Cloud service for your important documents, I mean that’s just my thinking about it, and the terms of service for any of these services will probably back that up in saying what you are entitled to and what you’re not entitled to.  So there’s this danger and, you know, Brad and Stephan we used to joke with Kevin about the Cloud and how I wouldn’t use Open ID and I wouldn’t trust Cloud Services 100% with all my data, but that’s true for me here as well; I’d love to have it as kind of a backup backup, but putting all your eggs into that basket it’s not without it’s risks.  And truth be told, Amazon and Google aren’t probably going anywhere, but still the same principle applies.</p><p><strong>Kevin:</strong> But with those services you can still download what you have on them to your computer at a moment’s notice.</p><p><strong>Patrick:</strong> Right, but if they get seized tomorrow by the government I mean it’s gonna be too late.</p><p><strong>Kevin:</strong> I would say my laptop has as much chance of being seized by not just the government but by somebody that walks by me in the coffee shop and wants to just snatch my computer away, right.</p><p><strong>Patrick:</strong> Right.  But at the same time there’s a difference between Google and Amazon and Crash Plan and Back Blaze and then Mega Upload and Rapid Share, right, there’s difference, Google and Amazon may have a stronger legal team, right, and they may be doing things a little more appropriately, but then if you’re using these other services that don’t have the same resources or might not be run the same way, you know, it’s just always important to be aware of what you’re getting into and who you’re placing all those files in with.</p><p><strong>Kevin:</strong> We trust banks, right, we trust banks with our money and our, you know, where we deposit at.</p><p><strong>Stephan:</strong> Yeah, for $100,000.00, $250,000.00, yeah.</p><p><strong>Patrick:</strong> Right.  Part of the reason that we trust banks is because they’re backed by the FDIC up to $100,000.00 or $250,000.00, and there’s that insurance plan; that doesn’t exist with Cloud Hosting, you know, and probably won’t.</p><p><strong>Kevin:</strong> Right.</p><p><strong>Stephan:</strong> I guess I’m a little different, I think it depends on what your workflow is, right, or what your use case is; I don’t backup my music, I have a hard drive with the music on it, if it goes out then so be it, I honestly don’t have that much music, and now with web services &#8212; and this comes back to &#8212; we’re coming full circle back to where we were at the beginning of the show, right, I have an app, it’s called Pandora, I can play random music that I want to listen to, I can use RDIO, I could use Spotify, I could use any of these services that are out there to play music without actually having my hard drive.  To me what’s important to backup is my personal stuff, my photographs, my personal documents, and that’s about it really, that’s the only thing I need to backup and make sure it’s anywhere.  But my photographs library is huge, so for me it’s different than what you guys are using it for or not using it for, and I think for everyone it’s going to be the same way and what’s important to them and how they want to back that stuff up and how they want to ensure they have that information when they need it.  Just my two cents.</p><p><strong>Kevin:</strong> Yeah, I agree with you and Patrick, I mean you both used the same keyword which was ‘important’, right, it’s all defining what’s important to that person; if it’s really, really important you’re going to want a physical copy of it, I mean that’s just the brass tacks I guess.</p><p><strong>Stephan:</strong> Yeah, absolutely.</p><p><strong>Patrick:</strong> And Google Drive, if you’re interested, the pricing is as follows: you can get five gigabyte of Google Drive free, and then on top of that they say 10 gigabyte of Gmail and one gigabyte of Picasa, and then for $2.49 a month you can go 25 gigabytes for drive and Picasa, and Gmail is upgraded to 25 gigabytes.  For $4.99 a month you go to 100 gigabytes, that’s 100 gigabytes for Drive and Picasa, and once again your Gmail is upgraded to 25 gigabytes, and beyond that 200 gigabytes up until 16 terabytes you can upgrade your plan, and that ranges from $9.99 a month up to $799.99 a month for a 16 terabytes, so, yes, Google has plans for everyone.</p><p><strong>Kevin:</strong> That sounds a little creepy, Patrick, “Google has plans for everyone,” mwuhahaha (evil laugh).</p><p><strong>Patrick:</strong> And their data.</p><p><strong>Kevin:</strong> Yes, and everything you own.</p><p><strong>Patrick:</strong> Alright, so with that said I think we’ve come to the end of our story segment, and let’s do host spotlights.  Kevin, why don’t you go first.</p><p><strong>Kevin:</strong> So my spotlight comes from <a
href="http://webdesignledger.com/">webdesignledger.com</a>, it’s 20 inspiring examples of big backgrounds in web design, and it’s just really a fun post of pretty inspiring, of course, website screenshots and links to those sites, so check it out, it’s pretty cool.  I mean some of this stuff is pretty neat, but I mean it’s all big background, so.<br
/> big background, so.</p><p><strong>Patrick:</strong> Cool, yeah, you can see kind of a consistent theme, there’s a lot of visual obviously, but not as much text, right, the text is kind of sparse, selective with how the text and what the copy on the page contains.</p><p><strong>Kevin:</strong> Hmm-mm.  It feels very much like an ad in a magazine with navigation.</p><p><strong>Patrick:</strong> Cool.  Stephan what do you have?</p><p><strong>Stephan:</strong> I have a blog post by a man named Dan Haggard, he writes for a website called Reviews in Depth, and his post is called Why Everyone Should Learn to Program.  And Mr. Haggard works at a university, he’s an administrator, and it’s just a nice, long blog post on him writing an application and then showing this application to one of his co-workers and getting them excited to program.  And he just kind of talks and touches on a few things that I think resonate with people who aren’t programmers.  My wife is a math major and I shared this with her and she really enjoyed it because I think it kind of made sense to her, you know, we use a lot of interfaces in our day-to-day lives, the stove you use to cook your dinner, the knife you use to cut your food, the car, the anything, and this kind of touches on how that can be translated into programming and how it’s just an interface for getting things done.<br
/> So, it’s one of those articles that you can use to show someone who’s kind of skeptical on you writing an application, and have them read this and I think they’ll get it a little bit better.</p><p><strong>Patrick:</strong> Very cool.  I myself am not a programmer but I sometimes wish I was.<br
/> And my spotlight is a web video series called Beer and Board Games, it’s by Blame Society Films, and you can find them at <a
href="http://youtube.com/blamesocietyfilms/">youtube.com/blamesocietyfilms</a>.  Basically it is &#8212; Blame Society Films is led by Max Sloane and Aaron Yonda, maybe more popularly known as the guys behind Chad Vader, which is a popular web video series, but they’ve done a bunch of other series as well, and one of my favorites is Beer and Board Games, I watch it regularly with my brother Sean, and they tackle board games popular and obscure.  They’ve done Risk, they’ve done Sex Maniacs, the card game (laughs), so, you know, there are a lot of crazy board games out there, and the shows are just hilarious, they’re kind of &#8212; you know, they’re not three minute YouTube videos, they’re usually about 10 minutes or so, but just great humor, very hilarious and there’s a lot of fun stuff on there channel as well.</p><p><strong>Stephan:</strong> I’ll have to find the Settlers of Catan one; I need to watch that one.</p><p><strong>Patrick:</strong> They haven’t done that one yet, have they?  I’ve never even played that game, I have heard of it.</p><p><strong>Stephan:</strong> (Laughs) it’s a good game.</p><p><strong>Kevin:</strong> Have you heard of Carcassonne?</p><p><strong>Patrick:</strong> Uh, no.</p><p><strong>Kevin:</strong> Ah, man, what’s wrong with you?</p><p><strong>Patrick:</strong> I guess if I come to where you guys are located one day then we can play those games.</p><p><strong>Kevin:</strong> We shall.</p><p><strong>Patrick:</strong> Before we go around the table I’d like to shout out a listener of the show, Chris Trynkiewicz, who is a very literal listener, always commenting on my Google+ posts about the show, so Chris thank you for listening, we really appreciate it.  Chris actually left me a really long comment about something we should talk about on the show, but I didn’t have enough time to review it before we recorded. So thanks again, Chris, and thank you to everyone that listens to the show.<br
/> Let’s go ahead and go around the table.</p><p><strong>Kevin:</strong> Okay, so you can find me <a
href="http://twitter.com/kevindees">@kevindees</a> on Twitter and <a
href="http://kevindees.cc/">kevindees.cc</a> on the Interwebs.</p><p><strong>Stephan:</strong> I’m Stephan Segraves, you can find me on Twitter <a
href="http://twitter.com/ssegraves">@ssegraves</a>, and I blog at <a
href="http://badice.com/">badice.com</a></p><p><strong>Patrick:</strong> And I am Patrick O’Keefe of the iFroggy Network, I blog at <a
href="http://managingcommunities.com/">managingcommunities.com</a>; find me on Twitter <a
href="http://twitter.com/ifroggy">@ifroggy</a>, i-f-r-o-g-g-y.<br
/> You can follow our usual co-host, Louis Simoneau, <a
href="http://twitter.com/rssaddict">@rssaddict</a>, and SitePoint <a
href="http://twitter.com/sitepointdotcom">@sitepointdotcom</a>, that’s sitepoint d-o-t-c-o-m.  You can check out the podcast at <a
href="http://sitepoint.com/podcast/">sitepoint.com/podcast</a> and leave comments on this show or any show, and also subscribe to receive every show automatically.  Email us at podcast@sitepoint.com with your comments and your questions, we’d love to give you our thoughts or read them out on the show.<br
/> The SitePoint podcast is produced by Karn Broad, thank you for listening and we’ll see you next week.</p><p>Theme music by <a
href="http://www.belikewater.ca/">Mike Mella</a>.</p><p>Thanks for listening! Feel free to let us know how we’re doing, or to continue the discussion, using the comments field below.</p></div> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=_Rm7GsQ7E8w:g6fkklyQMFY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=_Rm7GsQ7E8w:g6fkklyQMFY:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=_Rm7GsQ7E8w:g6fkklyQMFY:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=_Rm7GsQ7E8w:g6fkklyQMFY:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/_Rm7GsQ7E8w" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/podcast-162-taking-google-for-a-drive/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <enclosure url="http://media.libsyn.com/media/sitepoint/sitepointpodcast162.mp3" length="0" type="audio/mpeg" /> <feedburner:origLink>http://www.sitepoint.com/podcast-162-taking-google-for-a-drive/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=podcast-162-taking-google-for-a-drive</feedburner:origLink></item> <item><title>Scalable Vector Graphics: an Overview</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/IhBe6RvB0nc/</link> <comments>http://www.sitepoint.com/svg-scalable-vector-graphics-overview/#comments</comments> <pubDate>Fri, 11 May 2012 18:30:38 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[Client Side Coding]]></category> <category><![CDATA[Design]]></category> <category><![CDATA[HTML & CSS]]></category> <category><![CDATA[HTML5]]></category> <category><![CDATA[Web Tech]]></category> <category><![CDATA[canvas]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <category><![CDATA[SVG]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54386</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/672-svg-basics-50x50.png" class="attachment-thumbnail wp-post-image" alt="672-svg-basics" title="672-svg-basics" />Craig provides a concise overview of Scalable Vector Graphics and its associated technologies.]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/672-svg-basics-50x50.png" class="attachment-thumbnail wp-post-image" alt="672-svg-basics" title="672-svg-basics" /><p></p><p>In my recent article, we discussed <a
href="http://www.sitepoint.com/7-reasons-to-consider-svgs-instead-of-canvas/">7 Reasons to Consider SVGs Instead of Canvas</a>. SVGs are ideal if you require a scalable diagram such as a chart or logo which can be altered or animated using JavaScript DOM methods.</p><p>So &hellip; <em>what are SVGs and how do we use them?</em> This is the first part in a series articles about the vector image format.</p><h2>What Are SVGs?</h2><p>SVGs are vector graphics. Rather than defining the color of each pixel like you would in a bitmap (JPEG, PNG, GIF, BMP etc.), vector graphics define lines and shapes, e.g. draw a black line from co-ordinate 0,0 to 100,100. This has a number of advantages: vectors are easy to modify, generally require smaller files and are scalable to any dimension without losing quality &#8212; which makes them ideal for responsive web design. Bitmaps remain the best choice for photographs or very complex images (note that SVGs can include embedded bitmaps).</p><p><img
src="http://blogs.sitepointstatic.com/images/tech/672-svg-basics-vector.png" width="339" height="267" alt="vector vs bitmap comparison" class="center" style="margin:20px auto" /></p><p>SVG is a royalty-free web standard maintained by the <a
href="http://www.w3.org/Graphics/SVG/">W3C SVG Working Group</a>. Version 1.0 of the technology was originally proposed in 1999. <a
href="http://www.w3.org/TR/SVG11/">Version 1.1</a> is the most recent standard with <a
href="http://www.w3.org/Graphics/SVG/WG/wiki/Roadmap">version 2.0</a> expected in 2013.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>There are a couple of other flavors: <a
href="http://www.w3.org/TR/SVGTiny12/">SVG Tiny</a> and <a
href="http://www.w3.org/TR/SVGMobile/">SVG Mobile</a>. These are simplified profiles or subsets of the full SVG specification which target devices with reduced computational and display capabilities. These standards largely relate to how rendering engines parse the image; an SVG 1.1 file can be rendered on a device which supports SVG Tiny but some effects such as gradients and opacities would not be applied.</p><h2>How are SVGs Defined?</h2><p>SVGs are declared using eXtensible Markup Language (XML). It uses tags like HTML &#8212; the following code draws a white circle with a black border:</p><pre><code>
&lt;circle cx=&quot;100&quot; cy=&quot;100&quot; r=&quot;50&quot; stroke-width=&quot;4&quot; stroke=&quot;#000&quot; fill=&quot;#fff&quot; /&gt;
</code></pre><p>Be aware that XML is stricter than HTML. You cannot, for example, omit a closing tag since this will make the file invalid and the SVG will not be rendered.</p><p>The W3C SVG1.1 specification defines 14 main features:</p><ol><li><strong>Basic shapes</strong>: straight lines, polygons, circles, ellipses, and rectangles with or without rounded corners.</li><li><strong>Paths</strong>: outlined or filled paths containing curved or straight lines.</li><li><strong>Text</strong>: on straight or curved paths in any direction.</li><li><strong>Painting</strong>: fills and outlines using solid colors, gradients, patterns, transparency, and markers (line terminators such as arrow heads).</li><li><strong>Color</strong>: fill and stroke properties defined using standard 3 or 6-digit hex or rgb values.</li><li><strong>Gradients and patterns</strong>: CSS3-like gradient declarations or bitmap backgrounds.</li><li><strong>Clipping, masking and compositing</strong>: using elements to outline regions which can be painted.</li><li><strong>Filters</strong>: effects applied to all elements within a container, e.g. blurring, lighting, color adjustments, etc.</li><li><strong>Linking</strong>: hyperlinks to other documents.</li><li><strong>Interactivity</strong>: attaching event handlers using JavaScript.</li><li><strong>DOM Scripting</strong>: accessing and manipulating SVG elements using the Document Object Model.</li><li><strong>Animation</strong>: built-in animations using Synchronized Multimedia Integration Language (SMIL).</li><li><strong>Fonts</strong>: text glyphs defined in an SVG file which can be used as a standard font.</li><li><strong>Metadata</strong>: titles, descriptions, subjects, creators and other properties about the SVG image.</li></ol><h2>Cascading Stylesheets in SVGs</h2><p>SVGs also support embedded or external CSS rules. Like HTML, the selectors can target tag types or IDs and classes assigned to specific elements. CSS properties and values generally follow element attributes. For example, this CSS renders every circle in the SVG with the same white fill and black border color:</p><pre><code>
circle
{
	stroke: #000;
	fill: #fff;
}
</code></pre><h2>SVG Creation Tools</h2><p>Creating SVGs in a text editor is possible but it&#8217;s a slow process, error-prone and not much fun. Fortunately, there are several open source and commercial tools which allow designers and non-programmers to easily create SVG images:</p><ul><li><a
href="http://www.inkscape.org/">Inkscape</a></li><li><a
href="http://www.openoffice.org/">OpenOffice</a> or <a
href="">LibreOffice</a> Draw</li><li><a
href="http://svg-edit.googlecode.com/svn/branches/2.5.1/editor/svg-editor.html">svg-edit</a></li></ul><p>Therefore, a design team could create a great-looking chart which a programmer can modify by applying real data to specific elements.</p><p>However, note that some graphics packages may not create the most optimal code or apply their own XML extensions.</p><h2>SVG Browser Support</h2><p>Although the technology has been available for more than a decade, SVG use within browsers was held back by Internet Explorer which first provided support in IE9. Today, most desktop and mobile browsers can handle SVGs and it is a recognized HTML5 standard.</p><p>Browser implementations vary, but SVGs can either be:</p><ul><li>viewed as a separate file directly in a web browser.</li><li>embedded as an XML section within an HTML page.</li><li>defined as an external page resource within <code>img</code>, <code>object</code> or the old <code>embed</code> tags (or as an <code>iframe</code>, although that&#8217;s effectively viewing the SVG file)</li><li>set as background image in CSS.</li></ul><p>There are a number of plug-in and shim options if you require SVG support in Internet Explorer 8.0 and below. Several fallback to Vector Markup Language (VML); a technology used in Microsoft products which influenced the SVG standard:</p><ul><li><a
href="http://raphaeljs.com/">Rapha&euml;l</a> &#8212; JavaScript/VML</li><li><a
href="http://www.amplesdk.com/">AmpleSDK</a> &#8212; JavaScript/VML</li><li><a
href="http://code.google.com/p/svgweb/">svgweb</a> &#8212; JavaScript/Flash</li><li><a
href="http://xmlgraphics.apache.org/batik/">Batik</a> &#8212; Java toolkit</li></ul><h2>SVG Performance in Browsers</h2><p>SVG XML must be parsed to render images on-screen and represented in memory as a Document Object Model. As with HTML pages, performance will be affected if you attempt to move or manipulate SVGs containing a large number of elements. In extreme cases, the redraw will be noticeable.</p><p>For this reason, it&#8217;s often preferable to use the HTML5 <code>canvas</code> tag for fast action games with hundreds of animated items. However, you may be able to adopt SVGs for some aspects, e.g. a player&#8217;s spaceship could be a simple SVG which can be moved, rotated, scaled and warped over a <code>canvas</code>-generated background.</p><h2>SVGs and Accessibility</h2><p>Owing to their XML data structure, <a
href="http://www.w3.org/TR/SVG-access/">SVGs provide better accessibility</a> than bitmap images. At a basic level, meta data, short text and long text alternatives can be applied to any SVG image.</p><p>That said, screen reader support is poor. SVGs were not considered a viable browser technology until the release of IE9 so vendors did not consider them a priority. The situation will undoubtedly improve.</p><p>In the short term, you could consider transforming SVG XML into a text-based alternative using XSLT.</p><h2>SVGs and Search Engine Optimization</h2><p>Unlike bitmaps, XML is inherently machine-readable so static SVG files can be read, parsed and indexed by search engine bots. Google has been indexing SVG content since August 2010 and results can be found in the standard and image search systems.</p><p>Replacing a few PNGs with SVGs is unlikely to improve your rankings. However, if you&#8217;re displaying data as images without textual fall-backs, switching to SVGs could offer an SEO boost.</p><p>In my next SVG article we&#8217;ll create our first images without the use of a graphics package!</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=IhBe6RvB0nc:3poilrWadEQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=IhBe6RvB0nc:3poilrWadEQ:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=IhBe6RvB0nc:3poilrWadEQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=IhBe6RvB0nc:3poilrWadEQ:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/IhBe6RvB0nc" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/svg-scalable-vector-graphics-overview/feed/</wfw:commentRss> <slash:comments>5</slash:comments> <feedburner:origLink>http://www.sitepoint.com/svg-scalable-vector-graphics-overview/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=svg-scalable-vector-graphics-overview</feedburner:origLink></item> <item><title>Add a Web Console to Your Toolbox, Part 2</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/qc9icwUI3kQ/</link> <comments>http://www.sitepoint.com/add-a-web-console-to-your-toolbox-part-2/#comments</comments> <pubDate>Thu, 10 May 2012 15:00:32 +0000</pubDate> <dc:creator>Jeff Friesen</dc:creator> <category><![CDATA[HTML5]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[HTML5 Dev Center]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54170</guid> <description><![CDATA[<img
width="50" height="28" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/Screen-Shot-2012-05-02-at-4.06.54-PM1-50x28.png" class="attachment-thumbnail wp-post-image" alt="Screen Shot 2012-05-02 at 4.06.54 PM" title="Screen Shot 2012-05-02 at 4.06.54 PM" />A console is a software artifact for reading line-oriented textual input from the keyboard and writing line-oriented textual output to the screen. Part 1 of this two-part series introduced you to a console library for embedding a console in a web page, and demonstrated the usefulness of such a console via a browser shell. Part 2 shows [...]]]></description> <content:encoded><![CDATA[<img
width="50" height="28" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/Screen-Shot-2012-05-02-at-4.06.54-PM1-50x28.png" class="attachment-thumbnail wp-post-image" alt="Screen Shot 2012-05-02 at 4.06.54 PM" title="Screen Shot 2012-05-02 at 4.06.54 PM" /><p></p><p>A <em>console</em> is a software artifact for reading line-oriented textual input from the keyboard and writing line-oriented textual output to the screen. Part 1 of this two-part series introduced you to a console library for embedding a console in a web page, and demonstrated the usefulness of such a console via a browser shell. Part 2 shows you how the console library is implemented.</p><h2>Discover how Console Works</h2><p>The console library is fairly complete, but you might want to extend it with new capabilities (e.g., echo asterisks while inputting a password). Alternatively, you might want to improve performance or implement error checking. Regardless of your purpose, you&#8217;ll need to understand how the library works. The first step in gaining this knowledge is to grasp the library&#8217;s overall architecture. Listing 1 presents an overview.</p><pre>var Console =
{
   init: function(canvasName, numCols, numRows)
         {
         },
   clear: function()
          {
          },
   getLine: function(callback)
            {
            },
   echo: function(msg)
         {
         },
   render: function()
           {
           },
   writeChar: function(ch)
              {
              },
   scroll: function()
           {
           }
}</pre><p><strong>Listing 1:</strong> The console library&#8217;s skeletal structure</p><p>Listing 1 reveals a global object named <code>Console</code> consisting of seven function properties. The first four properties comprise the public API, whereas the last three properties should be considered private and not accessed. This list of properties is far from complete because the <code>init(canvasName, numCols, numRows)</code> function introduces additional properties.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><table
width="60%" border="1"><tbody><tr><th
bgcolor="#0000c0"><span
style="color: #ffffff;">Note</span></th></tr><tr><td>I could have &#8220;hidden&#8221; the final three properties by introducing expressions such as <code>Console.writeChar = function(ch) { /* code here */ }</code> within <code>init(canvasName, numCols, numRows)</code>. I chose to not do so to keep <code>init(canvasName, numCols, numRows)</code> from getting any longer.</td></tr></tbody></table><h3>Discover <code>init(canvasName, numCols, numRows)</code></h3><p>Listing 2 presents <code>init(canvasName, numCols, numRows)</code>.</p><pre>init: function(canvasName, numCols, numRows)
      {
         var canvas = document.getElementById(<wbr>canvasName); Console.numCols = numCols; Console.numRows = numRows; Console.ctx = canvas.getContext("2d"); Console.ctx.font = "20px/20px monospace"; Console.ctx.textBaseline = "top"; Console.charWidth = Console.ctx.measureText("m").</wbr><wbr>width; Console.charHeight = 20; canvas.width = Console.charWidth*numCols+10; canvas.height = Console.charHeight*numRows+10; Console.buffer = document.createElement("</wbr><wbr>canvas"); Console.buffer.width = canvas.width; Console.buffer.height = canvas.height; Console.bufferCtx = Console.buffer.getContext("2d"</wbr><wbr>); Console.bufferCtx.font = "20px/20px monospace"; Console.bufferCtx.textBaseline = "top"; Console.screen = new Array(numRows); for (var row = 0; row &lt; numRows; row++) Console.screen[row] = new Array(numCols); Console.keyQueue = new Array(); function keyDown(event) { // This function is called by all browsers for backspace. if (event.keyCode == 8) // backspace? { Console.keyQueue.push("\b"); // The following code is needed by Chrome to prevent backspace // from moving back in page history. event.preventDefault(); } } canvas.addEventListener("</wbr><wbr>keydown", keyDown, true); function keyPress(event) { if (event.keyCode == 8) { // The following code is needed by Opera to prevent backspace // from moving back in page history. event.preventDefault(); return; } if (event.keyCode == 13) // return? { Console.keyQueue.push("\n"); return; } var ch = (event.keyCode == 0) ? event.charCode : event.keyCode; if (ch &gt;= 32 &amp;&amp; ch &lt; 127) Console.keyQueue.push(String.</wbr><wbr>fromCharCode(ch)); } canvas.addEventListener("</wbr><wbr>keypress", keyPress, true); canvas.tabIndex = 0; // Place canvas in tab order. canvas.focus(); // Give keyboard focus to canvas. Doesn't work on // Internet Explorer. Console.cursorOn = true; Console.cursorCounter = 0; Console.cursorCounterMax = 5; Console.line = ""; Console.clear(); }</wbr></pre><p><strong>Listing 2:</strong> Initializing the console library</p><p>Listing 2 first obtains a reference to the named <code>&lt;canvas&gt;</code> element and saves the number of columns and number of rows in <code>Console</code> properties for use by other functions. It then obtains a context for drawing on this canvas, and initializes this context to a 20-pixel size monospace font. The text baseline is set to the top of the font so that a character&#8217;s coordinates are relative to its upper-left corner.</p><p>Now that the font has been specified, its character width and height are calculated so that the characters can be positioned properly on the canvas. This information is then used to calculate the width and height of the canvas. An extra 10 pixels is added to the width and height so that a five-pixel border surrounds the canvas (and prevents the cursor from being invisible on the bottom row when viewed in Internet Explorer).</p><p>The next few lines create and initialize a buffer to support double buffering. The goal is to avoid flicker by drawing into the buffer and then copying the buffer contents to the canvas. Various blog posts (e.g., <a
href="http://stackoverflow.com/questions/2795269/does-html5-canvas-support-double-buffering" target="_blank">http://stackoverflow.com/<wbr>questions/2795269/does-html5-</wbr><wbr>canvas-support-double-</wbr><wbr>buffering</wbr></a>) suggest that current browsers support double buffering automatically, whereas older browsers typically don&#8217;t.</p><p>A two-dimensional <code>screen</code> array for storing characters that are echoed to the console is now created. JavaScript implements a two-dimensional array as a one-dimensional row array of one-dimensional column arrays. The <code>Array</code> object is used to create the row array and then, for each row element, a column array whose reference is assigned to the row array element.</p><p>Although each row in this table could potentially store a different number of columns (which is known as a <em>ragged array</em>), I&#8217;ve chosen to fix the number of columns to the value passed to <code>Array</code>&#8216;s constructor. An element in the <code>Screen</code> array is accessed via syntax <code>Console.screen[<em>row</em>][<em>col</em>]</code> &#8211; row and column indexes are zero-based.</p><p>Moving on, the <code>Array</code> object is used to create a <code>keyQueue</code> array for storing character and special keystrokes (e.g., newline). This array behaves as a queue in which keystrokes are added at one end and removed at the other. Code that adds keystrokes to this queue is contained in a pair of event-handling functions that are registered with the canvas to respond to key-down and key-press events.</p><p>The key-down event handler responds to the backspace key only. I would have preferred to handle this key via key-press, but that event handler is not called when backspace is pressed in Internet Explorer, Chrome, or Safari contexts. After adding <code>\b</code> to the queue, key-down executes <code>event.preventDefault()</code> to prevent the current page from being replaced by the previous page in Chrome&#8217;s page history.</p><p>The key-press event handler also responds to the backspace key for Firefox and Opera. It ignores this key under these browsers (it would not be a good idea to add a second <code>\b</code> code to the queue), but executes <code>event.preventDefault()</code> to prevent the current page from being replaced by the previous page in Opera&#8217;s page history.</p><p>The key-press event handler also responds to the Enter/Return key by adding a newline character to the queue, and responds to keys whose codes range from 32 through 126 by calling <code>String</code>&#8216;s<code>fromCharCode()</code> function on the code and adding the equivalent character to the queue. On Firefox, <code>keyCode</code> contains 0 for a character key (e.g., A), and the appropriate code must be obtained from<code>charCode</code>.</p><table
width="60%" border="1"><tbody><tr><th
bgcolor="#0000c0"><span
style="color: #ffffff;">Note</span></th></tr><tr><td>Opera does not support <code>charCode</code>, but <code>keyCode</code> distinguishes between uppercase and lowercase characters in a key-press context.</td></tr></tbody></table><p>HTML provides a <code>tabindex</code> attribute and a <code>tabIndex</code> DOM property for placing elements into tab order. Zero is assigned to the canvas&#8217;s <code>tabIndex</code> property for this purpose. Next, the canvas&#8217;s<code>focus()</code> function is invoked to give this element the keyboard focus. Although focus is given on Firefox, focus is not given on Internet Explorer &#8212; you must press the Tab key once or click the mouse on the canvas.</p><p>The canvas manages a cursor via <code>cursorOn</code>, <code>cursorCounter</code>, and <code>cursorCounterMax</code> properties. The cursor is visible when <code>true</code> is assigned to <code>cursorOn</code> (the default value), and the cursor remains visible until <code>cursorCounter</code> reaches <code>cursorCounterMax</code>, at which point it is reset to 0. It then becomes invisible and remains as such for the same duration.</p><p>There are two final tasks for <code>init(canvasName, numCols, numRows)</code> to perform. First, it assigns the empty string to the <code>line</code> property, which is a buffer for storing characters until Enter/Return is pressed. Second, it invokes the <code>clear()</code> function to clear the console and reset the location of the cursor to the upper-left character position.</p><h3>Discover <code>clear()</code></h3><p>Listing 3 presents <code>clear()</code>.</p><pre>clear: function()
       {
          for (var row = 0; row &lt; Console.numRows; row++)
             for (var col = 0; col &lt; Console.numCols; col++)
                Console.screen[row][col] = " ";
          Console.row = 0;
          Console.col = 0;
          Console.render();
       }</pre><p><strong>Listing 3:</strong> Clearing the console</p><p>Listing 3 clears the console by assigning a space to each <code>screen</code> array element. (Although not very performant, I&#8217;m emphasizing clarity. I could probably speed up the code by leveraging <code>Array</code>&#8216;s<code>splice()</code> function.) It then resets the current cursor position (indicated by <code>Console</code>&#8216;s <code>col</code> and <code>row</code> properties) to the upper-left character position, and renders <code>screen</code>&#8216;s contents onto the canvas. (I discuss <code>render()</code> later.)</p><h3>Discover <code>getLine(callback)</code></h3><p>Listing 4 presents <code>getLine(callback)</code>.</p><pre>getLine: function(callback)
         {
            Console.render(); // update cursor
            if (Console.keyQueue.length == 0)
            {
               if (Console.line.length == 0)
               {
                  if (callback != undefined)
                     callback();
               }
               return null;
            }
            var ch = Console.keyQueue.shift();
            if (ch == "\b") // handle backspace
            {
               if (Console.line.length != 0)
               {
                  Console.line = Console.line.substr(0,
                                                     Console.line.length-1);
                  Console.echo(ch);
               }
               return null;
            }
            Console.echo(ch);
            if (ch == "\n") // handle newline
            {
               var temp = Console.line;
               Console.line = "";
               return temp;
            }
            else
               Console.line += ch;
            return null;
         }</pre><p><strong>Listing 4:</strong> Getting a line of input</p><p>Listing 4 describes a polling function that continually checks for input and processes this input one character at a time. The first task is to show or hide the cursor, and this task is accomplished by invoking <code>Console.render()</code>. Because <code>getLine()</code> is continuously invoked by the console demo and browser shell applications, the illusion of a blinking cursor is maintained.</p><table
width="60%" border="1"><tbody><tr><th
bgcolor="#0000c0"><span
style="color: #ffffff;">Note</span></th></tr><tr><td>The cursor&#8217;s blink rate depends upon the delay value passed to <code>setInterval()</code>. The larger the delay value, the slower the cursor blinks.</td></tr></tbody></table><p>The next task is to determine whether any characters are present in the queue. If the queue is empty, <code>getLine()</code> can return. However, it first needs to invoke any callback function passed as an argument, but can only invoke this function when the <code>line</code> buffer is empty (a line of input is not in progress), to prevent screwing up the input line as demonstrated while discussing the browser shell.</p><p>At this point, the queue contains a character that is subsequently removed. If this character is the backspace, and if the <code>line</code> buffer is not empty, the rightmost character is removed from the buffer and the backspace is echoed to the console to keep the <code>screen</code> array synchronized, and <code>null</code> is returned because a complete line of input is not yet available.</p><p>After echoing the character to the console, <code>getLine()</code> checks the current character to see if it is a newline. If so, the <code>line</code> buffer is reset to the empty string in anticipation of the next line of input, and its previous contents are returned. Otherwise, the current character is appended to this buffer, and <code>null</code> is returned because a complete line of input is not yet available.</p><h3>Discover <code>echo(msg)</code></h3><p>Listing 5 presents <code>echo(msg)</code>.</p><pre>echo: function(msg)
      {
         for (var i = 0; i &lt; msg.length; i++)
            Console.writeChar(msg.charAt(<wbr>i)); Console.render(); }</wbr></pre><p><strong>Listing 5:</strong> Echoing a string to the console</p><p>Listing 5 echoes a string of characters to the console one character at a time, updating the current cursor position in the process. The code employs <code>writeChar(ch)</code> for this purpose, and I will explain this function shortly. After writing out the string, <code>Console.render()</code> is invoked to update the canvas with the contents of the <code>screen</code> array.</p><h3>Discover <code>render()</code></h3><p>Listing 6 presents <code>render()</code>.</p><pre>render: function()
        {
           Console.bufferCtx.fillStyle = "#000"; // black
           Console.bufferCtx.fillRect(0, 0, Console.ctx.canvas.width,
                                      Console.ctx.canvas.height);
           Console.bufferCtx.fillStyle = "#0f0"; // green
           var y = 0;
           for (var row = 0; row &lt; Console.numRows; row++)
           {
              var x = 0;
              for (var col = 0; col &lt; Console.numCols; col++)
              {
                  var s = Console.screen[row][col]+"";
                  Console.bufferCtx.fillText(s, x+5, y+5);
                  x += Console.charWidth;
              }
              y += Console.charHeight;
           }
           if (Console.cursorOn)
              Console.bufferCtx.fillStyle = "#0f0"; // green
           else
              Console.bufferCtx.fillStyle = "#000"; // black
           Console.bufferCtx.fillText("_"<wbr>, Console.col*Console.charWidth+</wbr><wbr>5, Console.row*Console.</wbr><wbr>charHeight+5); if (++Console.cursorCounter == Console.cursorCounterMax) { Console.cursorCounter = 0; Console.cursorOn = !Console.cursorOn; } Console.ctx.drawImage(Console.</wbr><wbr>buffer, 0, 0); }</wbr></pre><p><strong>Listing 6:</strong> Rendering the <code>screen</code> array to the buffer (and more)</p><p>Listing 6 is responsible for rendering the <code>screen</code> array to the buffer and updating the cursor. It renders to the background buffer, and ultimately copies this buffer to the canvas to avoid flicker for those browsers where flicker could occur. The background buffer is first cleared to black to remove potential garbage from a previous rendering.</p><p>After setting the drawing color to green, <code>render()</code> iterates over the <code>screen</code> array, invoking the Canvas API&#8217;s <code>fillText()</code> function to draw each character. An offset of five pixels is added to the character&#8217;s upper-left corner to support an empty border that&#8217;s drawn around the console. Characters are separated horizontally by <code>charWidth</code> pixels and vertically by <code>charHeight</code> pixels.</p><p>The next section of code is responsible for rendering the cursor. An appropriate fill style is chosen based on the value of <code>cursorOn</code>: green when true and black when false. Either a green or black underline is then displayed at the current cursor position. The black underline completely erases what was previously displayed.</p><p>Finally, the cursor&#8217;s on/off interval is established: the cursor is visible over five calls to <code>render()</code> and invisible over five calls to this function. Because <code>render()</code> is called by <code>getLine()</code>, and because<code>getLine()</code> is invoked repeatedly by the application under the control of <code>setInterval()</code>, a blinking cursor is observed.</p><h3>Discover <code>writeChar(ch)</code></h3><p>Listing 7 presents <code>writeChar(ch)</code>.</p><pre>writeChar: function(ch)
           {
              if (ch == "\b")
              {
                 if (Console.col == 0 &amp;&amp; Console.row == 0)
                    return; // cannot backspace past the upper-left corner
                 Console.col--;
                 if (Console.col &lt; 0)
                 {
                    Console.col = Console.numCols-1;
                    Console.row--;
                 }
                 Console.screen[Console.row][<wbr>Console.col] = " "; return; } if (ch == "\n") { Console.col = 0; if (++Console.row &gt;= Console.numRows) Console.scroll(); return; } Console.screen[Console.row][</wbr><wbr>Console.col] = ch; if (++Console.col &gt;= Console.numCols) { Console.col = 0; if (++Console.row &gt;= Console.numRows) Console.scroll(); } }</wbr></pre><p><strong>Listing 7:</strong> Writing a single character to the <code>screen</code> array</p><p>Listing 7 writes its single character argument to the <code>screen</code> array and updates the current cursor position. If the character is a backspace, the appropriate element in the <code>screen</code> array is removed. Otherwise, if the character is a newline, the current row advances and the console scrolls vertically upward when necessary. Otherwise, the character is stored at the current position, which advances and possibly scrolls upward.</p><h3>Discover <code>scroll</code></h3><p>Listing 8 presents <code>scroll()</code>.</p><pre>scroll: function()
        {
           Console.row = Console.numRows-1;
           for (var row = 0; row &lt; Console.numRows-1; row++)
               for (var col = 0; col &lt; Console.numCols; col++)
                  Console.screen[row][col] = Console.screen[row+1][col];
           for (var col = 0; col &lt; Console.numCols; col++)
              Console.screen[Console.<wbr>numRows-1][col] = " "; }</wbr></pre><p><strong>Listing 8:</strong> Scrolling the console upward one row</p><p>Listing 8 performs a simple scrolling operation that moves the contents of the <code>screen</code> array up by one row. The first row&#8217;s contents are replaced by the second row&#8217;s contents, and the final row is set to spaces. I&#8217;ve coded this function for clarity, but it could be improved from a performance perspective.</p><h2>Conclusion</h2><p>Console&#8217;s implementation leaves lots of room for improvement. You can add missing features (e.g., echo asterisks while entering a password), boost <code>screen</code>-oriented loop performance (perhaps via<code>Array</code>&#8216;s <code>splice()</code> function), and make the library more robust through argument validation (e.g., compare what is passed with <code>undefined</code>) and exception throwing. Have fun.</p><table
width="60%" border="1" align="center"><tbody><tr><th
bgcolor="#0000c0"><span
style="color: #ffffff;">Note</span></th></tr><tr><td>All files pertaining to this article are located in <a
href="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/code.zip" target="_blank">code.zip</a>.</td></tr></tbody></table> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=qc9icwUI3kQ:PFGuufU4sg4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=qc9icwUI3kQ:PFGuufU4sg4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=qc9icwUI3kQ:PFGuufU4sg4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=qc9icwUI3kQ:PFGuufU4sg4:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/qc9icwUI3kQ" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/add-a-web-console-to-your-toolbox-part-2/feed/</wfw:commentRss> <slash:comments>4</slash:comments> <feedburner:origLink>http://www.sitepoint.com/add-a-web-console-to-your-toolbox-part-2/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=add-a-web-console-to-your-toolbox-part-2</feedburner:origLink></item> <item><title>Proposal sent, now what?</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/-N2Jq2nxrBA/</link> <comments>http://www.sitepoint.com/proposal-sent-now-what/#comments</comments> <pubDate>Thu, 10 May 2012 02:00:12 +0000</pubDate> <dc:creator>Miles Burke</dc:creator> <category><![CDATA[Business]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54514</guid> <description><![CDATA[<img
width="50" height="33" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/shutterstock_55335319-50x33.jpg" class="attachment-thumbnail wp-post-image" alt="shutterstock_55335319" title="shutterstock_55335319" />You've just sent the proposal to your client, but what do you do next? In this article, Miles shares his expertise on the subject.]]></description> <content:encoded><![CDATA[<img
width="50" height="33" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/shutterstock_55335319-50x33.jpg" class="attachment-thumbnail wp-post-image" alt="shutterstock_55335319" title="shutterstock_55335319" /><p></p><p>I&#8217;m a big fan of <a
href="http://www.sitepoint.com/forums/forum.php">the SitePoint forums</a>, and it&#8217;s not just because I write for SitePoint. In fact, I signed up a good five years before ever doing any work with SitePoint, so I&#8217;m allowed to say it. One of my favorite forums is the <a
href="http://www.sitepoint.com/forums/forumdisplay.php?61-Business-amp-Legal-Issues">Business &amp; Legal Issues</a> one, however they have a forum for just about everything, and even better; they have a great community.</p><p>So, whilst looking through my favorite forum, I came across this questions from one of the posters. You can <a
href="http://www.sitepoint.com/forums/showthread.php?850595-Proposal-Sent!-Now-what">read the whole question here</a>, however let me paraphrase;</p><p><em>Once you&#8217;ve sent the proposal what should we do? Should we wait and have the client go elsewhere, should we call back after a day or two, or wait longer. Should we not send it via email and personally hand it explaining everything to them so they are sure to know what they are getting, reducing the chance of them going elsewhere because they are not properly educated.</em><div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>I&#8217;m glad you asked! There are three options available to you, and depending on the size of the deal, and what your take of the prospect is, you may want to choose the most appropriate, however here are my three suggestions, in order of importance.</p><p><strong>Option 1: Meet and hand over the proposal in person.</strong></p><p>This is a great way to ensure that the prospect has a good grasp of what you are offering. The important part here is try and get the actual decision maker in the room – remember, the person you may be sending your proposal to may in fact not be the person who decides, so ensure your proposal covers all the points and walk it through with the decision maker.</p><p>At the end of the conversation, don&#8217;t be afraid to ask for the business; something along the lines of ‘Do you have any further questions, or shall we discuss when we can get started?&#8217; works best for me.</p><p>This option obviously isn&#8217;t the solution if the client is remote, or indeed the work is only small in value.</p><p><strong>Option 2: Send proposal over by email and call immediately.</strong></p><p>This is a great way to make sure that your prospect understands that you are keen to work with him/her. It also means you can ask them for a suitable time in the next 24 hours, so you can chat again on the phone (if they don&#8217;t have the time right then) to walk through your offering over the phone. This helps answer any questions and avoid any roadblocks, as does the above.</p><p><strong>Option 3: Send proposal and call back a day or two later.</strong></p><p>This should be the absolute last straw approach. If you don&#8217;t get through straight away, send them an email asking if they had any questions, and let them know you&#8217;ll try calling again in another two days. Keep this up for a handful of calls, or an answer either positive or negative. It reflects you are keen, and ensures you come across helpful as well.</p><p>Now you&#8217;ll note I haven&#8217;t offered the sales losers approach. I used to do this regularly years ago, and it&#8217;s definitely not the way to handle a proposal follow up; this one is don&#8217;t follow up. If you don&#8217;t follow up, you are demonstrating you don&#8217;t are about the work.</p><p>In this instance, you&#8217;d be just as better off writing a figure on the back of your business card and leaving it with the prospect at your initial meeting; it doesn&#8217;t say anything more about your professionalism or keenness to work with that prospect. Don&#8217;t be that sales loser – pick one of the first three options!</p><p>Good luck with that next sale!</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=-N2Jq2nxrBA:-F7kjPrZ5QM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=-N2Jq2nxrBA:-F7kjPrZ5QM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=-N2Jq2nxrBA:-F7kjPrZ5QM:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=-N2Jq2nxrBA:-F7kjPrZ5QM:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/-N2Jq2nxrBA" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/proposal-sent-now-what/feed/</wfw:commentRss> <slash:comments>3</slash:comments> <feedburner:origLink>http://www.sitepoint.com/proposal-sent-now-what/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=proposal-sent-now-what</feedburner:origLink></item> <item><title>My Website’s Broken: 5 Steps to Determine What’s Wrong</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/ZrJ6ZCIR5Nw/</link> <comments>http://www.sitepoint.com/5-steps-fix-broken-websites/#comments</comments> <pubDate>Wed, 09 May 2012 15:30:03 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[Best Practices]]></category> <category><![CDATA[Cloud]]></category> <category><![CDATA[Disaster]]></category> <category><![CDATA[Disaster Recovery]]></category> <category><![CDATA[failover]]></category> <category><![CDATA[Resources]]></category> <category><![CDATA[Web Hosting]]></category> <category><![CDATA[Web Tech]]></category> <category><![CDATA[disaster recovery]]></category> <category><![CDATA[website]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54311</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/013-surviving-failure-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="013-surviving-failure" title="013-surviving-failure" />Your website's down but you're convinced nothing has changed? Craig's 5-step guide could help diagnose those pesky performance problems.]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/013-surviving-failure-50x50.jpg" class="attachment-thumbnail wp-post-image" alt="013-surviving-failure" title="013-surviving-failure" /><p></p><p>We&#8217;ve all been there. Your wonderful website has been running successfully for months then &#8212; BAM &#8212; it disappears. Or, more often, certain features stop functioning. Despite your protests that nothing has changed, your client isn&#8217;t happy. Prepare yourself for a few frustrating hours of problem probing.</p><h2>Step 1: Identify the Issue</h2><p>This might sound obvious, but I&#8217;ve known many developers open their IDE and start hacking at random code. It&#8217;s more important to determine the issue than the cause at this stage. Is the site unavailable? Is a particular page or function failing? Is it limited to specific browsers?</p><h2>Step 2: Test Resource Availability</h2><p>Nine times out of ten, the problem will be caused by a connectivity issue at your end or the client&#8217;s. If you can&#8217;t access any other pages, it&#8217;s not surprising that your website has disappeared. That said, it&#8217;s not always obvious; certain IP ranges, countries or sections of the internet can become temporarily blocked.</p><p>Test your site from a variety of locations &#8212; a <a
href="http://www.publicproxyservers.com/">public proxy server</a> will help identify whether it&#8217;s a local or global problem. If possible, examine the status of other sites running from the same server or web host.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>One less obvious problem is disk space. If you&#8217;re running a busy site, server logs can rapidly use the available space even when your application&#8217;s storage requirements are low.</p><p>Remember that you might be using resources on other servers. This includes CDN-hosted files, database servers, or remotely-hosted APIs such as those for Google Maps, YouTube, Twitter, advertising services etc.</p><p>You should also check your server loads. A major traffic spike or Denial of Service attack will cause access problems.</p><p>Finally, is your domain registration valid and is the DNS server responding as it should?</p><h2>Step 3: Identify What Changed</h2><p>Once you&#8217;ve rejected connectivity, traffic, DNS and disk space, it&#8217;s time to determine what changed. 999 times out of 1,000 the problem will have been caused by an update.</p><p>You may not have touched the files but are you sure others haven&#8217;t? Check with everyone who has access but don&#8217;t necessarily believe them. Here&#8217;s a typical conversation you&#8217;ll encounter&hellip;</p><p><strong>Client:</strong> My sites not working. What are you going to do about it?<br
/> <strong>You:</strong> I&#8217;ll fix it. Have you made any changes recently?<br
/> <strong>Client:</strong> No. It was like that when I got here.<br
/> <em>&hellip;five hour&#8217;s frantic investigation&hellip;</em><br
/> <strong>You:</strong> You changed X, didn&#8217;t you?<br
/> <strong>Client:</strong> X? Oh yes, I changed X. I did that when I was fiddling with Y and Z.</p><p>Your application may not be directly to blame. Has your web host updated the OS, language runtime, database software or file permissions? While vendors attempt to ensure PHP, Ruby, Python, MySQL, PostgreSQL, etc. remain backward compatible, features will almost certainly change or break between editions.</p><h2>Step 4: Reject the Edge Cases</h2><p>Although rare, you should look for signs of cracking. Software such as <a
href="http://www.sitepoint.com/10-wordpress-security-tips/">WordPress</a>, Joomla and OScommerce are obvious targets, however, changes are often subtle because the cracker wants to retain access. For example, you might discover that a file explorer add-on has been installed or phishing pages have appeared deep within the file structure.</p><p>Finally, you should never rule out hardware problems. Corrupt memory chips or disk sectors could be responsible for any number of bizarre issues. If possible, evaluate your application on a similar set-up or install a separate test version on the same server.</p><h2>Step 5: Fix Your App</h2><p>Once you have eliminated the impossible, whatever remains, however improbable, must be the truth. Perhaps your code isn&#8217;t as perfect as you thought&hellip;</p><p>Do you have any tips for diagnosing website or application problems? What was the most difficult issue you encountered?</p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=ZrJ6ZCIR5Nw:M_0e3_7iyLc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=ZrJ6ZCIR5Nw:M_0e3_7iyLc:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=ZrJ6ZCIR5Nw:M_0e3_7iyLc:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=ZrJ6ZCIR5Nw:M_0e3_7iyLc:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/ZrJ6ZCIR5Nw" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/5-steps-fix-broken-websites/feed/</wfw:commentRss> <slash:comments>3</slash:comments> <feedburner:origLink>http://www.sitepoint.com/5-steps-fix-broken-websites/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=5-steps-fix-broken-websites</feedburner:origLink></item> <item><title>Are You as Smart as Kevin Yank? Take the PHP &amp; MySQL Quiz and Find Out.</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/qVvNqhc_cak/</link> <comments>http://www.sitepoint.com/are-you-as-smart-as-kevin-yank-take-the-php-mysql-quiz-and-find-out/#comments</comments> <pubDate>Wed, 09 May 2012 06:24:16 +0000</pubDate> <dc:creator>Mick Gibson</dc:creator> <category><![CDATA[PHP & MySQL News & Interviews]]></category> <category><![CDATA[PHP & MySQL Tutorials]]></category> <category><![CDATA[Tech]]></category> <category><![CDATA[Tutorials]]></category> <category><![CDATA[Web Developer Quiz]]></category> <category><![CDATA[Web Tech]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54479</guid> <description><![CDATA[<img
width="50" height="43" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/04/php-mysql-50x43.png" class="attachment-thumbnail wp-post-image" alt="php-mysql" title="php-mysql" />We all know Kevin Yank is a pretty smart guy. Now&#8217;s your chance to see if you&#8217;re as smart as Kev, by taking the PHP &#38; MySQL Quiz (which accompanies his new book &#8220;PHP &#38; MySQl: Novice to Ninja&#8220;) Jump in now, and take on the elephant in the room :)]]></description> <content:encoded><![CDATA[<img
width="50" height="43" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/04/php-mysql-50x43.png" class="attachment-thumbnail wp-post-image" alt="php-mysql" title="php-mysql" /><p></p><p><a
href="http://www.sitepoint.com/launch/d724a6" rel="attachment wp-att-53906"><img
class="alignright size-medium wp-image-53906" title="PHP &amp; MySQL: Novice to Ninja" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/04/phpmysql5-cover-86x115.jpg" alt="PHP &amp; MySQL: Novice to Ninja" width="86" height="115" /></a>We all know <a
href="http://www.sitepoint.com/launch/d724a6">Kevin Yank</a> is a pretty smart guy.</p><p>Now&#8217;s your chance to see if you&#8217;re as smart as Kev, by taking the <strong><a
href="http://www.sitepoint.com/quiz-phpmysql" target="_blank">PHP &amp; MySQL Quiz</a></strong> (which accompanies his new book &#8220;<a
href="http://www.sitepoint.com/launch/d724a6 ">PHP &amp; MySQl: Novice to Ninja</a>&#8220;)</p><p><strong><a
href="http://www.sitepoint.com/quiz-phpmysql" target="_blank">Jump in now</a>,</strong> and take on the elephant in the room :)</p><p
style="text-align: center;"><a
href="http://www.sitepoint.com/quiz-phpmysql"><img
class="aligncenter size-full wp-image-54486" title="Take the PHP &amp; MySQL Quiz" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/05/php-mysql5-quiz.jpg" alt="Take the PHP &amp; MySQL Quiz" width="500" height="454" /></a></p> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=qVvNqhc_cak:QquAeUzbmEI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=qVvNqhc_cak:QquAeUzbmEI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=qVvNqhc_cak:QquAeUzbmEI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=qVvNqhc_cak:QquAeUzbmEI:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/qVvNqhc_cak" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/are-you-as-smart-as-kevin-yank-take-the-php-mysql-quiz-and-find-out/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <feedburner:origLink>http://www.sitepoint.com/are-you-as-smart-as-kevin-yank-take-the-php-mysql-quiz-and-find-out/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=are-you-as-smart-as-kevin-yank-take-the-php-mysql-quiz-and-find-out</feedburner:origLink></item> <item><title>XSS Attacks, Redis DB, REST, and More</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/pxZvFXJ_bvk/</link> <comments>http://www.sitepoint.com/xss-attacks-redis-db-rest-and-more/#comments</comments> <pubDate>Wed, 09 May 2012 05:25:33 +0000</pubDate> <dc:creator>Timothy Boronczyk</dc:creator> <category><![CDATA[PHP]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54470</guid> <description><![CDATA[<img
width="50" height="15" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/03/phpmaster-50x15.png" class="attachment-thumbnail wp-post-image" alt="phpmaster" title="phpmaster" />on PHPMaster, we present tutorials on protecting yourself from cross-site scripting attacks, using Redis with the Predis library, understanding REST, using an Access database with PHP, and working with text and CSV files. Be sure to visit phpmaster.com for more great articles!]]></description> <content:encoded><![CDATA[<img
width="50" height="15" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/03/phpmaster-50x15.png" class="attachment-thumbnail wp-post-image" alt="phpmaster" title="phpmaster" /><p></p><h2><a
href="http://phpmaster.com/php-security-cross-site-scripting-attacks-xss/">PHP Security: Cross-site Scripting Attacks (XSS)</a></h2><p>Every PHP programmer has the responsibility to understand how attacks can be carried out against their code to exploit possible security vulnerabilities. Learn about cross-site scripting (XSS) attacks and how you can prevent them in your PHP scripts.</p><hr
/><h2><a
href="http://phpmaster.com/an-introduction-to-redis-in-php-using-predis/">An Introduction to Redis in PHP Using Predis</a></h2><p>Redis is an open-source data structure server with an in-memory data set that does much more than simple key/value storage. This article introduces you to some of the basic yet powerful commands that Redis has to offer using the Predis library.</p><hr
/><h2><a
href="http://phpmaster.com/rest-can-you-do-more-than-spell-it-1/">REST: Can you do more than spell it?</a></h2><p>Though you&#8217;ll often see the words &#8220;REST&#8221; and &#8220;architecture&#8221; together, REST is not a specific architecture. This four-part series introduces you to REST, a set of principles that define how a server and client can communicate with each other (and external resources) in a straightforward and robust manner.</p><hr
/><h2><a
href="http://phpmaster.com/using-an-access-database-with-php/">Using an Access database with PHP</a></h2><p>Sometimes a client will already have a database and ask that we make it available on the Web, and sometimes that database is in Access. Never fear, for PHP can easily work with Access databases using an ODBC driver. Learn the essential elements you&#8217;ll need to put an existing Access database online.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><hr
/><h2><a
href="http://phpmaster.com/working-with-files-in-php/">Working with Files in PHP</a></h2><p>You&#8217;re familiar with databases such as MySQL and Access, but data can also be stored in files. This article gives you an introduction into working with text and CSV files, as well as find out information about the files (such as permissions and the last time it was modified).</p><hr
/> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=pxZvFXJ_bvk:FKRxgdZSdz4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=pxZvFXJ_bvk:FKRxgdZSdz4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=pxZvFXJ_bvk:FKRxgdZSdz4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=pxZvFXJ_bvk:FKRxgdZSdz4:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/pxZvFXJ_bvk" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/xss-attacks-redis-db-rest-and-more/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://www.sitepoint.com/xss-attacks-redis-db-rest-and-more/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=xss-attacks-redis-db-rest-and-more</feedburner:origLink></item> <item><title>Laconic: a New Way to Generate DOM Content from JavaScript</title><link>http://feedproxy.google.com/~r/SitepointFeed/~3/S_4WujyCif0/</link> <comments>http://www.sitepoint.com/laconic-javascript-dom-content-generation/#comments</comments> <pubDate>Tue, 08 May 2012 15:00:48 +0000</pubDate> <dc:creator>Craig Buckler</dc:creator> <category><![CDATA[JavaScript]]></category> <category><![CDATA[JavaScript & Ajax Tutorials]]></category> <category><![CDATA[JavaScript & CSS]]></category> <category><![CDATA[jQuery]]></category> <category><![CDATA[Opinion]]></category> <category><![CDATA[DOM]]></category> <category><![CDATA[javascript]]></category> <category><![CDATA[jQuery Tutorials & Articles]]></category> <guid isPermaLink="false">http://www.sitepoint.com/?p=54308</guid> <description><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2009/01/dom-exception-tree-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="DOM Exception Tree" title="DOM Exception Tree" />Craig looks at Laconic: a small standalone JavaScript library for easy content creation using standard DOM insertion methods.]]></description> <content:encoded><![CDATA[<img
width="50" height="50" src="http://www.sitepoint.com/wp-content/uploads/1/files/2009/01/dom-exception-tree-150x150.jpg" class="attachment-thumbnail wp-post-image" alt="DOM Exception Tree" title="DOM Exception Tree" /><p></p><p>Content can be inserted into your page using innerHTML or outerHTML&hellip;</p><pre><code>
var container = document.getElementById(&quot;container&quot;);
container.innerHTML = &quot;&lt;p&gt;Here's some new &lt;strong&gt;DOM&lt;/strong&gt; content.&lt;/p&gt;&quot;;
</code></pre><p><em>(Note that jQuery also uses innerHTML for DOM content manipulation).</em></p><p>It&#8217;s fast and easy &#8212; but it&#8217;s not without problems:</p><ol><li>Invalid HTML strings can be inserted which make errors difficult to spot and debug.</li><li>You may encounter browser issues if you attempt complex activities such as using or modifying nodes in the resulting DOM content.</li><li>Although it&#8217;s well supported, innerHTML is a proprietary technology and not part of the W3C DOM. It offends the standards gods.</li></ol><p>So let&#8217;s look at the DOM-based alternative:</p><pre><code>
var newpara = document.createElement(&quot;p&quot;);
var newstrong = document.createElement(&quot;strong&quot;);
newstrong.appendChild(document.createTextNode(&quot;DOM&quot;));
newpara.appendChild(document.createTextNode(&quot;Here's some new &quot;));
newpara.appendChild(newstrong);
newpara.appendChild(document.createTextNode(&quot; content.&quot;));
var container = document.getElementById(&quot;container&quot;);
container.appendChild(newpara);
</code></pre><p>Nasty. It&#8217;s three times longer, slower to execute and still prone to human error.<div
id='div-gpt-ad-1328644474660-10' style='width:728px; height:90px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1328644474660-10'); });</script> </div></p><p>Several years ago I devised by own solution, <a
href="http://www.optimalworks.net/resources/betterinnerhtml/">BetterInnerHTML</a>, which loaded an HTML string as XML, recursed the structure and inserted appropriate nodes into the DOM. It worked, but I was never totally happy with performance or issues such as HTML entities.</p><p>Fortunately, Joe Stelmach has devised an alternative. It&#8217;s a small standalone utility named <a
href="https://github.com/joestelmach/laconic">Laconic</a> which uses a logical JavaScript notation to map directly to HTML, e.g.</p><pre><code>
$.el.p(
	&quot;Here's some new &quot;,
	$.el.strong(&quot;DOM&quot;),
	&quot; content.&quot;
).appendTo(document.getElementById(&quot;container&quot;));
</code></pre><p>Attributes are supported using object literal notation:</p><pre><code>
// produce &lt;div class=&quot;example&quot;&gt;&lt;div&gt;Content&lt;/div&gt;&lt;/div&gt;
$.el.div(
	{ &quot;class&quot;: &quot;example&quot;},
	$.el.div(&quot;Content&quot;)
);
</code></pre><p>I like it. While innerHTML remains the best option for quick and dirty DOM content generation, Laconic will be useful in those odd situations when it fails to work as expected.</p><p>For more information and downloads, refer to:</p><ul><li><a
href="https://github.com/joestelmach/laconic">Laconic on GitHub</a></li><li><a
href="http://joestelmach.github.com/laconic/">Laconic example page</a></li></ul> <span
id="pty_trigger"></span><div
style='padding:20px 0px 50px 0px;'><div
style='float:left;padding-left:40px;'><div
id='div-gpt-ad-1335489406190-0' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-0'); });</script> </div></div><div
style='float:right;padding-right:40px;'><div
id='div-gpt-ad-1335489406190-1' style='width:300px; height:100px;'> <script type='text/javascript'>googletag.cmd.push(function() { googletag.display('div-gpt-ad-1335489406190-1'); });</script> </div></div><div
style='clear:both'></div></div><div
style='clear:both'></div><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=S_4WujyCif0:7GvuhSs-Wts:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=S_4WujyCif0:7GvuhSs-Wts:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SitepointFeed?a=S_4WujyCif0:7GvuhSs-Wts:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SitepointFeed?i=S_4WujyCif0:7GvuhSs-Wts:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/SitepointFeed/~4/S_4WujyCif0" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://www.sitepoint.com/laconic-javascript-dom-content-generation/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://www.sitepoint.com/laconic-javascript-dom-content-generation/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=laconic-javascript-dom-content-generation</feedburner:origLink></item> </channel> </rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using memcached
Database Caching 29/31 queries in 0.046 seconds using memcached
Object Caching 3188/3188 objects using memcached

Served from: www.sitepoint.com @ 2012-05-15 09:00:59 -->

