<?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>Lynk IT Blog</title>
	<atom:link href="http://www.lynkit.net/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.lynkit.net/blog</link>
	<description>Just another weblog</description>
	<lastBuildDate>Fri, 29 Jul 2011 15:50:56 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Useragent browser and OS detection PHP script</title>
		<link>http://www.lynkit.net/blog/php-useragent-browser-os-detection-script/</link>
		<comments>http://www.lynkit.net/blog/php-useragent-browser-os-detection-script/#comments</comments>
		<pubDate>Fri, 29 Jul 2011 15:19:55 +0000</pubDate>
		<dc:creator>Eck</dc:creator>
				<category><![CDATA[Content Management System]]></category>
		<category><![CDATA[How to do stuff]]></category>
		<category><![CDATA[JibberJabber]]></category>
		<category><![CDATA[Object Oriented Programming in PHP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[What were making now]]></category>

		<guid isPermaLink="false">http://www.lynkit.net/blog/?p=373</guid>
		<description><![CDATA[PHP Browser detection made easy
Useragent strings are notoriously tricky, but essential for statistic gathering, and PHP scripts to process them are few and far between, often out of date and difficult to update, or plain old inefficient. I set about writing a simple analysis script that was easy to update and had a small footprint. [...]]]></description>
			<content:encoded><![CDATA[<h3>PHP Browser detection made easy</h3>
<p>Useragent strings are notoriously tricky, but essential for statistic gathering, and PHP scripts to process them are few and far between, often out of date and difficult to update, or plain old inefficient. I set about writing a simple analysis script that was easy to update and had a small footprint. I can live with 99% accuracy for my stats, I dont need to know if a single visitor in a million uses a version of Netscape Navigator from 1994, as long as the big four are covered Im happy.</p>
<h2>XML UserAgent Search strings</h2>
<p>First off, we need an XML configuration file. Im going to call this ua.xml. The first item I want to check is whether the visitor is a bot, so I'll add a few of these first. The script works by searching for a specific string, so I'll call this attribute "search". For my own stats, I can give a name to each bot:</p>
<pre>&lt;uasearch type=<span style="color: #339966;">"os"</span>&gt;
	&lt;bot search=<span style="color: #339966;">"googlebot"</span> /&gt;
	&lt;bot search=<span style="color: #339966;">"bingbot"</span> /&gt;
	&lt;bot search=<span style="color: #339966;">"baiduspider"</span> name=<span style="color: #339966;">"Baidu"</span> /&gt;
	&lt;bot search=<span style="color: #339966;">"slurp"</span> name=<span style="color: #339966;">"Yahoo"</span> /&gt;
	&lt;bot search=<span style="color: #339966;">"msnbot"</span> name=<span style="color: #339966;">"MSN"</span> /&gt;
	&lt;bot search=<span style="color: #339966;">"jeeves"</span> name=<span style="color: #339966;">"Ask"</span> /&gt;
	&lt;bot search=<span style="color: #339966;">"teoma"</span> name=<span style="color: #339966;">"Ask"</span> /&gt;
	...</pre>
<p>Using the same methods, I need to find the Operating System and version number of the visitor. To find the version number, Im going to call the optional attribute "vsearch". If ommitted, it will use the search attribute instead. I can nest more complex searching for OSs like Windows where several versions exist, but I want a more meaningful name for them. So NT 6.1 for example becomes "WIN7".</p>
<p>In addition, I need to specify how far to look ahead for the version number after the OS string is found. The script defaults to 5 characters, but some version numbers can stretch longer than that, so I'll use a "lookahead" attribute. In the script, searching for version numbers begins immediately after the name of the OS, which works in most cases, but not with Windows, so I need to cancel this out with a "lookback" attribute. The XML below works for most browsers, but can be refined for more accurate detection of say, Linux distros:</p>
<pre>	&lt;os search=<span style="color: #339966;">"ipad"</span> name=<span style="color: #339966;">"IPAD"</span> vsearch=<span style="color: #339966;">" OS "</span> lookahead=<span style="color: #339966;">"7" </span>/&gt;
	&lt;os search=<span style="color: #339966;">"iphone"</span> name=<span style="color: #339966;">"IPHN"</span> vsearch=<span style="color: #339966;">" OS "</span> lookahead=<span style="color: #339966;">"7"</span> /&gt;
	&lt;os search=<span style="color: #339966;">"windows"</span> name=<span style="color: #339966;">"WIN"</span> lookback=<span style="color: #339966;">"0"</span>&gt;
		&lt;version search=<span style="color: #339966;">"6.1"</span> name=<span style="color: #339966;">"7"</span> /&gt;
		&lt;version search=<span style="color: #339966;">"6.0"</span> name=<span style="color: #339966;">"Vista"</span> /&gt;
		&lt;version search=<span style="color: #339966;">"5.2"</span> name=<span style="color: #339966;">"XP64"</span> /&gt;
		&lt;version search=<span style="color: #339966;">"5.1"</span> name=<span style="color: #339966;">"XP2"</span> /&gt;
		&lt;version search=<span style="color: #339966;">"XP"</span> /&gt;
		&lt;version search=<span style="color: #339966;">"5.0"</span> name=<span style="color: #339966;">"2K"</span> /&gt;
		&lt;version search=<span style="color: #339966;">"4.0"</span> name=<span style="color: #339966;">"NT"</span> /&gt;
		&lt;version search=<span style="color: #339966;">"98"</span> /&gt;
		&lt;version search=<span style="color: #339966;">"95"</span> /&gt;
		&lt;version search=<span style="color: #339966;">"CE"</span> /&gt;
	&lt;/os&gt;
	&lt;os search=<span style="color: #339966;">"macintosh"</span> name=<span style="color: #339966;">"MAC"</span> /&gt;
	&lt;os search=<span style="color: #339966;">"android"</span> name=<span style="color: #339966;">"ANDR"</span> /&gt;
	&lt;os search=<span style="color: #339966;">"google desktop"</span> name=<span style="color: #339966;">"GD"</span> /&gt;
	&lt;os search=<span style="color: #339966;">"fedora"</span> name=<span style="color: #339966;">"LXFED"</span> lookahead=<span style="color: #339966;">"7"</span> /&gt;
	&lt;os search=<span style="color: #339966;">"linux"</span> name=<span style="color: #339966;">"LX"</span> lookahead=<span style="color: #339966;">"7"</span> /&gt;
	&lt;os search=<span style="color: #339966;">"java"</span> lookagead=<span style="color: #339966;">"6"</span> /&gt;
	&lt;os search=<span style="color: #339966;">"symbian"</span> lookagead=<span style="color: #339966;">"6"</span> /&gt;</pre>
<p>Add in more obscure OS's as required. The last thing is to detect the users browser. The big four are covered here, with a fallback for unknown webkit based browsers, but if I did want to know more about that time travelling Netscape user from 1994, I could add an extra trap in the XML, avoiding the PHP altogether.</p>
<pre>	&lt;browser search=<span style="color: #339966;">"MSIE"</span> name=<span style="color: #339966;">"IE"</span> /&gt;
	&lt;browser search=<span style="color: #339966;">"Firefox"</span> name=<span style="color: #339966;">"FF"</span> /&gt;
	&lt;browser search=<span style="color: #339966;">"Chrome"</span> name=<span style="color: #339966;">"CH"</span> /&gt;
	&lt;browser search=<span style="color: #339966;">"Safari"</span> name=<span style="color: #339966;">"SF"</span> /&gt;
	&lt;browser search=<span style="color: #339966;">"Webkit"</span> name=<span style="color: #339966;">"WK"</span> /&gt;</pre>
<p>Again, lookahead can be tweaked here for more accurate version numbers. For my purposes, just the major revisions are needed. For example, "FF36" is enough to tell me the user is using Firefox version 3.6. I dont need toknow if its Version 3.6.1 or 3.6.8. If you do, add in the attribute <em>lookahead="7"</em>. Finish up the XML with:</p>
<pre>&lt;/uasearch&gt;</pre>
<h2>PHP to parse useragent string</h2>
<p>Im going to build a new class for handling this called UserAgent. Later, I may add statistical analysis routines to it and other whizzy functions for IP locations and such like, but for now we will just parse the UserAgent string using the XML settings above.</p>
<pre><span style="color: #ff0000;">&lt;?php</span>
<span style="color: #339966;">class </span>UserAgent {
	<span style="color: #339966;">public </span>$UA;

	<span style="color: #339966;">public </span><span style="color: #3366ff;">function </span>__construct() {
		<span style="color: #3366ff;">$this</span>-&gt;UA = <span style="color: #3366ff;">$_SERVER</span>[<span style="color: #ff0000;">'HTTP_USER_AGENT'</span>];
	}</pre>
<p>Because Im using an external XML file for the search configs, I need a handler to convert it to an array. I'll use one I have lying around, I dont take any credit for this function, I found it lying around on the web somewhere, but its damn useful:</p>
<div style="overflow: auto;">
<pre style="width: 1000px;">	<span style="color: #339966;">public </span><span style="color: #339966;">static </span><span style="color: #3366ff;">function </span>xml2array($xml) {
		$xmlary = <span style="color: #3366ff;">array</span>();
		$reels = <span style="color: #ff0000;">'/&lt;(\w+)\s*([^\/&gt;]*)\s*(?:\/&gt;|&gt;(.*)&lt;\/\s*\\1\s*&gt;)/s'</span>;
		$reattrs = <span style="color: #ff0000;">'/(\w+)=(?:"|\')([^"\']*)(:?"|\')/'</span>;
		<span style="color: #3366ff;">preg_match_all</span>($reels, $xml, $elements);

		<span style="color: #339966;">foreach</span>($elements[<span style="color: #ff6600;">1</span>] <span style="color: #3366ff;">as </span>$ie =&gt; $xx) {
			$xmlary[$ie][<span style="color: #ff0000;">"name"</span>] = $elements[<span style="color: #ff6600;">1</span>][$ie];

			<span style="color: #339966;">if</span>($attributes = <span style="color: #3366ff;">trim</span>($elements[<span style="color: #ff6600;">2</span>][$ie])) {
				<span style="color: #3366ff;">preg_match_all</span>($reattrs, $attributes, $att);
				<span style="color: #339966;">foreach</span>($att[<span style="color: #ff0000;">1</span>] <span style="color: #339966;">as </span>$ia =&gt; $xx) $xmlary[$ie][<span style="color: #ff0000;">"attributes"</span>][$att[<span style="color: #ff0000;">1</span>][$ia]] = $att[<span style="color: #ff6600;">2</span>][$ia];

				$cdend = <span style="color: #3366ff;">strpos</span>($elements[<span style="color: #ff0000;">3</span>][$ie], <span style="color: #ff0000;">"&lt;"</span>); 				<span style="color: #339966;">if</span>($cdend &gt; <span style="color: #ff6600;">0</span>) $xmlary[$ie][<span style="color: #ff0000;">"text"</span>] = <span style="color: #3366ff;">substr</span>($elements[<span style="color: #ff0000;">3</span>][$ie], <span style="color: #ff0000;">0</span>, $cdend - <span style="color: #ff0000;">1</span>);

				<span style="color: #339966;">if</span>(<span style="color: #3366ff;">preg_match</span>($reels, $elements[<span style="color: #ff0000;">3</span>][$ie])) $xmlary[$ie][<span style="color: #ff0000;">"elements"</span>] = <span style="color: #3366ff;">self</span>::xml2array($elements[<span style="color: #ff0000;">3</span>][$ie]);
				<span style="color: #339966;">elseif</span>($elements[<span style="color: #ff0000;">3</span>][$ie]) $xmlary[$ie][<span style="color: #ff0000;">"text"</span>] = $elements[<span style="color: #ff0000;">3</span>][$ie];
			}
		}

	        <span style="color: #339966;">return </span>$xmlary;
	}</pre>
</div>
<p>Since were parsing the useragent, we may as well search for the visitors language settings. I dont need this to be spot on so the code is crude, and IE lower than version 9.0 doesnt send any language data at all, but its better than nothing:</p>
<pre>	<span style="color: #339966;">public </span><span style="color: #3366ff;">function </span>lang($ua) {
		<span style="color: #ffcc00;">//Detect Language</span>
		$ua = <span style="color: #3366ff;">str_replace</span>(<span style="color: #ff0000;">")"</span>, <span style="color: #ff0000;">";"</span>, $ua);
		$parts = <span style="color: #3366ff;">explode</span>(<span style="color: #ff0000;">";"</span>, $ua);
		<span style="color: #339966;">foreach</span>($parts as $p) {
			$p = <span style="color: #3366ff;">trim</span>($p);
			<span style="color: #339966;">if</span>(<span style="color: #3366ff;">strlen</span>($p)===<span style="color: #ff0000;">5</span>&amp;&amp;<span style="color: #3366ff;">strpos</span>($p, <span style="color: #ff0000;">'-'</span>)) <span style="color: #339966;">return </span><span style="color: #3366ff;">strtoupper</span>(<span style="color: #3366ff;">substr</span>($p,<span style="color: #ff0000;">0</span>,<span style="color: #ff0000;">2</span>));
		}
		<span style="color: #339966;">return </span><span style="color: #3366ff;">false</span>;
	}</pre>
<p>The only thing left is to parse the useragent string using the XML settings from earlier to detect the browser and OS. I figured the easiest way was to simplify the data, remove all of the irrelevant fluff that browsers sometimes add on, and then present the important stuff in a simple to use array. Heres the result:</p>
<div style="overflow: auto;">
<pre style="width: 1550px;">	<span style="color: #339966;">public </span><span style="color: #3366ff;">function </span>detect($xmlfile = <span style="color: #ff0000;">"ua.xml"</span>, $vsep = <span style="color: #ff0000;">''</span>) {
		<span style="color: #339966;">if</span>(!$xml = <span style="color: #3366ff;">$this</span>-&gt;xml2array(<span style="color: #3366ff;">file_get_contents</span>($xmlfile))) <span style="color: #339966;">return </span><span style="color: #3366ff;">array</span>();
		$ua = <span style="color: #3366ff;">strtolower</span>(<span style="color: #3366ff;">$this</span>-&gt;UA);
		$data = <span style="color: #3366ff;">array</span>();
		<span style="color: #339966;">foreach </span>($xml as $atts) {
			<span style="color: #339966;">foreach</span>($atts[<span style="color: #ff0000;">'elements'</span>] as $xml) {
				<span style="color: #339966;">if</span>(<span style="color: #3366ff;">isset</span>($xml[<span style="color: #ff0000;">'attributes'</span>][<span style="color: #ff0000;">'lookahead'</span>]) &amp;&amp; <span style="color: #3366ff;">intval</span>($xml[<span style="color: #ff0000;">'attributes'</span>][<span style="color: #ff0000;">'lookahead'</span>])) $lookahead = <span style="color: #3366ff;">intval</span>($xml[<span style="color: #ff0000;">'attributes'</span>][<span style="color: #ff0000;">'lookahead'</span>]); <span style="color: #339966;">else </span>$lookahead =<span style="color: #ff0000;"> 5</span>; <span style="color: #ffcc00;">//Number of chars to search</span>
				<span style="color: #339966;">if</span>(<span style="color: #3366ff;">isset</span>($xml[<span style="color: #ff0000;">'attributes'</span>][<span style="color: #ff0000;">'lookback'</span>])) $lookback = <span style="color: #3366ff;">intval</span>($xml[<span style="color: #ff0000;">'attributes'</span>][<span style="color: #ff0000;">'lookback'</span>]); <span style="color: #339966;">else </span>$lookback = <span style="color: #ff0000;">1</span>; <span style="color: #ffcc00;">//Disable or enable lookback</span>
				$xml[<span style="color: #ff0000;">'name'</span>] = <span style="color: #3366ff;">strtolower</span>($xml[<span style="color: #ff0000;">'name'</span>]);
				<span style="color: #339966;">if</span>(!<span style="color: #3366ff;">isset</span>($data[$xml[<span style="color: #ff0000;">'name'</span>]]) &amp;&amp; !<span style="color: #3366ff;">isset</span>($data[<span style="color: #ff0000;">'bot'</span>])) {
					<span style="color: #339966;">if</span>($st = <span style="color: #3366ff;">stripos</span>($ua, $xml[<span style="color: #ff0000;">'attributes'</span>][<span style="color: #ff0000;">'search'</span>])) {
						$data[$xml[<span style="color: #ff0000;">'name'</span>]] = <span style="color: #3366ff;">isset</span>($xml[<span style="color: #ff0000;">'attributes'</span>][<span style="color: #ff0000;">'name'</span>])? $xml[<span style="color: #ff0000;">'attributes'</span>][<span style="color: #ff0000;">'name'</span>] : $xml['attributes']['search'];
						<span style="color: #339966;">if</span>(!<span style="color: #3366ff;">isset</span>($xml[<span style="color: #ff0000;">'elements'</span>])) {
							$vsearch = <span style="color: #3366ff;">isset</span>($xml[<span style="color: #ff0000;">'attributes'</span>][<span style="color: #ff0000;">'vsearch'</span>])? $xml[<span style="color: #ff0000;">'attributes'</span>][<span style="color: #ff0000;">'vsearch'</span>] : $xml[<span style="color: #ff0000;">'attributes'</span>][<span style="color: #ff0000;">'search'</span>];
							<span style="color: #339966;">if</span>($stv = <span style="color: #3366ff;">stripos</span>($ua, $vsearch)) {
								$data[$xml['name']] .= $vsep . <span style="color: #3366ff;">preg_replace</span>(<span style="color: #ff0000;">"/[^\d]/"</span>, <span style="color: #ff0000;">""</span>, <span style="color: #3366ff;">substr</span>($ua, ($stv+(strlen($vsearch)*$lookback)), $lookahead));
							}
						} <span style="color: #339966;">else </span>{
							<span style="color: #339966;">foreach</span>($xml[<span style="color: #ff0000;">'elements'</span>] as $el) {
								<span style="color: #339966;">if</span>(!<span style="color: #3366ff;">isset</span>($version) &amp;&amp; $el[<span style="color: #ff0000;">'name'</span>]==<span style="color: #ff0000;">"version"</span>) {
									<span style="color: #339966;">if</span>($stv = <span style="color: #3366ff;">stripos</span>($ua, $el[<span style="color: #ff0000;">'attributes'</span>][<span style="color: #ff0000;">'search'</span>])) {
										$version = <span style="color: #3366ff;">preg_replace</span>(<span style="color: #ff0000;">"/[^\d]/"</span>, <span style="color: #ff0000;">""</span>, <span style="color: #3366ff;">substr</span>($ua, ($stv+(<span style="color: #3366ff;">strlen</span>($el[<span style="color: #ff0000;">'attributes'</span>][<span style="color: #ff0000;">'search'</span>])*$lookback)), $lookahead));
										$data[$xml[<span style="color: #ff0000;">'name'</span>]] .= $vsep . <span style="color: #3366ff;">isset</span>($el[<span style="color: #ff0000;">'attributes'</span>][<span style="color: #ff0000;">'name'</span>])? $el[<span style="color: #ff0000;">'attributes'</span>][<span style="color: #ff0000;">'name'</span>] : $version;
									}
								}
							}
						}
					}
				}
			}
		}

		<span style="color: #339966;">if</span>($lang = <span style="color: #3366ff;">$this</span>-&gt;lang($ua)) $data[<span style="color: #ff0000;">'lang'</span>] = $lang;
		<span style="color: #339966;">return </span>$data;
	}

}
<span style="color: #ff0000;">?&gt;</span></pre>
</div>
<h2>Testing</h2>
<p>The script above returns an array containing anything between 0 and 3 elements. A zero element array means that the script was unable to parse anything useful from the useragent string, so can be discarded or filed under "Others". This happens with unknown bots, browsers that dont pass any UA detail, or referal mechanisms designed to hide the useragent. For example, hits from links contained within a facebook page may have a useragent string containing the information "Facebookexternal" but no other relevant details. This will be discarded unless a trap is set in the XML to keep this data.</p>
<p>If the useragent carries a bot signature, the returned data will be a single element array with the key 'bot' and the search value that matches one of our XML bot traps, plus the version number if one exists. For example:</p>
<pre>Array(
	'bot' =&gt; 'Googlebot21'
)</pre>
<p>Internet Explorer pre version 9.0 user agent strings will usually return a 2 element array containing the OS and the browser detail:</p>
<pre>Array(
	'os' =&gt; 'WINXP',
	'browser' =&gt; 'IE80'
)</pre>
<p>This data is self evident, indicating an OS of Windows XP and Microsoft Internet Explorer 8.0. Useragent data from modern browsers will usually return 3 elements:</p>
<pre>Array(
	'os' =&gt; 'WINXP',
	'browser' =&gt; 'IE90',
	'lang' =&gt; 'EN'
)</pre>
<p>We now have the additional language information for the user, in this case English. If you have a typical Apache log lying around, you can run the entire script like so:</p>
<pre>$ua = <span style="color: #339966;">new </span>UserAgent();

<span style="color: #3366ff;">echo </span><span style="color: #ff0000;">'&lt;pre&gt;'</span>;
<span style="color: #339966;">foreach</span>(<span style="color: #3366ff;">file</span>(<span style="color: #ff0000;">"access.log"</span>) <span style="color: #3366ff;">as </span>$line) {
	<span style="color: #339966;">if</span>(<span style="color: #3366ff;">strlen</span>($line) &gt; <span style="color: #ff0000;">20</span>) {
		$ua-&gt;UA = <span style="color: #3366ff;">trim</span>($line);
		<span style="color: #339966;">if</span>(<span style="color: #3366ff;">count</span>($data = $ua-&gt;detect())) {
			$str = <span style="color: #3366ff;">implode</span>(<span style="color: #ff0000;">"/"</span>, $data) . <span style="color: #ff0000;">" ("</span>.<span style="color: #3366ff;">implode</span>(<span style="color: #ff0000;">"/"</span>, <span style="color: #3366ff;">array_keys</span>($data)) . <span style="color: #ff0000;">")\n"</span>;
			<span style="color: #3366ff;">echo </span>$str;
		} <span style="color: #339966;">else </span>{
			$str = <span style="color: #ff0000;">"Nothing found.\n"</span>;
			<span style="color: #3366ff;">echo </span>$str;
		}
	}
}
<span style="color: #3366ff;">echo </span><span style="color: #ff0000;">'&lt;/pre&gt;'</span>;</pre>
<p>The result will look something like this:</p>
<pre>BING20 (bot)
MJ1213 (bot)
WINXP2/EN (os/lang)
WIN7/EN (os/lang)
YAHOO (bot)
WINVista/IE60 (os/browser)
WINXP2/IE80 (os/browser)
ANDR21/SF530/EN (os/browser/lang)
ANDR21/SF530/EN (os/browser/lang)
ANDR21/SF530/EN (os/browser/lang)
Nothing found.
Nothing found.
WIN7/IE80 (os/browser)
WIN7/IE80 (os/browser)
WIN7/IE80 (os/browser)
IPHN401/SF6531/EN (os/browser/lang)
SYMBIAN8 (os)
WIN7/FF36/EN (os/browser/lang)
WIN7/FF36/EN (os/browser/lang)
WIN7/FF36/EN (os/browser/lang)
WINVista/IE80 (os/browser)
BAIDU (bot)
JAVA14 (os)
JAVA14 (os)</pre>
<p>All of the log data is now in a nice concise and readable format ready for further processing or storage. If you use a database to record your access logs, or archive your existing logs, you will want to keep them as efficiently as possible. The above data can now be compressed further. In fact, depending on how accurate a record you need, the above can be contained in a single byte of data if for example you can live with just the major browser version and major OS version and ignore bots and language data. If you do need this, 2 bytes is plenty.</p>
<p>I use this information (and some extra Geo-IP data) to generate statistical data on website usage within our customers CMS. Heres an example:</p>
<div id="attachment_397" class="wp-caption alignnone" style="width: 708px"><a href="http://www.lynkit.net/blog/wp-content/uploads/2011/03/UA-stats1.jpg"><img class="size-full wp-image-397" title="UA-stats" src="http://www.lynkit.net/blog/wp-content/uploads/2011/03/UA-stats1.jpg" alt="Language statistics from website daily log" width="698" height="436" /></a><p class="wp-caption-text">Language statistics from website daily log</p></div>
<div id="attachment_398" class="wp-caption alignnone" style="width: 445px"><a href="http://www.lynkit.net/blog/wp-content/uploads/2011/03/UA-stats-21.jpg"><img class="size-full wp-image-398" title="UA-stats-2" src="http://www.lynkit.net/blog/wp-content/uploads/2011/03/UA-stats-21.jpg" alt="Browser and OS information" width="435" height="493" /></a><p class="wp-caption-text">Browser and OS spread</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.lynkit.net/blog/php-useragent-browser-os-detection-script/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Rockpool App Launches on iTunes</title>
		<link>http://www.lynkit.net/blog/rockpool-app-launches-on-itunes/</link>
		<comments>http://www.lynkit.net/blog/rockpool-app-launches-on-itunes/#comments</comments>
		<pubDate>Mon, 28 Mar 2011 15:05:22 +0000</pubDate>
		<dc:creator>Eck</dc:creator>
				<category><![CDATA[App Development]]></category>
		<category><![CDATA[What were making now]]></category>

		<guid isPermaLink="false">http://www.lynkit.net/blog/?p=368</guid>
		<description><![CDATA[
Over the past few weeks weve been working with Sheffield based design agency MM Design developing iPad Apps for the iTunes store. We have a dedicated website for this over at www.fingersnthumbs.com, primarily aimed at producing mobile apps for book publishers. Our first App "Rockpool" launched on iTunes this weekend. This app is a library [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.fingersnthumbs.com/theme/default/img/ipads-grey.png" alt="iPad and Android App development" style="float:right;margin:0 0 20px 20px" /></p>
<p>Over the past few weeks weve been working with Sheffield based design agency <a href="http://www.mmdesign.co.uk" target="_blank">MM Design</a> developing iPad Apps for the iTunes store. We have a dedicated website for this over at <a href="www.fingersnthumbs.com" target="_blank">www.fingersnthumbs.com</a>, primarily aimed at producing mobile apps for book publishers. Our first App "Rockpool" launched on iTunes this weekend. This app is a library of childrens books from <a href="http://www.rockpoolchildrensboks.com" target="_blank">Rockpool Childrens Books</a>.</p>
<p>Rockpool Childrens Books was founded by Stuart Trotter, the illustrator for Rupert Bear and publishes superb original content for children in traditional book form. Check out the FREE App!</p>
<p><a target="_blank" onclick="gocmd('http%3A%2F%2Fitunes.apple.com%2Fgb%2Fapp%2Frockpool%2Fid426418503%3Fmt%3D8', 'extlnkfeatured')" href="http://itunes.apple.com/gb/app/rockpool/id426418503?mt=8"><img border="0" title="Download Rockpool App on iTunes" alt="Download Rockpool App on iTunes" src="http://www.fingersnthumbs.com/theme/default/img/appstore-icon-Ltrim.gif"></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lynkit.net/blog/rockpool-app-launches-on-itunes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5 Rolls out</title>
		<link>http://www.lynkit.net/blog/html5-websites-rollout/</link>
		<comments>http://www.lynkit.net/blog/html5-websites-rollout/#comments</comments>
		<pubDate>Mon, 14 Feb 2011 15:42:53 +0000</pubDate>
		<dc:creator>Eck</dc:creator>
				<category><![CDATA[How to do stuff]]></category>
		<category><![CDATA[JibberJabber]]></category>

		<guid isPermaLink="false">http://www.lynkit.net/blog/?p=362</guid>
		<description><![CDATA[All new websites to feature HTML5
Im happy to announce that we have completed our research into the cross browser incompatibilities of HTML5, and that all new websites will be built using the stable structural elements of the new language. The official recommendation by W3C isnt expected until around May of this year, with the final [...]]]></description>
			<content:encoded><![CDATA[<h1>All new websites to feature HTML5</h1>
<p>Im happy to announce that we have completed our research into the cross browser incompatibilities of HTML5, and that all new websites will be built using the stable structural elements of the new language. The official recommendation by W3C isnt expected until around May of this year, with the final implementations being expected some time in 2012, but given that we are already developing Apps in HTML5, we just cant wait that long to move our website making procedures forward too. For interested parties, Ive listed a couple of browser inconsistencies and their remedies below.</p>
<h3>Internet Explorer</h3>
<p>When Internet Explorer encounters unknown elements (such as the ones found in HTML5) it enters them into the DOM tree in an unusual way. Rather than adding them as a child node to the immediate parent, it simply places them at the root level as a sibling rendering them unstylable with CSS. There is a remarkably simple workaround for this, provided by <a href="http://remysharp.com/2009/01/07/html5-enabling-script/" target="_blank">HTML5Shiv</a>. This works by introducing the elements to IE before the DOM has loaded. When it comes to page rendering time, the elements are known to IE and therefore can be styled in CSS. Add the following into your head section:</p>
<p><code><br />
&lt;!--[if lt IE 9]&gt;<br />
&lt;script src="http://html5shim.googlecode.com/svn/trunk/html5.js"&gt;&lt;/script&gt;<br />
&lt;![endif]--&gt;<br />
</code></p>
<h3>Firefox</h3>
<p>This presented us with a bit of a nuisance that seemed to be unique to Firefox as our pages rendered correctly in all modern versions of Safari, Opera and Chrome. None of the background styles were showing on the articles, sections, or in fact any of the new elements. Adding a border in Firebug provided the answer, in that Firefox does not render them as block level elements. Again the solution is simple. Simply add the following CSS to your normal reset stylesheets:</p>
<p><code><br />
/* Firefox block level fixes */<br />
article, section, figure, figcaption, aside, header, footer, hgroup, nav, menu	{ display:block; }<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lynkit.net/blog/html5-websites-rollout/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Microsoft CSS3 uptake in IE9 is too little too late</title>
		<link>http://www.lynkit.net/blog/microsoft-css3-uptake-in-ie9-is-too-little-too-late/</link>
		<comments>http://www.lynkit.net/blog/microsoft-css3-uptake-in-ie9-is-too-little-too-late/#comments</comments>
		<pubDate>Thu, 11 Nov 2010 09:46:13 +0000</pubDate>
		<dc:creator>Eck</dc:creator>
				<category><![CDATA[JibberJabber]]></category>

		<guid isPermaLink="false">http://www.lynkit.net/blog/?p=354</guid>
		<description><![CDATA[If I didnt know better, Id say Microsoft were deliberately holding up progress on the web. The company that arguably dragged the masses into using PCs at home with Windows 95 (Im sticking my head above the parapit here) and brought computing into the 21st century are now desperately trying to keep us back in [...]]]></description>
			<content:encoded><![CDATA[<p>If I didnt know better, Id say Microsoft were deliberately holding up progress on the web. The company that arguably dragged the masses into using PCs at home with Windows 95 (Im sticking my head above the parapit here) and brought computing into the 21st century are now desperately trying to keep us back in the 20th century. The failings of Internet Explorer 6 are the millstone around every web developers neck, its blatant disregard for web standards forces us to use two sets of markup for every website we produce. Not only do we have to do the job twice, but the IE6 version is almost always trickier and takes longer to perfect than its modern browser counterpart.</p>
<p>I dont completely blame Microsoft for this, IE6 is a technology that shipped with their operating system back in 2003, an OS so good that even now many people refuse to upgrade. Partly this is down to the disaster that was Windows Vista, but more likely that in general people are comfortable and familiar with XP, so cant see the need to upgrade their OS.</p>
<h3>Kill IE6 say Microsoft</h3>
<p>Microsoft have appointed people to kill off their old browser, whose sole job it is to bring the user base for IE6 and IE7 down to zero. Or at least thats what they say. Keeping the same OS does not stop them upgrading their browser say Microsoft, and IE7, IE8 and soon, IE9 are all freely available from the Microsoft website, so why the hold up?</p>
<p>Well, first of all you are required to download a small application that verifies that your installtion of Windows is genuine. Like the launderette washing machine in "The Young Ones" when they realise they need 50p, I can hear a deafening silence. Thats right, Microsoft want you to trust them to install a little spyware app of theirs to make sure you are not ripping them off in any way before you can have access to their latest browser. Did you get that copy of Microsoft Office Professional on a student discount? Do you really want the local bobby snooping around your house making sure everything is ship shape, even if it is?</p>
<p>By Microsofts own estimates, the share of illegal XP installations in south America and Less economically developed countries is running at around 90%. Thats a hell of a lot of IE6 users worldwide then, and an impossible task for the new Microsoft team. As if this bad situation could get worse, Microsoft developed the IE7 browser that fixed some IE6 bugs, but introduced a whole lot more. Just to show once again that they have lost none of their arrogance, IE7 took flaunting of web standards to new heights, and to prove they dont learn from past mistakes, shipped it with Vista. Thankfully for us as it turns out, Vista was widely rejected, with many people opting for a "downgrade" back to XP. PC retailers too reverted their new stock to the old OS before IE7 could take a real hold.</p>
<p>MS responded (and I use the term loosely) with what has turned out to be a decent successor to XP in Windows 7. Whats more it ships with IE8, a browser that fixes most of the bugs present in both previous versions of Internet Explorer. Web developers the world over can rejoice at last; the news is that IE finally renders pages using the same markup that every other major browser has been doing for years. Are Microsoft really taking web standards seriously?</p>
<p>Sadly not. While MS were patting themselves on the back that they had finally produced what should have been a half decent browser in IE8, the rest of the web world had moved on.</p>
<h3>HTML5 &amp; CSS3</h3>
<p>Many web developers are itching to get going with HTML5. Its not just a new generation of HTML, it completely rewrites the rules about how web pages are constructed. It has features that allow developers to place less reliance on flash and more control over the CSS to produce graphical elements within web pages. The future of web design is here, now.</p>
<p>Sadly though, history has a habit of repeating itself, and IE8 does not support HTML5 or CSS3. It looks as if IE8 is around to stay for the forseeable future so webbies stop rejoicing. The dark ages are not over and we are back to developing at least two seperate sets of markup for every site. One for the modern world and one for IE8 users. Even worse, IE6 and IE7 users are still around and still occupy a fearsome market share, so if your sites rely on this demographic, you may need three sets of markup.</p>
<h3>Internet Explorer 9</h3>
<p>When this finally appears, it features some support for HTML5 and CSS3. This is far too little, and way too late, the die is cast - Windows 7 comes with IE8 as standard and the Microsoft upgrade path still requires that they inspect your PC. Even if those South Americans upgrade their OS to an illegal version of Windows 7, theyre stuck with IE8. And so are we.</p>
<p>To see how far theyve come with IE8, take a look at the HTML5/CSS3 features table below:</p>
<table width="100%" cellspacing="0" id="compatchart">
<tr>
<th></th>
<th><img src="/img/chrome.png" alt="Google Chrome" title="Google Chrome" /></th>
<th><img src="/img/firefox.png" alt="Mozilla Firefox" title="Mozilla Firefox" /></th>
<th><img src="/img/opera.png" alt="Opera" title="Opera" /></th>
<th><img src="/img/safari.png" alt="Apple Safari" title="Apple Safari" /></th>
<th><img src="/img/ie8.png" alt="Internet Explorer" title="Internet Explorer" /></th>
</tr>
<tr>
<td colspan="6" class="title">HTML5</td>
</tr>
<tr>
<td class="label">Canvas</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">Canvas Text</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">Audio</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">Video</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">Codec support</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">Form Inputs</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/error.png" alt="Some" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">Form Attributes</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/error.png" alt="Some" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td colspan="6" class="title">CSS3 Selectors</td>
</tr>
<tr>
<td class="label">Begins with</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
</tr>
<tr>
<td class="label">Ends with</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
</tr>
<tr>
<td class="label">Empty</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">Target</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">Disabled</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td colspan="6" class="title">CSS3 Properties</td>
</tr>
<tr>
<td class="label">RGBA</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">HSLA</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">Background Size</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">Multiple bg</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">Border Image</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">Border Radius</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">Box Shadow</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">Opacity</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">Animation</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">Columns</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">Gradients</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">Reflections</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">Transforms</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">3D</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">Transitions</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
<tr>
<td class="label">FontFace</td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/tick.png" alt="Yes" /></td>
<td><img src="/img/cross.png" alt="No" /></td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.lynkit.net/blog/microsoft-css3-uptake-in-ie9-is-too-little-too-late/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Understanding DNS</title>
		<link>http://www.lynkit.net/blog/understanding-dns/</link>
		<comments>http://www.lynkit.net/blog/understanding-dns/#comments</comments>
		<pubDate>Fri, 08 Oct 2010 22:10:08 +0000</pubDate>
		<dc:creator>Eck</dc:creator>
				<category><![CDATA[How to do stuff]]></category>

		<guid isPermaLink="false">http://www.lynkit.net/blog/?p=341</guid>
		<description><![CDATA[Part one - Basic domain name settings
One of the main problems we encounter when taking over an existing domain name or website is the DNS configuration. Most people do not understand DNS, or have lost contact with "the guy that sorted it all out". Even IT professionals are often left in the dark as to [...]]]></description>
			<content:encoded><![CDATA[<h4>Part one - Basic domain name settings</h4>
<p>One of the main problems we encounter when taking over an existing domain name or website is the DNS configuration. Most people do not understand DNS, or have lost contact with "the guy that sorted it all out". Even IT professionals are often left in the dark as to how a companies DNS is configured. It may have been setup years ago, or companies are reluctant to interfere with something that works but they dont understand why or how it works. This post is intended to demystify the processes involved.</p>
<p>The domain name service was originally introduced to simplify the Internet, its purpose is to give meaningful names to series of numbers that form Internet addresses (IP addresses), and for web <em>users</em>, it works perfectly. Its much easier to remember "www.google.com" than "173.194.36.104". The tricky bit is saved for website <em>owners</em>, when you buy a shiny new domain name, it needs to be bound somehow to an IP address so that the domain name service (DNS) can fulfil its purpose and serve up your website when someone types in your domain name. It seems straightforward, you type a domain name and some behind the scenes magic fairy goes off to look for where that domain lives. However, since there are no magic fairies were going to have to understand what it is they actually do behind those scenes.</p>
<h2>Registration</h2>
<p>When you buy a domain name, you are buying a service from a "registrar", for example 123-reg is a registrar. At this point, the domain name is not configured to point at your website, in fact the only job of the registrar is to register your domain and contact details with the Internet authority. In order for your website to function, registrars also need to register the "name service" that will form the first point of call when a request for your page is made. To simplify buying a domain name, registrars simply tag their own name service onto your domain name.</p>
<h2>Name Servers</h2>
<p>Your domain name is held on a database called a "Name Server". Nameservers are a bit like like websites in some respects, they live at a particular IP address and they already have a domain name bound to that IP address. They are unlike websites in that they do not serve content, pictures or video, but records from a database containing technical information about your website. Although registrars also provide nameservers as part of the domain registration service, by default, these nameservers are configured to point back to the registrars website, some free advertising for them.</p>
<p>Nameservers are the first port of call whenever you request a website via your browser. In most cases and if you havent modified these details, this will be the name server of your registrar. However, if you have an existing website the name server details may have been modified at some point in the past.</p>
<h2>Zone records</h2>
<p>So what data do name servers actually provide? When a user types your domain name into a browser, the browser must decode the actual IP address of where your website is hosted. It cannot make a request until it knows this information.</p>
<p>To obtain it, the browser queries the nameserver to get the appropriate "zone records" that describe your domains location. Zone records are made up of text files that tell web requests where appropriate aspects of your domain live. In the case of a browser, it probably wants to know the "www" address, and so the name server returns the appropriate "A" record containing the IP address for your website. With email, these require a different type of record known as "MX" (Mail eXchanger) records. This is what makes it possible to host your email at a different location or on a different server to your website.</p>
<h2>Website</h2>
<p>For the purposes of this discussion, your website simply comprises of files (such as web pages) that reside on a hosted server somewhere on the Internet. As of now, they are "orphaned", that is, although they exist on the Internet, your domain name doesnt yet point to them and so they are unreachable.</p>
<p>To fill in the gaps, take a look at the following diagram. Work left to right starting with the registrar, then following the arrows along the process to discover the actual address of your website. There are two examples here from two different registrars. Notice the zone records for both "@" and "www", dont be confused by the "@" symbol, this does not signify email, but is the 123-reg specific "wildcard" that signifies the non-www address of your website, for example "<em>domain.com</em>" as opposed to "<em>www.domain.com</em>". It is possible then to serve two entirely different websites from "www" and non-www, although this is rarely done and is never advised. For now, ignore the MX (email) records in the diagram, we'll get to them later.</p>
<p><img src="/img/blog/DNS1.jpg" alt="Simple DNS" /></p>
<div class="wp-caption">
Note: Technically the www record is a "C" record rather than an "A" record, but this is an irrelevant detail here.
</div>
<p>According to the diagram above, if I type in www.lynkit.net into a browser, the <del datetime="2010-10-08T21:38:03+00:00">magic fairy</del> domain name service will see to it that our website reaches your screen. Which it does otherwise you wouldnt be reading this! </p>
<p>So what could possibly go wrong? As long as the correct IP addresses are entered into the zone records your website should show? Maybe not...</p>
<p><img src="/img/blog/DNS2.jpg" alt="Not so simple DNS" /></p>
<p>Here we have reconfigured the nameserver records to use a different provider. Although our domain was registered by 123-Reg, they are no longer supplying the required zone records. If you attempt to modify the zone records at 123-Reg, it will have no effect because domainmonster is now supplying these. This is the number one cause of confusion about DNS so its worth remembering. When configuring your website its best to have access to usernames and passwords for all providers in the chain so that fine tuning can take place without breaking any part of your domain. Email is usually the one to suffer in these cases.</p>
<p>So how do we fix the situation above? We could revert to the simple configuration in figure 1, or we could continue to use our third party nameservers by correcting the zone records contained there, as in the configuration illustrated below: </p>
<p><img src="/img/blog/DNS3.jpg" alt="DNS 101" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lynkit.net/blog/understanding-dns/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Get Your SEO Campaigns Right: Keywords</title>
		<link>http://www.lynkit.net/blog/get-your-seo-campaigns-right/</link>
		<comments>http://www.lynkit.net/blog/get-your-seo-campaigns-right/#comments</comments>
		<pubDate>Mon, 28 Jun 2010 12:26:06 +0000</pubDate>
		<dc:creator>Eck</dc:creator>
				<category><![CDATA[How to do stuff]]></category>
		<category><![CDATA[Sales Stuff]]></category>
		<category><![CDATA[Search Engine Optimisation]]></category>
		<category><![CDATA[PPC]]></category>
		<category><![CDATA[SEO]]></category>

		<guid isPermaLink="false">http://www.lynkit.net/blog/?p=311</guid>
		<description><![CDATA[Apart from your website navigation (see boxout), one of the first tasks is to identify your keywords by thinking about your users and what they might be expected to enter as a search term to find you. At each stage of the buying cycle, users will enter different phrases, and these can be categorised]]></description>
			<content:encoded><![CDATA[<p>Getting your search engine optimisation campaign right can be the difference between success and failure. Research shows that the top listing on Google receives 55 percent of the traffic for the term that was applied, and other sites in the top ten receive the next 40%. This shows that SEO can be a cost effective way to achieve long term success for your business. Getting it right though is less simple and there is no universal formula that can be applied to make it right, every business needs a bespoke analysis of their products, services, competitors and primary objectives so that an SEO plan can be formed to achieve those objectives.</p>
<p>The way people use the web is changing fast, and the changing landscape means that performing well in search engine rankings is becoming more of a challenge. Its a cat and mouse game with high rewards for the top performers meaning that big business will risk all to get there.</p>
<h2>How can small businesses compete?</h2>
<p>The good news is that search engines do not charge for organic listing results. Big business cannot influence the SERPS of any major search engine and so the playing field is level for businesses of all sizes. This means that your business is very much still in the game. Armed with a few insider techniques, you can significantly reduce the cost of employing an SEO specialist by carrying out a lot of research for yourself. Bigger businesses employ specialists to do this for them, but this puts them at a significant disadvantage. In almost all cases, the specialist will not be an expert in your particular field of business, and so optimising for "long tail" industry specific phrases will be difficult for them at best, if not impossible.</p>
<div class="contentbox">
<h1>Reduce Friction</h1>
<p>Before embarking on any SEO campaign, job number 1 is to ensure your sites "user experience" is not confusing, difficult or unpleasant. Define clear goals and calls to action so that your users can instantly get what they want, and that you want them to get. Website users are impatient, they have arrived at your site for some specific purpose. Maybe they want to enquire about your services, or buy a product, or download a technical manual. If they have to navigate through a dozen pages of waffle to find it, they will simply click the back button and go to the next company - your competitor. This is known as "website friction".</p>
<p>In one instance, a customer asked us why their search engine strategy was failing. Upon first look at their website, we told them to cancel their Google Pay-per-click (PPC) campaign, a saving of over £2000 per month. The result? Nothing. No decrease in sales, no decrease in enquiries. The "bounce rate" of the site was 89% (the highest weve seen), meaning that 89% of visitors were navigating away from their site within 30 seconds of arriving. Now we could begin the process of streamlining their site and embarking on a properly designed organic campaign, and they were £2000 per month richer.</p>
</div>
<h1>Smart SEO</h1>
<p>Apart from your website navigation (see boxout), one of the first tasks is to identify your keywords by thinking about your users and what they might be expected to enter as a search term to find you. At each stage of the buying cycle, users will enter different phrases, and these can be categorised as follows:</p>
<ul>
<li><strong>Navigational Search</strong>Queries that include your brand or company name</li>
<li><strong>Informational search</strong>Highly generic phrases such as "motorbike shops near me"</li>
<li><strong>Transactional Search</strong>Usually three, four or more word phrases, highly specific that identify exactly what a user wants eg: "GC-3111 Crankcase Heater Control"</li>
</ul>
<p>Each type of search relates to the stage the user is at, from research, shopping around or ready to purchase, and you must ensure that your site contains keywords that are relevant for each stage. SEO specialists often fail at transactional searches since they are highly specific, and so often concentrate on generic keywords to drive traffic to your site. This is no bad thing since users may return once theyve reached the buying stage, but this could be at the expense of potential customers that are ready to buy now. <em>It is critical to get these keywords right</em>.</p>
<h3>Identifying keywords</h3>
<p>Start by building an initial list of most obvious keywords for your industry. Take a look at your competitors sites and list a dozen or so two and three word phrases that users might search for. Take a look at your products and build a list of words that describe them both generally and specifically. Its not a good idea to focus on expressions that describe products you cannot supply, but it is a good idea to focus on products or services that have a higher profit margin, even if it is searched for less. Finally, what expressions and words are unique to your business or product? Try to categorise the expressions you have identified into <strong>Navigational</strong>, <strong>Informational</strong> and <strong>Transactional</strong>. Try to include in your list three word expressions (not including two and three letter words eg: the of, and, for etc.). Search engine users use three and four word phrases more than any other when carrying out an informational search.</p>
<p>Now that you have an initial list, you can use a keyword discovery tool to develop these further and identify new ones you may not have thought of, or discard ones that receive no traffic. Google have a keyword discovery tool at <a href="http://www.google.com/sktool/" target="_blank">http://www.google.com/sktool/</a></p>
<p>The list you have generated will form not only the basis of your SEO campaign, but any PPC campaigns you may embark on where <em>Googles Quality Score (QS)</em> can determine the difference between hundreds of pounds and thousands of pounds in PPC monthly spend.</p>
<h3>Content Optimisation</h3>
<p>You need to understand where a user arrives on your site and follow their journey through the site to the point of sale, or reach one of the goals you identified earlier. The key to SEO success is ensuring that you have visibility at each point of the journey, by using appropriate keywords for that point. Print out each page as you navigate through your site to the goal, and align the most appropriate keywords from your list with each page. Just because users who buy from you do a navigational search right before they buy, doesnt mean you should undervalue the influence of informational keywords. Their search may have begun weeks earlier with an informational search that led them to your site in the first place.<br />
Search engines are machines, they are incapable of thought. They follow a set of rules from an algorithm. Humans may be able to read your content, but that doesnt mean that search engines can, and creating pages that ticks all the boxes for the engine, might result in good rankings at the expense of a terrible user experience. The number one rule here is: Dont try to fool the engines. Modern search engines are extremely sophisticated and have already thought of all the ways site owners can trick them into ranking their site higher. Its hard enough to optimise website content as it is without running the risk of being de-listed. A good rule of thumb is to always put humans first, and the engines second, after all, receiving loads of traffic from high ranking keywords to an awful site equals disaster. Our goal is to drive qualified traffic to our site at all stages of the user journey.</p>
<h3>Keyword Proximity</h3>
<p>Read through your content, how many words did you use? 100-400 words is a good amount, but now think about how you can rewrite the content to accommodate keywords from your list. If you can repeat the keywords, even in a different order without making it unreadable to human beings, all the better. A good rule of thumb here is to optimise each page with one main keyphrase. It could be a generic phrase like "Web Design", but you can expand on this with some <em>longtail</em> keywords such as "best value web design".</p>
<p>Word proximity calculations score the words "web", "design", "best" and "value" not only as individual words, but how close they are to other words in the content. After a few repeats "Web" and "Design" become synonymous with "Web Design". To a human, this seems obvious, but as mentioned previously, engines are not human and have to try and work out what words are related to form phrases. Searches for "best value web design" will result in your site being ranked higher because the words match the search term, but the search engines are clever enough to know that "our web design services offer the best value" is a derivative of your primary keyphrase because again, "best value" is in close proximity to "web design". Suppose someone searches for "which web designer is the best value", rather than "best value web design", you have captured this too.</p>
<h3>Keyword Density</h3>
<p>We are aiming for a 2%-5% keyword saturation or <em>keyword density</em> for your keywords within the content of the web page, if you are using the Lynk CMS, there is a built-in content analysis tool that identifies amongst other things, the position and density of the most common words and prominence on the page. Unless theres a specific reason for a high keyword density score, if your percentage is any higher than this the content may become unnatural for humans to read and you run the risk of being accused of keyword spamming. Any lower and search engines may not relate your web page to the keyword you are trying to promote. Its a fine balance, but then search engine optimisation is not supposed to be easy.<br />
<div id="attachment_324" class="wp-caption alignright" style="width: 363px"><a href="http://www.lynkit.net/blog/wp-content/uploads/2010/06/SEO_scores.jpg"><img class="size-full wp-image-324 " title="SEO_scores" src="http://www.lynkit.net/blog/wp-content/uploads/2010/06/SEO_scores.jpg" alt="" width="353" height="328" /></a><p class="wp-caption-text">Table for tweaking your SEO scores on a page by page basis.</p></div></p>
<h3>Keyword Prominence</h3>
<p>Words, or more precisely keywords are measured by search engines not only by how many times they appear on a page, but how prominent they are within the page. For example a keyword placed inside a heading will be considered to have more importance than a keyword that appears within a sentence. There are more: words that appear in bold, in links or link titles, even in lists have a slightly different <em>score</em> to standard paragraph words. In some cases the difference is negligible, such as list items, but combined with others these can be powerful indicators to a search engine about what the page is describing. When rewriting your content, you should consider how you will fit keywords within these elements.</p>
<h4>Meta Title</h4>
<p>The single most important keyword placement is in the meta title. This is the title that appears in the users browser when they navigate to the page. More importantly in terms of searching, this is what will appear in the Google listings. You have about 60 characters in which to say to the buying public what is on the page, so its absolutely imperative that this title describes the page very concisely, but also contains your number one keyword for that page. </p>
<p>There is another technical consideration when devising meta titles. Its vital that your titles reflect natural navigation through your site, rather than act as a keyword vehicle. In fact, in 60 characters you need to sell your services to the public, indicate to the search engines what is on the page AND offer structural indications to the engines. The latter of these is influential in Google identifying your site as a candidate for its much revered <em>Sitelinks</em> technology. You may have seen this on some older or larger sites whereby links to internal pages are displayed immediately underneath the home page link:</p>
<p><div id="attachment_329" class="wp-caption alignnone" style="width: 581px"><a href="http://www.lynkit.net/blog/wp-content/uploads/2010/06/pickplant_sitelinks.jpg"><img src="http://www.lynkit.net/blog/wp-content/uploads/2010/06/pickplant_sitelinks.jpg" alt="Pickerings Plant sitelinks" title="pickplant_sitelinks" width="571" height="226" class="size-full wp-image-329" /></a><p class="wp-caption-text">Sitelinks appearing under the main link to websites take up lots of google space.</p></div><br />
</p>
<h3>Meta Description</h3>
<p>Meta descriptions allow you to appeal to the public via Google search listings. This forms the two lines of text that appear underneath your link. Unlike the title, the description is less important in determining site structure but should always concisely describe what is on the page it relates to. In addition, it should be an <em>excerpt</em> from the page itself and should closely match a key sentence from the page and should of course contain your primary keywords or phrase for that page. If your meta description is missing, Google will select a sentence at random, usually from the top, which may not be appropriate or contain your keywords.</p>
<h3>Accessibilty</h3>
<p>In order to appeal to search engines and humans, your on-page links should contain a title that concisely but accurately describes the page it points to. This is not only an opportunity to get more keyword exposure, by carefully crafting titles you can help users navigate your site and allow search engines to build confidence that the page title is relevant to its content.</p>
<p>This is also true for images on your website. Search engines cannot read or see images, so its important to give each image a title that describes what the image is. Appropriately titled images feature in Googles image search quite prominently and give the rest of your site more credibility for your chosen keywords.</p>
<p>Consider partially sighted visitors to your site. Users that use screen readers must be able to navigate your site and screen readers do a good job (by way of appropriate titles) of informing them where links go, or what images contain. Search engines (for the purposes of SEO) can be considered "partially sighted", so by doing this, you are also writing good index-able content.</p>
<h3>Now we can begin!</h3>
<p>Now that you have insider knowledge as to how to format your content and keywords appropriately for both human visitors and search engine spiders, the process of getting your site recognised properly by Google and the others can begin. From here on it gets technical, so <a href="http://www.lynkit.net/get-in-touch_36.html">contact us</a> about notifying Google that your site has some new and exciting changes that it ought to be aware of.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lynkit.net/blog/get-your-seo-campaigns-right/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Fast page loading essential for SEO according to Google</title>
		<link>http://www.lynkit.net/blog/fast-page-loading-essential-for-seo-according-to-google/</link>
		<comments>http://www.lynkit.net/blog/fast-page-loading-essential-for-seo-according-to-google/#comments</comments>
		<pubDate>Sat, 19 Jun 2010 14:27:45 +0000</pubDate>
		<dc:creator>Eck</dc:creator>
				<category><![CDATA[Content Management System]]></category>
		<category><![CDATA[Sales Stuff]]></category>
		<category><![CDATA[Search Engine Optimisation]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[SEO]]></category>

		<guid isPermaLink="false">http://www.lynkit.net/blog/?p=305</guid>
		<description><![CDATA[The speed at which your site loads is essential for a good ranking in Google.
In April Google posted on their official blog that website speed has become one of their 200 signals it uses in its search engine ranking algorithm. This has huge implications for Search Engine Optimisation, web design and web hosting, and means [...]]]></description>
			<content:encoded><![CDATA[<h3>The speed at which your site loads is essential for a good ranking in Google.</h3>
<p>In April Google posted on their official blog that website speed has become one of their 200 signals it uses in its search engine ranking algorithm. This has huge implications for Search Engine Optimisation, web design and web hosting, and means that choosing the right hosting and system is more important than ever before. Research conducted by Google shows that even a few tenths of a second in page load times can produce a significant drop in user activity.</p>
<p>The rub of this is that this will mean that slick looking but bloated and slow-to-load websites may counter-productive to search engine optimisation, and reduce search engine rankings, so why is it that so many websites feature home pages that require the user to "wait while loading". Flash websites, or websites that feature lots of flash are most guilty of this.</p>
<p>By using a fast hosting plan and optimised content management or ecommerce system, the operating costs can be significantly lower in other areas. For example, site speed has been used by Google to determine landing page quality for some time, so by increasing the quality score of your pages using faster loading times, you are reducing the cost per click of your PPC campaigns which can translate to vast savings in your PPC spend.</p>
<p>Website owners can directly influence their chances in the rankings by thinking carefully about the type of system and hosting plan they will deploy for their website. By understanding why websites perform and what the bottlenecks are, you are better equipped to make crucial decisions.</p>
<ol>
<li><strong>Bandwidth</strong>
<p>By far the most critical consideration in influencing site speed is bandwidth. This is affected by the infrastructure upon which a hosting server is mounted, but more importantly, how many sites are sharing the same resource. Cheap or even free web hosts use sub-par servers, usually past their sell-by date with minimal processing power, but even worse is the number of sites they host on each server. Finding a server with 1000 or more websites is not uncommon.</p>
<p>Imagine, 1000 websites are competing for the same resource as your site, that resource is a cable that connects the server to the Internet. Whilst links between hosting servers and the Internet are fast, only one can pass through this bottleneck at any one time, so your site may be forced into a queue just to get through. To make it worse, other resources on the server, such as database calls and processor actions are also part of this resource. With fast modern servers this would never be a bigger issue than the bandwidth, but then cheap hosting plans never run on fast modern servers.</p>
</li>
<li><strong>Database access</strong>
<p>Most modern systems require calls to the database for their content and settings. In most cases this is a really fast operation, databases are highly optimised and increasingly sophisticated. However, there are certain operations carried out by databases, such as large "table joins" that are inherently slow, and some systems insist on using hundreds of these operations slowing a website down considerably. In addition to this, many large hosting providers provide a seperate database server, meaning that the server where your site is hosted often isnt even in the same city, or even country as the database that controls it!. This results in not only slow database operations, but then compounds that with the problem of bandwidth as the data has to travel hundreds of miles over the internet. When considering your hosting plan, ensure that your database is on the same machine as your website.</p>
<li><strong>Disk access</strong>
<p>The fastest operation of all when it comes to influencing site speed is disk access. This is much faster than either of the other two, and so an intelligent system should use this advantage at every level. For example, a slow database operation can be carried out once and then "cached" to disk. The next time this operation is required, the system can call on the cache rather than run the query again.</p>
</li>
</ol>
<h3>So how do we compare</h3>
<h4>Benchmarking</h4>
<p><div id="attachment_309" class="wp-caption alignright" style="width: 441px"><a href="http://www.lynkit.net/blog/wp-content/uploads/2010/06/benchmark.jpg"><img src="http://www.lynkit.net/blog/wp-content/uploads/2010/06/benchmark.jpg" alt="Benchmarking results during site build" title="Benchmarking results during site build" width="431" height="339" class="size-full wp-image-309" /></a><p class="wp-caption-text">Benchmarking results during site build</p></div><br />
We spend a lot of time benchmarking and optimising our CMS so that bandwidth is minimised, and database calls are cached. Every website we produce has a "benchmarking" panel attached to it during the build, where we monitor not only every database call, but every disk call too. Database calls are cached to disk so that next time the page is called, no database operations are carried out, unless of course you have made changes in the CMS. Because the system keeps track of any changes in the backend, the front end knows to refresh the cache by calling upon the database again.</p>
<h4>Bandwidth reduction</h4>
<p>The number one problem of bandwidth is alleviated significantly by using GZip compression on all request. This means that your web page is compressed (zipped) by the server <em>before</em> it is sent to the browser for display, resulting in a significant decrease in page size. Sometimes a page can be compressed by 80% depending on the number of images displayed in the page (images are usually already compressed so cannot be squeezed any more).<br />
The effect of zipping up your page creates an additional overhead on the hosting server, in that the processor has more work to do (it has to compress your page before its sent). However, because we use the latest dual and quad core processors this is never an issue.</p>
<h4>Disk Footprint</h4>
<p>Because our CMS backend is <em>cloud</em> based, this doesnt figure at all in the disk space calculations. The frontend then, is made up of highly optimised code. If you discount the images, the total disk space occupied by the core files is around 800k, and that includes the ecommerce, news, events and downloads applications!. Compare this to say, wordpress, which weights in at a mighty 20Mb. Even without the backend files (3.5Mb) its still quite hefty. You can fit 20 Lynk CMS applications into the space of just one wordpress installation. Figure in the caching, HTTP compression and tight code operations and thats a significant saving on page load times.</p>
<h4>Need hosting?</h4>
<p>If you are interesed in hosting with us, we offer a range of options from single website hosting, discounted multi-domain hosting (eg: buy 10 hosting plans for a discounted fixed cost), managed and dedicated server hosting. All hosting plans come with a Plesk interface, Roundcube webmail, POP3, IMAP and SMTP email with SpamAssassin, PHP5 and unlimited MySQL databases. We also offer Tomcat based Java/JSP hosting.<br />
<a href="http://www.lynkit.net/get-in-touch_36.html">Contact us</a> to discuss your requirements.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lynkit.net/blog/fast-page-loading-essential-for-seo-according-to-google/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CHMOD in Linux</title>
		<link>http://www.lynkit.net/blog/chmod-in-linux/</link>
		<comments>http://www.lynkit.net/blog/chmod-in-linux/#comments</comments>
		<pubDate>Fri, 30 Apr 2010 14:32:56 +0000</pubDate>
		<dc:creator>Eck</dc:creator>
				<category><![CDATA[How to do stuff]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Sys Admin stuff]]></category>
		<category><![CDATA[chmod]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[putty]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://www.lynkit.net/blog/?p=294</guid>
		<description><![CDATA[Some Ecommerce applications such as PrestaShop have an annoying habit of locking image files upon upload. Depending on your FTP servers setup, this can result in the files being inaccessible and preventing you from downloading the files via FTP, or overwriting the files directly. In a typical Plesk environment, the files have deletion enabled which [...]]]></description>
			<content:encoded><![CDATA[<p>Some Ecommerce applications such as PrestaShop have an annoying habit of locking image files upon upload. Depending on your FTP servers setup, this can result in the files being inaccessible and preventing you from downloading the files via FTP, or overwriting the files directly. In a typical Plesk environment, the files have deletion enabled which allows you to delete the file and then re-upload them, but this is of no use if you dont have a local copy of the file, such as when the file is renamed by the application.</p>
<p>The only way to unlock these files then is to use a specialist SFTP application such as Directory Opus (our tool of choice), or login to a terminal window via SSH. If you dont have an SSH client, you can get PuTTy from <a href="http://www.putty.org/">here</a>, or our favourite is the superb <a href="http://www.ultraedit.com/">UltraEdit</a> which is not only a great text and Hex editor, but has a built-in SSH client.</p>
<h2>CHMOD</h2>
<p>For Prestashop, log into to your SSH session, cd to your domains image folder eg:</p>
<pre>
cd /var/www/vhosts/domain.com/httpdocs/img/p
</pre>
<p>Now list your files with:</p>
<pre>
ls -l
</pre>
<p>you will notice that the permissions are set to -rw------- for each file meaning that they can only be read or modified by the application that created them. We need to give them more friendly permissions and for this we use CHMOD:</p>
<pre>
chmod 644 *.jpg
</pre>
<p>Now perfom another list operation and you should see that permissions have changed to -rw-r--r-- allowing you to download or upload the files via FTP. You may want to do this with the category image folder too:</p>
<pre>
cd ../c
chmod 644 *.jpg
ls -l
</pre>
<p>For further information on using CHMOD see http://catcode.com/teachmod/</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lynkit.net/blog/chmod-in-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CP3 &#8211; content management system for agencies</title>
		<link>http://www.lynkit.net/blog/domain-management-system/</link>
		<comments>http://www.lynkit.net/blog/domain-management-system/#comments</comments>
		<pubDate>Tue, 27 Apr 2010 12:54:55 +0000</pubDate>
		<dc:creator>Eck</dc:creator>
				<category><![CDATA[Content Management System]]></category>
		<category><![CDATA[JibberJabber]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[What were making now]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[CP3]]></category>

		<guid isPermaLink="false">http://www.lynkit.net/blog/?p=277</guid>
		<description><![CDATA[CP3 is due to take over our CP2 system later this year. The main improvements focus on the user interface, making it easier to use for end users. All of the functionality from CP2 has been retained with the added improvemtn that modules are now easier to create an integrate. We have even developed a [...]]]></description>
			<content:encoded><![CDATA[<p>CP3 is due to take over our CP2 system later this year. The main improvements focus on the user interface, making it easier to use for end users. All of the functionality from CP2 has been retained with the added improvemtn that modules are now easier to create an integrate. We have even developed a rapid deployment tool that creates an entire module, including corresponding XML configuration files and accompanying classes, from a database specification, meaning that new functionality can be incorporated within seconds. Because the system and its domains are cloud based, any new functionality is instantly available (subject to permissions) within every site in the cloud!</p>
<h2>About the CP3 platform</h2>
<p>From the outset we designed CPx as a cloud based <em>domain management</em> system, with centralised control and a host of tools that befire the    long term administration of websites. For example SEO and minor content    updates becomes very simple across many websites when theyre all   managed  from one login screen. Renewals are tracked and site details   and  statistics are presented in one place.</p>
<h2>Permissions</h2>
<p>The heirarchy goes: Super, Owner, Administrator, User and different themes and permissions can be applied at all levels. For example, youre a web design agency that resells its services to other web design agencies. You are the  "Super" with unrestricted access to all parts of the system  including  renewals, timelog, billing etc. Your customers are "owners",  they can  "own" any number of sites that you specify, for example you  may sell a  block of 10 sites at a discounted rate. The system is themed  with your  branding at the <em>Super</em> level, whilst owners and their  customers  see the owner branding. Optionally, each of their customes  can ask that  their own branding be applied to the system at any stage.</p>
<p>Owners have access to renewal, billing and SEO tools that relate to   their customers only, and can set permissions for administrators and   users, whereas only Supers can set permissions for Owners.</p>
<p>To clarify:</p>
<ul>
<li>Supers have access to all the tools available to owners, administrators and users.</li>
<li>Owners have access to all the tools available to administrators and users.</li>
<li>Site Administrators have access to all permissioned tools available to users</li>
<li>Users only have access to tools and modules (eg: CRM, Orders) that are permissioned for them.</li>
</ul>
<h1>Super Tools</h1>
<h2>Mass Emailing System</h2>
<p>Supers have fine-grained control of a mass emailing system, enabling them to resell an e-marketing service. The system is extremely sophisticated, allowing for timed deliveries and detailed analytics: who opened and who clicked through the mailer, bounced emails can be automatically removed from the subscriber list or moved to a seperate subscriber category. At a technical level, email can be delivered using the servers built-in mail platform, or any number of SMTP servers can be added and cycled throughout the mailing. Email addresses are categorised as either POP, Webmail or AOL, and different services can be allocated to ensure full delivery is carried out. Mail is delivered in batches of 25, 50 or 75 depending on the size of the mailing list, and each iteration can be scheduled into two minute cycles to prevent server overload.</p>
<h1>Owner Tools</h1>
<p>There are a number of owner tools available to help the   process of  managing any number of websites such as directory  submission  tools,  search engine trackers, time loggers, auto-backups  and many more.</p>
<p><img class="alignleft" title="cms_renewals2" src="http://www.lynkit.net/blog/wp-content/uploads/2010/04/cms_renewals2.jpg" alt="" width="245" height="73" /></p>
<div>
<dl id="attachment_270">
<dt><img title="cms_renewals" src="http://www.lynkit.net/blog/wp-content/uploads/2010/04/cms_renewals.jpg" alt="" width="300" height="113" /></dt>
<dd>Domain  Renewals are managed via the administration console</dd>
</dl>
</div>
<div>
<dl id="attachment_269">
<dt><a href="http://www.lynkit.net/blog/wp-content/uploads/2010/04/cms_logins.jpg"><img title="cms_logins" src="http://www.lynkit.net/blog/wp-content/uploads/2010/04/cms_logins.jpg" alt="" width="606" height="201" /></a></dt>
<dd>Timelogger   for domain management tasks</dd>
</dl>
</div>
<div id="attachment_289" class="wp-caption alignnone" style="width: 542px"><a href="http://www.lynkit.net/blog/wp-content/uploads/2010/04/cms_permissions.jpg"><img class="size-full wp-image-289" title="cms_permissions" src="http://www.lynkit.net/blog/wp-content/uploads/2010/04/cms_permissions.jpg" alt="CMS Permissions" width="532" height="415" /></a><p class="wp-caption-text">You can specify permissions on a per user basis</p></div>
<h1></h1>
<h1>Administrator Tools</h1>
<p>With our wide datasheet view and ajax based tables, any aspect of a   page (such as the meta information) can be edited directly on screen,   without needing to open up the page editor at all.</p>
<div>
<dl id="attachment_266">
<dt><a href="http://www.lynkit.net/blog/wp-content/uploads/2010/04/ajaxcms.jpg"><img title="Onscreen meta editing makes the    job easy" src="http://www.lynkit.net/blog/wp-content/uploads/2010/04/ajaxcms.jpg" alt="" width="273" height="82" /></a></dt>
<dd>Onscreen meta editing makes  the job easy</dd>
</dl>
</div>
<h2></h2>
<h1>Front end</h1>
<p>Because domains within this system are cloud based, the front end requires only a set of library files. This makes for a tiny hosting footprint comprising CSS files, site specific images and a few driver files. The drivers do not need to be on the same hosting server as the platform.</p>
<p>Themes and skins can be file or database based and our unique skinning system makes it easy to convert designs and HTML    into a fully integrated Content Management System (CMS), with many    modules automatically available and requiring no technical input, simply   switch them on.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lynkit.net/blog/domain-management-system/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>White label CMS Platform for web and design agencies</title>
		<link>http://www.lynkit.net/blog/white-label-cms-platform/</link>
		<comments>http://www.lynkit.net/blog/white-label-cms-platform/#comments</comments>
		<pubDate>Tue, 27 Apr 2010 12:38:51 +0000</pubDate>
		<dc:creator>Eck</dc:creator>
				<category><![CDATA[Content Management System]]></category>
		<category><![CDATA[JibberJabber]]></category>
		<category><![CDATA[What were making now]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[CP3]]></category>

		<guid isPermaLink="false">http://www.lynkit.net/blog/?p=265</guid>
		<description><![CDATA[With the imminent launch of our CP3 platform, we are opening up the system to make it available to web and design agencies. CP3 incorporates multi-level theming so that agencies can not only apply their own branding to the product, but can re-sell and brand individual parts of the system making this a true white [...]]]></description>
			<content:encoded><![CDATA[<p>With the imminent launch of our CP3 platform, we are opening up the system to make it available to web and design agencies. CP3 incorporates multi-level theming so that agencies can not only apply their own branding to the product, but can re-sell and brand individual parts of the system making this a true white label CMS platform.</p>
<p>Small and medium agencies often lack the technical resources to deliver websites rapidly and so there is a need to shift from a do-it-all approach to a more specialised model that concentrates on the core aims of the business such as design, marketing and content with less focus placed on the technical installation and workings of the website. </p>
<p>For this reason we have developed a robust and flexible <em>cloud</em> based platform for delivering websites in a fraction of the time it normally takes and are looking for partners to use or contribute to our systems. This kind of partnership results in a very low cost of ownership and hugely increased capacity for agencies.It also creates a clear role division between the responsibilities of creating and managing websites, with the technology provider (us)  being in charge of maintaining and developing a state of the art CMS platform and modules, leaving agencies free to handle the design and content management.</p>
<p>In particlular, the system is aimed at individuals or companies that wish to extend their range of services by including website design into their business.</p>
<ul>
<li>Web and new media Design Agencies</li>
<li>Traditional Design agencies</li>
<li>Sales and marketing consultants</li>
<li>Search Engine specialists</li>
<li>Email marketers</li>
</ul>
<p>Ultimately the CMS is accessible in "simple mode" to the end users, the website owners, allowing them full control of their own content should they desire, only turning to the agencies for redesigns or implementation of new features. Agencies control the module permissions of individual users, offering a valuable up-sell opportunity to many of their clients, such as the inclusion of a blog, registration, e-Catalogue or other complex functionality.</p>
<p>Using our technology platform has many advantages:</p>
<ul>
<li>Substantially lower cost of ownership</li>
<li>Lower training costs</li>
<li>Low maintenance costs</li>
<li>Own brand livery and operating manuals</li>
<li>Robust and mature standards compliant code</li>
<li>Backoffice is completely independent of website files</li>
<li>Interchangeable templates</li>
<li>More customers are familiar with the platform and the tools</li>
<li>Always up to do date and with the latest web features</li>
<li>Continuous improvements of the platform immediately apply to all domains in the cloud</li>
<li>Powerful tools and modules can be developed once and applied to all, creating extra revenue streams</li>
<li>Fully scalable as the web expands - New modules are created regularly</li>
<li>No frontend updates are required. Statistical and version updates, as well as site backups are carried out automatically</li>
</ul>
<p>If you are an agency or sales consultant and would like to know more about our platform to deliver state of the art websites to your customers, please <a title="Get in touch" href="http://www.lynkit.net/get-in-touch_36.html">contact Dave or Paul</a> or leave a comment below.</p>
<p>You can read more about CP3 <a title="Domain Management System" href="http://www.lynkit.net/blog/domain-management-system/">here</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lynkit.net/blog/white-label-cms-platform/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
