<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jeremy Smyth's Blog &#187; Web</title>
	<atom:link href="http://jeremysmyth.com/category/web/feed/" rel="self" type="application/rss+xml" />
	<link>http://jeremysmyth.com</link>
	<description></description>
	<lastBuildDate>Sun, 04 Jul 2010 07:10:51 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Accessibility: HTML Keyboard Shortcuts with &#8220;accesskey&#8221;</title>
		<link>http://jeremysmyth.com/2010/03/29/accessibility-keyboard-shortcuts-on-the-web-with-accesskey/</link>
		<comments>http://jeremysmyth.com/2010/03/29/accessibility-keyboard-shortcuts-on-the-web-with-accesskey/#comments</comments>
		<pubDate>Mon, 29 Mar 2010 09:59:22 +0000</pubDate>
		<dc:creator>Jeremy Smyth</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://jeremysmyth.com/?p=237</guid>
		<description><![CDATA[
function showKeys() {
	if (document.styleSheets) {
		var s = document.styleSheets[0];
		var l = s.cssRules.length;
		s.insertRule("[accesskey]:after {font-weight: 700; border-bottom: 1px blue dotted; content: '[' attr(accesskey) ']';}", l);
	} 
}

Accessibility is a hot topic on the web, and there are many emerging standards to help move in an accessible direction. We have CSS media types, alternative web pages with simpler navigation and [...]]]></description>
			<content:encoded><![CDATA[<p><script language="Javascript1.2">
function showKeys() {
	if (document.styleSheets) {
		var s = document.styleSheets[0];
		var l = s.cssRules.length;
		s.insertRule("[accesskey]:after {font-weight: 700; border-bottom: 1px blue dotted; content: '[' attr(accesskey) ']';}", l);
	} 
}
</script></p>
<p>Accessibility is a hot topic on the web, and there are many emerging standards to help move in an accessible direction. We have CSS media types, alternative web pages with simpler navigation and high-contrast styling, <tt>alt</tt> and <tt>title</tt> tags, and the general move away from mixing style with substance.</p>
<p>Along with all of this, we have the relatively old standard of using the <tt>accesskey</tt> attribute on invokeable elements such as hyperlinks and form inputs. This allows us to attach a keyboard shortcut to elements in our webpage.</p>
<p>Unfortunately, this isn&#8217;t a widely used, or easily implemented standard. Although the accesskey attribute is widely supported, only one commonly-used browser (Opera) at the time of writing provides an easy way for users to see what accesskeys are enabled on a given site, and there is no widely-accepted standard for choosing which accesskeys perform which function.</p>
<p>However, with a little jiggery-pokery we can implement a simple way to show accesskeys on demand:</p>
<div style="width: 90%; border: 1px dashed gray; margin-left: auto; margin-right: auto; padding: 8px;">
<input type="button" value="Show access keys" onclick="showKeys()" style="float: right;" />
<p><a href="http://jeremysmyth.com/2010/03/29/accessibility-keyboard-shortcuts-on-the-web-with-accesskey/"     title="Link to this post"  accesskey="9"><br />
This link</a> will bring you to this post&#8217;s permalink, and can be actuated with the accesskey &#8220;9&#8243;; in Firefox, you hold alt-shift and press 9. </p>
</div>
<p />
<p>The code for the above is pretty simple. First, the button:</p>
<pre>
<div class="codesnip-container" >
<div class="html4strict codesnip" style="font-family:monospace;"><span class="sc2">&lt;<a href="http://december.com/html/4/element/input.html"><span class="kw2">input</span></a> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;button&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;Show access keys&quot;</span> </span>
<span class="sc2"> &nbsp; &nbsp; &nbsp; <span class="kw3">onclick</span><span class="sy0">=</span><span class="st0">&quot;showKeys()&quot;</span> <span class="kw3">style</span><span class="sy0">=</span><span class="st0">&quot;float: right;&quot;</span> <span class="sy0">/</span>&gt;</span></div>
</div>
</pre>
<p>The hyperlink itself (abbreviated):</p>
<pre>
<div class="codesnip-container" >
<div class="html4strict codesnip" style="font-family:monospace;"><span class="sc2">&lt;<a href="http://december.com/html/4/element/a.html"><span class="kw2">a</span></a> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;http://jeremysmyth.com/....&quot;</span> </span>
<span class="sc2"> &nbsp; &nbsp; &nbsp; <span class="kw3">title</span><span class="sy0">=</span><span class="st0">&quot;Link to this post&quot;</span> </span>
<span class="sc2"> &nbsp; &nbsp; &nbsp; <span class="kw3">accesskey</span><span class="sy0">=</span><span class="st0">&quot;9&quot;</span>&gt;</span>This link<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/a.html"><span class="kw2">a</span></a>&gt;</span> 
will bring you...</div>
</div>
</pre>
<p>Finally, the javascript:</p>
<pre>
<div class="codesnip-container" >
<div class="javascript codesnip" style="font-family:monospace;"><span class="kw2">function</span> showKeys<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>document.<span class="me1">styleSheets</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> sheet <span class="sy0">=</span> document.<span class="me1">styleSheets</span><span class="br0">&#91;</span>0<span class="br0">&#93;</span><span class="sy0">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> len <span class="sy0">=</span> sheet.<span class="me1">cssRules</span>.<span class="me1">length</span><span class="sy0">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// reformatted to fit</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sheet.<span class="me1">insertRule</span><span class="br0">&#40;</span><span class="st0">&quot;[accesskey]:after {&quot;</span> <span class="sy0">+</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;font-weight: 700; &quot;</span> <span class="sy0">+</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;border-bottom: 1px blue dotted; &quot;</span> <span class="sy0">+</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;content: '[' attr(accesskey) ']';}&quot;</span> <span class="sy0">,</span> len<span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> 
<span class="br0">&#125;</span></div>
</div>
</pre>
<p>Clicking on the button calls the &#8220;showKeys()&#8221; function in the Javascript script block, which adds a style to the current stylesheet. The style automatically styles elements with the &#8220;accesskey&#8221; attribute, adding the value of that attribute after the element itself.
</p>
<p>Put simply, it adds a styled [9] after the hyperlink, because (1) it has the &#8220;accesskey&#8221; attribute, and secondly, the &#8220;9&#8243; is the value of that attribute, as calculated by the <tt>attr()</tt> function.</p>
<p><em style="font-style: italic; font-size: 90%;">Note: The above Javascript won&#8217;t currently work in Internet Explorer; for that, you&#8217;d need Microsoft&#8217;s <a href="http://msdn.microsoft.com/en-us/library/aa358796%28VS.85%29.aspx" title="Microsoft StyleSheet reference">addRule</a> function rather than the standards-compliant <a href="http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleSheet" title="W3 StyleSheet standards site">insertRule</a> I&#8217;ve used.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://jeremysmyth.com/2010/03/29/accessibility-keyboard-shortcuts-on-the-web-with-accesskey/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Feature requests: discuss, implement, or reject/deny?</title>
		<link>http://jeremysmyth.com/2010/03/23/feature-requests-discuss-implement-or-rejectdeny/</link>
		<comments>http://jeremysmyth.com/2010/03/23/feature-requests-discuss-implement-or-rejectdeny/#comments</comments>
		<pubDate>Tue, 23 Mar 2010 19:12:13 +0000</pubDate>
		<dc:creator>Jeremy Smyth</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Feature Requests]]></category>

		<guid isPermaLink="false">http://jeremysmyth.com/?p=215</guid>
		<description><![CDATA[I work in another publicly accessible community, where bug reports and feature requests are happily solicited from the userbase.
We have thousands of open idea requests (the codebase is nearing 20 years old), and close only a sizeable fraction of those opened regularly.
From our perspective, the idea requests are welcome, but not all of them are [...]]]></description>
			<content:encoded><![CDATA[<p>I work in another publicly accessible community, where bug reports and feature requests are happily solicited from the userbase.</p>
<p>We have <em>thousands</em> of open idea requests (the codebase is nearing 20 years old), and close only a sizeable fraction of those opened regularly.</p>
<p>From our perspective, the idea requests are welcome, but not all of them are actionable; some are brilliant, and are implemented immediately because they work well with our vision; some are entirely incompatible and are closed/denied.</p>
<p>The majority fit in between; they&#8217;re ideas that would work with a bit of tweaking, or a bit of thought, but aren&#8217;t necessarily on the primary development roadmap, so don&#8217;t get our attention immediately. Nor do they warrant closing, because they are relevant, merely not timely or important.</p>
<p>Because our developers have their own ideas, their own neverending todo lists, we treat the open idea pile more as inspiration than as a roadmap. There&#8217;s very much a feeling of &#8220;we&#8217;ll get to it when we&#8217;ve run out of other things to do&#8221;, but this never happens in practice.</p>
<p>I know it&#8217;s a cop-out not to choose one or the other, but I think it&#8217;s a normal thing to have to choose between two equally bad things in a public forum like this: either responding to most feature requests with a &#8220;denied&#8221;, and so risk upsetting the folk who love the community enough to contribute with their own ideas; or leave some of them dangling because they&#8217;re not immediately and obviously wrong, but to do something worthwhile with them takes more time and effort than the idea deserves<em> right now</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeremysmyth.com/2010/03/23/feature-requests-discuss-implement-or-rejectdeny/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML: Title Tooltips and Alt text</title>
		<link>http://jeremysmyth.com/2010/03/18/html-title-tooltips-and-alt-text/</link>
		<comments>http://jeremysmyth.com/2010/03/18/html-title-tooltips-and-alt-text/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 19:11:18 +0000</pubDate>
		<dc:creator>Jeremy Smyth</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[XHTML]]></category>

		<guid isPermaLink="false">http://jeremysmyth.com/?p=227</guid>
		<description><![CDATA[Sadly, another one for the Internet Explorer Vs. Firefox debate.
It&#8217;s pretty well known that most browsers will display a tooltip of sorts when you hover over an image. The alt attribute of the img tag gives rise to that, in pretty much all places.
Lesser known is the title attribute, which is supposed to give the [...]]]></description>
			<content:encoded><![CDATA[<p>Sadly, another one for the Internet Explorer Vs. Firefox debate.</p>
<p>It&#8217;s pretty well known that most browsers will display a tooltip of sorts when you hover over an image. The <tt>alt</tt> attribute of the <tt>img</tt> tag gives rise to that, in pretty much all places.</p>
<p>Lesser known is the <tt>title</tt> attribute, which is <i>supposed</i> to give the tooltip; the <tt>alt</tt> attribute might do that as a side-effect if <tt>title</tt> isn&#8217;t there, but it&#8217;s just that: a side-effect. The <tt>alt</tt> attribute is really there to give browsers that aren&#8217;t displaying images (or screenreaders that can&#8217;t see them anyway) some idea of what the image is.</p>
<p>This separation of concerns is somewhat of a problem when it comes to image maps: in image maps, the <tt>alt</tt> text for the <tt>area</tt> elements is there for similar reasons, to show what options are there when the image isn&#8217;t there. The <tt>title</tt> attribute is there for the tooltip, as ever.</p>
<p>However, if both alt and title are there, Internet Explorer shows the alt text as a tooltip, where Firefox will show the title text. Although they serve very different functions, a conscientious web developer is forced to keep them identical, or risk causing problems for the non-standards-compliant behaviour of Internet Explorer.</p>
<p>Of course, <tt>title</tt> will still work in other places, for example on images or even links:</p>
<div class="codesnip-container" >
<div class="html4strict codesnip" style="font-family:monospace;"><span class="sc2">&lt;<a href="http://december.com/html/4/element/a.html"><span class="kw2">a</span></a> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;mypage.html&quot;</span> <span class="kw3">title</span><span class="sy0">=</span><span class="st0">&quot;My lovely page!&quot;</span>&gt;</span>My Page<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/a.html"><span class="kw2">a</span></a>&gt;</span></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://jeremysmyth.com/2010/03/18/html-title-tooltips-and-alt-text/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Delving into the XHTML 1.1 DTD</title>
		<link>http://jeremysmyth.com/2010/03/16/delving-into-the-xhtml-1-1-dtd/</link>
		<comments>http://jeremysmyth.com/2010/03/16/delving-into-the-xhtml-1-1-dtd/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 15:11:52 +0000</pubDate>
		<dc:creator>Jeremy Smyth</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[DOCTYPE]]></category>
		<category><![CDATA[DTD]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[XHTML]]></category>

		<guid isPermaLink="false">http://jeremysmyth.com/?p=217</guid>
		<description><![CDATA[So, you&#8217;re looking at the top of a web page&#8217;s source code, and you see something like this:


&#60;!DOCTYPE html PUBLIC &#34;-//W3C//DTD XHTML 1.1//EN&#34; 
 &#160; &#34;http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd&#34;&#62;


What&#8217;s the relationship between that and the actual code in the web page?
Well, a DOCTYPE tag declares what document type this webpage is, by formally specifying a Document Type Descriptor [...]]]></description>
			<content:encoded><![CDATA[<p>So, you&#8217;re looking at the top of a web page&#8217;s source code, and you see something like this:</p>
<pre>
<div class="codesnip-container" >
<div class="html4strict codesnip" style="font-family:monospace;"><span class="sc0">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.1//EN&quot; </span>
<span class="sc0"> &nbsp; &quot;http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd&quot;&gt;</span></div>
</div>
</pre>
<p>What&#8217;s the relationship between that and the actual code in the web page?</p>
<p>Well, a DOCTYPE tag declares what <em>document type</em> this webpage is, by formally specifying a <em>Document Type Descriptor</em> (that&#8217;s what the &#8220;dtd&#8221; in the filename and in the declaration means). This is the formal specification, written in its own computer language, used to define legal dialects of languages descended from SGML. Most predominantly, this includes languages like HTML 4.01 and XHTML. Hence this walkthrough.</p>
<p>In our specific case, it references a specification for XHTML, which is a modular XML-expressed version of HTML. Let&#8217;s look inside.</p>
<p>Firstly, if we look in the declaration, we see the link &#8220;<a href="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">&#8220;http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd&#8221;</a> which, if you download it, shows the DTD itself. For XHTML, this is a relatively short document; the specification largely consists of modules, referenced from this document. Let&#8217;s have a look.</p>
<p>Within the DTD, you&#8217;ll see this section (around line 121):</p>
<pre>
<div class="codesnip-container" >
<div class="html4strict codesnip" style="font-family:monospace;"><span class="sc-1">&lt;!-- Text Module (Required) &nbsp;..................................... --&gt;</span>
<span class="sc2">&lt;!ENTITY % xhtml-<span class="kw3">text</span>.module <span class="st0">&quot;INCLUDE&quot;</span> &gt;</span>
<span class="sc2">&lt;!<span class="br0">&#91;</span>%xhtml-<span class="kw3">text</span>.module;<span class="br0">&#91;</span></span>
<span class="sc2">&lt;!ENTITY % xhtml-<span class="kw3">text</span>.mod</span>
<span class="sc2"> &nbsp; &nbsp; PUBLIC <span class="st0">&quot;-//W3C//ELEMENTS XHTML Text 1.0//EN&quot;</span></span>
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-text-1.mod&quot;</span> &gt;</span>
%xhtml-text.mod;]]&gt;</div>
</div>
</pre>
<p>This defines a module to be included, which itself is a technically part of the DTD as it is INCLUDEd.</p>
<p>If you navigate to the included module, <a href="http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-text-1.mod">&#8220;http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-text-1.mod&#8221;</a>, you&#8217;ll see a further set of INCLUDEd items, for example:</p>
<pre>
<div class="codesnip-container" >
<div class="html4strict codesnip" style="font-family:monospace;"><span class="sc2">&lt;!ENTITY % xhtml-inlstruct.module <span class="st0">&quot;INCLUDE&quot;</span> &gt;</span>
<span class="sc2">&lt;!<span class="br0">&#91;</span>%xhtml-inlstruct.module;<span class="br0">&#91;</span></span>
<span class="sc2">&lt;!ENTITY % xhtml-inlstruct.mod</span>
<span class="sc2"> &nbsp; &nbsp; PUBLIC <span class="st0">&quot;-//W3C//ELEMENTS XHTML Inline Structural 1.0//EN&quot;</span></span>
<span class="sc2"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;xhtml-inlstruct-1.mod&quot;</span> &gt;</span>
%xhtml-inlstruct.mod;]]&gt;</div>
</div>
</pre>
<p>This entry includes the inline structural elements br and span, and further down the document we have more included modules containing inline phrasal elements (em, strong etc.), block structural (p and div), and block phrasal (h1, h2 etc.).</p>
<p>Try them:</p>
<ul>
<li> <a href="http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-inlstruct-1.mod">xhtml-inlstruct-1.mod</a>
<li> <a href="http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-inlphras-1.mod">xhtml-inlphras-1.mod</a>
<li> <a href="http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-blkstruct-1.mod">xhtml-blkstruct-1.mod</a>
<li> <a href="http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-blkphras-1.mod">xhtml-blkphras-1.mod</a>
</ul>
<p>In each, you&#8217;ll see the definitions for tags such as p, div, code, strong, em and so on.</p>
<p>For comparison, have a look at the HTML 4.01 DTD, which you&#8217;ll be able to follow using the DOCTYPE:</p>
<pre>
<div class="codesnip-container" >
<div class="html4strict codesnip" style="font-family:monospace;"><span class="sc0">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01//EN&quot;</span>
<span class="sc0"> &nbsp; &quot;http://www.w3.org/TR/html4/strict.dtd&quot;&gt;</span></div>
</div>
</pre>
<p>&#8230;and linked to from here: <a href="http://www.w3.org/TR/html4/strict.dtd">http://www.w3.org/TR/html4/strict.dtd</a>. As you&#8217;ll see, it&#8217;s not quite modular, but still contains code defining the elements (and their contents, attributes and so on) that are legal within the dialect concerned.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeremysmyth.com/2010/03/16/delving-into-the-xhtml-1-1-dtd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quality of Service: Hosting</title>
		<link>http://jeremysmyth.com/2009/10/15/quality-of-service-of-service-hosts/</link>
		<comments>http://jeremysmyth.com/2009/10/15/quality-of-service-of-service-hosts/#comments</comments>
		<pubDate>Thu, 15 Oct 2009 21:48:14 +0000</pubDate>
		<dc:creator>Jeremy Smyth</dc:creator>
				<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://jeremysmyth.com/?p=205</guid>
		<description><![CDATA[There are several useful QoS parameters, although not all are as easily measured as e.g. 99.98% uptime, which is easily derived &#8211; 99.98% of the time, your server is available. 
Some other useful metrics:

 What sort of bandwidth do they support? How about if it&#8217;s a shared pipe and they&#8217;ve multiple high-volume clients? You&#8217;re unlikely [...]]]></description>
			<content:encoded><![CDATA[<p>There are several useful QoS parameters, although not all are as easily measured as e.g. 99.98% uptime, which is easily derived &#8211; 99.98% of the time, your server is available. </p>
<p>Some other useful metrics:</p>
<ul>
<li> What sort of bandwidth do they support? How about if it&#8217;s a shared pipe and they&#8217;ve multiple high-volume clients? You&#8217;re unlikely to get an honest answer to this from the vendor.</li>
<li> If you&#8217;re on a shared host, what sort of competition for resources will you have on the box? Again, this is competitive information, so you&#8217;re unlikely to get an honest response.</li>
<li> How independent is each application? i.e. if another application on a co-hosted box loops MySQL, will your app suffer?</li>
<li> How often do they upgrade dependencies, and does that affect their 99.98% uptime?</li>
</ul>
<p>Then there are the fluffy not-entirely-QoS related hosting problems:</p>
<ul>
<li> Will they do your backups etc.?</li>
<li> How responsive are they to queries? Do they have a guaranteed response time e.g. 3 hours from first email to first response, 24/7?</li>
<li> Are they efficient? Have they resolved issues within a useful timeframe? A quick response-time is nice and feelgood, but if they don&#8217;t fix the problem, that&#8217;s not quite so good!</li>
<li> Are they patient with you when you suggest issues, but due to your own technical background are slightly off-base?</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://jeremysmyth.com/2009/10/15/quality-of-service-of-service-hosts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Representing Hierarchical data in PHP</title>
		<link>http://jeremysmyth.com/2009/08/28/representing-hierarchical-data-in-php/</link>
		<comments>http://jeremysmyth.com/2009/08/28/representing-hierarchical-data-in-php/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 17:41:42 +0000</pubDate>
		<dc:creator>Jeremy Smyth</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://jeremysmyth.com/?p=156</guid>
		<description><![CDATA[I&#8217;ve come across a lot of people having a problem when representing data from their databases; hierarchical data provides us with a particular problem when displaying the relationships and containers required.
An example of hierarchical data
As an example, let&#8217;s say you have forums within categories. The category &#8220;Web Programming&#8221; may have forums like &#8220;PHP&#8221;, &#8220;JavaScript&#8221; and [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve come across a lot of people having a problem when representing data from their databases; hierarchical data provides us with a particular problem when displaying the relationships and containers required.</p>
<h2>An example of hierarchical data</h2>
<p>As an example, let&#8217;s say you have forums within categories. The category &#8220;Web Programming&#8221; may have forums like &#8220;PHP&#8221;, &#8220;JavaScript&#8221; and so on, so we want to list each forum <em>under</em> each category. The problem here is that you&#8217;ll have:
<ul>
<li>a table for categories
<li>one for forums (with a foreign key for categories)
<li>one for posts, with a foreign key for forums
<li>and probably one for comments.
</ul>
<p>This fits quite neatly into a hierarchy: each comment belongs to a post, which belongs to a forum, which belongs to a category.</p>
<h2>Using multiple resultsets</h2>
<p>If you want to display the Categories with Forums under them in your page, one way to do this is by setting up multiple resultsets, each focusing on one level of the hierarchy. To achieve this, you&#8217;d need to get a resultset for the categories first, and then iterate over this list with another loop for your forum list.</p>
<p>The following code is an example of iterating using <em>nested queries</em>:</p>
<pre>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="re0">$cat_rs</span> <span class="sy0">=</span> <a href="http://www.php.net/mysql_query"><span class="kw3">mysql_query</span></a><span class="br0">&#40;</span><span class="st0">&quot;select id, name from categories&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="kw1">while</span><span class="br0">&#40;</span><span class="re0">$cat_row</span> <span class="sy0">=</span> <a href="http://www.php.net/mysql_fetch_array"><span class="kw3">mysql_fetch_array</span></a><span class="br0">&#40;</span><span class="re0">$cat_rs</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp;<span class="co1">// print category name from $cat_row[1]</span>
&nbsp; &nbsp; &nbsp;<span class="re0">$forum_rs</span> <span class="sy0">=</span> <a href="http://www.php.net/mysql_query"><span class="kw3">mysql_query</span></a><span class="br0">&#40;</span><span class="st0">&quot;select name... &quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">.</span> <span class="st0">&quot;from forums &quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">.</span> <span class="st0">&quot;where cat_id = '&quot;</span> <span class="sy0">.</span> <span class="re0">$cat_row</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> <span class="sy0">.</span><span class="st0">&quot;'&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp; &nbsp; &nbsp;<span class="kw1">while</span><span class="br0">&#40;</span><span class="re0">$forum_row</span> <span class="sy0">=</span> <a href="http://www.php.net/mysql_fetch_array"><span class="kw3">mysql_fetch_array</span></a><span class="br0">&#40;</span><span class="re0">$forum_rs</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//print forum stuff</span>
&nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
<p>Although this matches the hierarchical nature of the data, and is pretty straightforward and intuitive to understand, it is somewhat inefficient; it issues a select statement for each category, plus one to list the categories in the first place. If there are many categories, the page might take some time to load as all queries are issued and processed.</p>
<h2>Using a SQL <tt>JOIN</tt>: a single resultset</h2>
<p>Another way to solve the problem would be to retrieve all relevant data in a <em>single resultset</em>, and use PHP to iterate over the rows, deciding on when to print each individual section.</p>
<p>A <tt>join</tt> will give you a single recordset with the category in one column, and the forum in another, giving you many rows for a single category.</p>
<pre>
<div class="codesnip-container" >
<div class="php codesnip" style="font-family:monospace;"><span class="re0">$join_rs</span> <span class="sy0">=</span> <a href="http://www.php.net/mysql_query"><span class="kw3">mysql_query</span></a><span class="br0">&#40;</span><span class="st0">&quot;select c.id, c.name, f.name,... &quot;</span> 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">.</span> <span class="st0">&quot;from categories c inner join forums f &quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">.</span> <span class="st0">&quot;on c.id = f.cat_id &quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">.</span> <span class="st0">&quot;order by c.id&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// this line is crucial</span>
<span class="re0">$current_category</span> <span class="sy0">=</span> <span class="st0">&quot;&quot;</span><span class="sy0">;</span>
<span class="kw1">while</span><span class="br0">&#40;</span><span class="re0">$join_row</span> <span class="sy0">=</span> <a href="http://www.php.net/mysql_fetch_array"><span class="kw3">mysql_fetch_array</span></a><span class="br0">&#40;</span><span class="re0">$join_rs</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$join_row</span><span class="br0">&#91;</span>0<span class="br0">&#93;</span> <span class="sy0">!=</span> <span class="re0">$current_category</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//set up new category headings here</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$current_category</span> <span class="sy0">=</span> <span class="re0">$join_row</span><span class="br0">&#91;</span>0<span class="br0">&#93;</span><span class="sy0">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//print the forum stuff in the current category</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
<p>The PHP is a bit more complex, because you have to close divs or tables correctly, within the loop. The <tt>order by</tt> line in the above example is vital, because without it, the categories may be dotted throughout the resultset. As we want all forum data related to a single category to appear together, we want rows belonging to that category to be adjacent in the resultset. The <tt>order by</tt> clause achieves this.</p>
<p>Despite the complexity, there are still benefits to this approach. The earlier example was simple and intuitive, using nested queries for each parent element. On the other hand, in this example we&#8217;ve only issued one <tt>select</tt> statement, so the page is likely to load more quickly, given that the number of round trips to MySQL will be substantially fewer.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeremysmyth.com/2009/08/28/representing-hierarchical-data-in-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8216;Hello World&#8217; using AJAX</title>
		<link>http://jeremysmyth.com/2009/08/20/hello-world-using-ajax/</link>
		<comments>http://jeremysmyth.com/2009/08/20/hello-world-using-ajax/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 14:16:54 +0000</pubDate>
		<dc:creator>Jeremy Smyth</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://jeremysmyth.com/?p=53</guid>
		<description><![CDATA[&#8220;Asynchronous Javascript And XML&#8221; is a mouthful for a web technology that&#8217;s in wide use these days. Simply put, it lets a web page download more content without reloading the page, and relies on a magic Javascript object called an XmlHttpRequest to do the work of requesting more data in the background, so it can [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;Asynchronous Javascript And XML&#8221; is a mouthful for a web technology that&#8217;s in wide use these days. Simply put, it lets a web page download more content without reloading the page, and relies on a magic Javascript object called an XmlHttpRequest to do the work of requesting more data in the background, so it can fill in things on the page.</p>
<p>So, fiddling with AJAX, let&#8217;s do a little Hello Worlding:</p>
<p><script type='text/javascript'>
<!--
var xhr;
if (window.XMLHttpRequest){
 xhr = new XMLHttpRequest();
}
else if (window.ActiveXObject){ // in case it's IE
 xhr = new ActiveXObject("Microsoft.XMLHTTP");
 }
// set up the callback
xhr.onreadystatechange = function(){
 myDiv = document.getElementById("ajaxtest");
 if(xhr.readyState  == 4) {
 if(xhr.status  == 200){
 myDiv.style.background = "green";
 myDiv.innerHTML =  xhr.responseText;
 } else {
 myDiv.innerHTML = "Error: " + xhr.status;
 }
 }  
}
function startRequest(){
 xhr.open('GET', '/ajaxtest.php', true);
 xhr.send(null);
}
-->
</script></p>
<p>Here&#8217;s a button, that when clicked, calls the &#8220;startRequest()&#8221; function in some javascript behind the entry:</p>
<pre>
<div class="codesnip-container" >
<div class="html4strict codesnip" style="font-family:monospace;"><span class="sc2">&lt;<a href="http://december.com/html/4/element/input.html"><span class="kw2">input</span></a> <span class="kw3">onclick</span><span class="sy0">=</span><span class="st0">&quot;startRequest()&quot;</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;button&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;Hello World!&quot;</span> <span class="sy0">/</span>&gt;</span></div>
</div>
</pre>
<input onclick="startRequest()" type="button" value="Hello World!" />
<p />
<p>And here&#8217;s a div:</p>
<pre>
<div class="codesnip-container" >
<div class="html4strict codesnip" style="font-family:monospace;"><span class="sc2">&lt;<a href="http://december.com/html/4/element/div.html"><span class="kw2">div</span></a> <span class="kw3">id</span><span class="sy0">=</span><span class="st0">&quot;ajaxtest&quot;</span>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/em.html"><span class="kw2">em</span></a>&gt;</span>(although you can't see it as a separate div, 
this text will be replaced)<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/em.html"><span class="kw2">em</span></a>&gt;&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/div.html"><span class="kw2">div</span></a>&gt;</span></div>
</div>
</pre>
<div id="ajaxtest"><em>(although you can&#8217;t see it as a separate div, this text will be replaced)</em></div>
<p />
<p>Go on, watch the div text above, and click the button.</p>
<p>Here&#8217;s the javascript:</p>
<pre>
<div class="codesnip-container" >
<div class="javascript codesnip" style="font-family:monospace;"><span class="kw2">var</span> xhr<span class="sy0">;</span>
<span class="kw1">if</span> <span class="br0">&#40;</span>window.<span class="me1">XMLHttpRequest</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; xhr <span class="sy0">=</span> <span class="kw2">new</span> XMLHttpRequest<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
<span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span>window.<span class="me1">ActiveXObject</span><span class="br0">&#41;</span><span class="br0">&#123;</span> <span class="co1">// in case it's IE</span>
&nbsp; xhr <span class="sy0">=</span> <span class="kw2">new</span> ActiveXObject<span class="br0">&#40;</span><span class="st0">&quot;Microsoft.XMLHTTP&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;<span class="br0">&#125;</span>
<span class="co1">// set up the callback</span>
xhr.<span class="me1">onreadystatechange</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; myDiv <span class="sy0">=</span> document.<span class="me1">getElementById</span><span class="br0">&#40;</span><span class="st0">&quot;ajaxtest&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>xhr.<span class="me1">readyState</span> &nbsp;<span class="sy0">==</span> 4<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp; <span class="kw1">if</span><span class="br0">&#40;</span>xhr.<span class="kw3">status</span> &nbsp;<span class="sy0">==</span> <span class="nu0">200</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; &nbsp;myDiv.<span class="me1">style</span>.<span class="me1">background</span> <span class="sy0">=</span> <span class="st0">&quot;green&quot;</span><span class="sy0">;</span>
&nbsp; &nbsp;myDiv.<span class="me1">innerHTML</span> <span class="sy0">=</span> &nbsp;xhr.<span class="me1">responseText</span><span class="sy0">;</span>
&nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
&nbsp; &nbsp;myDiv.<span class="me1">innerHTML</span> <span class="sy0">=</span> <span class="st0">&quot;Error: &quot;</span> <span class="sy0">+</span> xhr.<span class="kw3">status</span><span class="sy0">;</span>
&nbsp; <span class="br0">&#125;</span>
&nbsp; <span class="br0">&#125;</span> &nbsp;
<span class="br0">&#125;</span>
<span class="kw2">function</span> startRequest<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp; xhr.<span class="kw3">open</span><span class="br0">&#40;</span><span class="st0">'GET'</span><span class="sy0">,</span> <span class="st0">'/ajaxtest.php'</span><span class="sy0">,</span> <span class="kw2">true</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp; xhr.<span class="me1">send</span><span class="br0">&#40;</span><span class="kw2">null</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></div>
</div>
</pre>
<p />
<p />Firstly, the code sets up a variable <tt>xhr</tt>, which contains the magical object. This is the <tt>XmlHttpRequest</tt> object, and is responsible for communicating from the live Javascript to the back end server.</p>
<p>The request object is first set up at the script&#8217;s execution, but the only thing we do with it is tell it what to do when its &#8220;ready state&#8221; changes; that is, when the request shifts from not initialised, to set up, to having been sent, to being in process, to completion. </p>
<p>These states are numbered 0-4 respectively. Hold that thought; we&#8217;ll use it later. Suffice to say that, on the script&#8217;s execution, we now have an otherwise anonymous function that will be called when the ready state changes.</p>
<p>Now, in order for something interesting to happen, we click the button. That kicks off <tt>startRequest()</tt>, which in turn sets up a asynchronous request to <tt>ajaxtest.php</tt>, and submits it with no parameters (that&#8217;s the <tt>null</tt>). Asynchronous means we don&#8217;t sit around waiting for a response, and that&#8217;s why we need the readystatechange callback function.</p>
<p>So, when something interesting happens to the xhr object, the ready state changes (e.g. when we get a response back after sending our request). The browser then executes the anonymous function: first, the function checks that the request is complete &#8211; remember Ready State 4 above? don&#8217;t forget the ready state changes several times per request. We only want to read the response text once, at completion. Once the function has checked the request has been successfully completed,  it then uses the xhr&#8217;s response-text to fill in the div called &#8220;ajaxtest&#8221;. </p>
<p>Et voila, we have &#8220;Hello World&#8221; in AJAX.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeremysmyth.com/2009/08/20/hello-world-using-ajax/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
