<?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>Sandjam</title>
	<atom:link href="http://sandjam.co.uk/sandjam/feed/" rel="self" type="application/rss+xml" />
	<link>http://sandjam.co.uk/sandjam</link>
	<description>Web development and more fun stuff</description>
	<lastBuildDate>Thu, 16 May 2013 15:02:10 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>WordPress Optimisation Checklist</title>
		<link>http://sandjam.co.uk/sandjam/2013/05/wordpress-optimisation-checklist/</link>
		<comments>http://sandjam.co.uk/sandjam/2013/05/wordpress-optimisation-checklist/#comments</comments>
		<pubDate>Sat, 11 May 2013 13:51:25 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[Code Chat]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[tricks]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=761</guid>
		<description><![CDATA[WordPress is a framework which is great for rapid development because it is so quick and easy to set up. Check out the famous WordPress 5 minute install. However, if you want to really make sure that your installation is working as efficiently and securely as possible, there are a...]]></description>
				<content:encoded><![CDATA[<p>WordPress is a framework which is great for rapid development because it is so quick and easy to set up. Check out the famous <a href="http://codex.wordpress.org/Installing_WordPress#Famous_5-Minute_Install">WordPress 5 minute install</a>.</p>
<p>However, if you want to really make sure that your installation is working as efficiently and securely as possible, there are a few extra tweaks I tend to add in to most sites I set up.</p>
<h2>Table Prefix</h2>
<p>During the setup, you are prompted to set a couple of site variables. It&#8217;s easy to skip these and leave them as their default values, but don&#8217;t.</p>
<p>Changing the default table prefix from &#8216;wp_&#8217; to something else means that:</p>
<ul>
<li>You can have multiple WordPress sites on one database without overwriting eachother&#8217;s tables.</li>
<li>If a hacker gains access to your database, they will have a harder time working out what tables you have.</li>
</ul>
<h2>Admin Username</h2>
<p>Don&#8217;t leave the default admin user called &#8216;admin&#8217;. Brute force attacks can more easily gain access if they only have to guess the password.</p>
<p>This must be done when you first set up the site as it&#8217;s lots more difficult to change the admin username after the initial setup.</p>
<h2>Limit Previous Post Versions</h2>
<p>WordPress keeps previous versions of posts which is handy in case you accidentally save something and you want to revert a post. However this can result in bloated database tables if your site has a lot of posts or is updated frequently.</p>
<p>By adding this setting in to your wp_config.php file you can limit post revisions to something reasonable, or disable revisions altogether.</p>
<pre class="qoate-code">
define('WP_POST_REVISIONS', 3);

or

define('WP_POST_REVISIONS', false);
</pre>
<h2> Autosave Interval</h2>
<p>WordPress automatically saves posts as you write them every 60 seconds. This adds a little more overhead to the page, and is usually a bit unnecessary.</p>
<p>Adding this setting into wp_config.php allows you to amend this interval to something more reasonable like 5 minutes.</p>
<pre class="qoate-code">

define('AUTOSAVE_INTERVAL', 300);   // 5 mins

</pre>
<h2> Move wp_content Directory</h2>
<p>There are some security advantages to moving your wp_content directory away from the site root. It may deter some automated bots which scan your domain for recognised directory patterns.</p>
<p>Anybody who looks even a little more closely at your site will still be able to work out where wp-content is, but it&#8217;s another small step towards making your site look a little less like a standard WordPress installation.</p>
<pre class="qoate-code">

define('WP_CONTENT_DIR', $_SERVER['DOCUMENT_ROOT'].'/path/wp-content');

define('WP_CONTENT_URL', 'http://mysite.com/path/wp-content');

</pre>
<h2> Thumbnail Sizes</h2>
<p>One of my biggest problems with WordPress is its greedy habit of creating thumbnails of all sizes for every uploaded image, whether that thumbnail is used or not. This can cause your uploads directory to grow very large very quickly, so anything that can be done to keep this in check is useful.</p>
<p>If your theme uses custom image sizes, update the thumbnail sizes in <strong>Settings &gt; media</strong> to be the same as those in your theme. If you don&#8217;t need any of the default image sizes like &#8216;medium&#8217; or &#8216;large&#8217; set the width and height values to zero to prevent WordPress from generating these thumbs.</p>
<h2>Cache Plugin</h2>
<p>It&#8217;s useful to have a cache plugin like <a href="http://wordpress.org/extend/plugins/wp-super-cache/">WP Super Cache</a> set up on your site, even if you don&#8217;t think you need it right now.</p>
<p>When your site becomes so popular that the server starts to fall over, it&#8217;s a lot harder to start installing a cache plugin. Have the plugin ready to go, and you can just activate the cache or even use the &#8216;lockdown&#8217; mode if your site happens to get <a href="http://www.techradar.com/news/internet/how-stephen-fry-takes-down-entire-websites-with-a-single-tweet-674170">tweeted by Stephen Fry</a>.</p>
<h2>Comments</h2>
<p>If your site is going to use comments, definitely sign up to <a href="http://akismet.com/">Akismet </a>which will help filter out spam comments.</p>
<p>If you&#8217;re not using comments, make sure you disable all the comments features in <strong>Settings &gt; Discussion</strong> to make sure people can&#8217;t sign up or submit content.</p>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2013/05/wordpress-optimisation-checklist/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Custom Styles for Select Inputs</title>
		<link>http://sandjam.co.uk/sandjam/2013/03/custom-styles-for-select-inputs/</link>
		<comments>http://sandjam.co.uk/sandjam/2013/03/custom-styles-for-select-inputs/#comments</comments>
		<pubDate>Sat, 16 Mar 2013 15:03:00 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[Code Chat]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[tricks]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=765</guid>
		<description><![CDATA[It&#8217;s long been a problem for developers that the Select (or dropdown) input doesn&#8217;t allow you many options for customising their look and feel. You shouldn&#8217;t be trying to style selects! When you search for help on this matter, you often come across people arguing that select inputs get their...]]></description>
				<content:encoded><![CDATA[<p>It&#8217;s long been a problem for developers that the Select (or dropdown) input doesn&#8217;t allow you many options for customising their look and feel.</p>
<h2>You shouldn&#8217;t be trying to style selects!</h2>
<p>When you search for help on this matter, you often come across people arguing that select inputs get their style from whatever browser you are in and you should under no circumstance by trying to overrule browser behaviour.</p>
<p>That&#8217;s all well and good, but when a client asks for a website with a custom designed select, you can&#8217;t just say &#8220;You can&#8217;t have it&#8221;.</p>
<p>You&#8217;ve just got to get it done.</p>
<h2>Plugins</h2>
<p>There are already some great plugins out there, which take different approaches to solve this problem. My favourite is</p>
<p><a href="http://jamielottering.github.io/DropKick/">DropKick</a></p>
<h2>My Solution</h2>
<p>My aim is to have the look of the select styled completely outside of the original element, however it should still use the native select dropdown options when it is clicked.</p>
<p>Some plugins, including DropKick, hide the select and completely re-create the behavior using css and JavaScript. This is all very nice, and lets you have the most control over how the element and the options look, but it does present problems. The main issue is on touch devices like phones and tablets. These devices have their own way of handling dropdown behavior, which is usually quite nice and useable, while the functionality introduced by the JavaScript plugins is usually a little clunky and difficult to use.</p>
<p>Here&#8217;s my solution:</p>
<p>Use a jQuery selector to wrap the select in a div</p>
<pre class="qoate-code">

$('select').wrap('&lt;div class="style_select"&gt;&lt;/div&gt;');

</pre>
<p>Add a span element into the div which will mimic the select text</p>
<pre class="qoate-code">

$('.style_select').append('&lt;span&gt;&lt;/span&gt;');

</pre>
<p>Attach a change event to update the span caption whenever the select is updated</p>
<pre class="qoate-code">

$('select').change(function(){
$(this).parent().find('span').html($(this).find('option:selected').text());
});
$('select').change();

</pre>
<p>Now for the css&#8230;</p>
<p>The aim is to hide the original select element, but still have it clickable. By setting the opacity to zero, and positioning the select absolutely above its holder it still receives the click event but is invisible until the dropdown is triggered.</p>
<pre class="qoate-code">

.style_select{
position: relative; display: block; float:left; padding:17px; width:175px; margin-right:20px; overflow: hidden;
background: url('../images/select-arrow.png') #f1f1f1 center right no-repeat; cursor: pointer;
color: #3b4043; border:solid #e7e5e5 1px;
}
.style_select select{
-webkit-appearance: none;
position: absolute; top:0; left:0; width:100%; height:48px; cursor:pointer;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0);
-moz-opacity: 0;
-khtml-opacity: 0;
opacity: 0;
}
.style_select span{ display: block; width:160px; height:1.14em; overflow: hidden; color: #888888; }
.style_select select option{ padding:5px; border: none; }

</pre>
<p>I think this is a good compromise between getting your form element to fit in with the house styles while preserving the native browser behavior.</p>
<p>The only drawback is that you are still using the native dropdown which remains difficult to style, but the functionality is great on mobile devices and the other browsers all handle it as they see fit.</p>
<p><a href="http://www.sandjam.co.uk/demos/styled_select/" class="button orange" target="_blank"><span>Check out an example</span></a></p>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2013/03/custom-styles-for-select-inputs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Twitter Changes Its Terms</title>
		<link>http://sandjam.co.uk/sandjam/2012/12/twitter-changes-its-terms/</link>
		<comments>http://sandjam.co.uk/sandjam/2012/12/twitter-changes-its-terms/#comments</comments>
		<pubDate>Fri, 28 Dec 2012 14:11:23 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[Code Chat]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[social networking]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=735</guid>
		<description><![CDATA[In March 2011 Twitter announced some upcoming changes to its Terms of Use which would affect developers. This is really an understatement as what they&#8217;ve actually done is fundamentally redefined how they would like their service to be used and what developers ought to be using it for. What&#8217;s new?...]]></description>
				<content:encoded><![CDATA[<p>In March 2011 Twitter <a href="http://www.guardian.co.uk/technology/blog/2011/mar/14/twitter-developers-client-warning">announced some upcoming changes</a> to its Terms of Use which would affect developers. This is really an understatement as what they&#8217;ve actually done is fundamentally redefined how they would like their service to be used and what developers ought to be using it for.</p>
<h2>What&#8217;s new?</h2>
<p>The most important changes can be broken down in to two main principles:</p>
<blockquote><p>1. All requests to the Twitter API must tied to a developer&#8217;s account. If the number of requests a developer makes passes a threshold, then charges may be imposed.</p></blockquote>
<p>Deep integration of the API including anything with account details has always required a secure request tied to a developer&#8217;s account. However requests to the public timeline and search pages has until now been available to anonymous requests.</p>
<p>In theory this shouldn&#8217;t affect small-scale projects with just a few thousand requests per month but it will discourage people from creating even small scale applications because of the fear that they may become too successful and start becoming expensive before the app really makes the money to justify it.</p>
<p>One of my projects is Tweetedtrips.com which makes use of anonymous client-side requests to the Twitter API to fetch data by all the visitors to the site, creating a type of cloud-computing resource that I couldn&#8217;t afford to pay for at a server farm. It would be possible to re-write this to the all the requestsa re signed to my developer account, but it&#8217;s risky to spend all that time when the site may be shut down by the second change.</p>
<blockquote><p>2. If you want to request a Tweet and display it on your own website or app it must be in a format specifically defined by Twitter. No re-formatting Tweets.</p></blockquote>
<p>This is the most perplexing rule which in theory will mean the millions of websites which display their latest tweets on the home page will be outlawed. Lots of very successful services which make use of the rich data made available through Twitter have already started closing down because they simply can&#8217;t exist without the flexibility to display the tweet data in different ways.</p>
<p>I don&#8217;t know how or if they are planning on enforcing this rule. Presumably they will pursue site which they see as competition or don&#8217;t like the look of and ignore any small infringements like personal blogs. But once again, having this threat that you could be shut down at any moment is going to discourage a lot of developers from pursuing ideas based upon Twitter data.</p>
<h2>The end is nigh</h2>
<p>These changes come in to force in March 2013, so until that date we won&#8217;t know how strictly this will be enforced or how many services will be affected.</p>
<h2>What does this mean for me?</h2>
<p>There are already some big names which have had to change the way they work, or drop their Twitter integration altogether like Instagram.</p>
<p>This move has angered a lot of developers and many may think twice before selecting Twitter as a data source to play with in the future. Twitter has reached a size now where it is ubiquitous and invaluable for a lot of companies. It&#8217;s a bold move to try and start to dictate how their service should be used after it has grown so quickly due to massive public uptake, but when you hold all the cards you also get to dictate the terms.</p>
<p>I actually don&#8217;t have a problem with them needing to authenticate all requests, and to charge for larger users after all they have to make money somehow. I do have a problem with them potentially charging to retrieve Twitter data then dictating how it may be displayed.</p>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2012/12/twitter-changes-its-terms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building a Responsive Design: Top Tips</title>
		<link>http://sandjam.co.uk/sandjam/2012/11/building-a-responsive-design-top-tips/</link>
		<comments>http://sandjam.co.uk/sandjam/2012/11/building-a-responsive-design-top-tips/#comments</comments>
		<pubDate>Tue, 27 Nov 2012 11:34:31 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Responsive Design]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[tricks]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=707</guid>
		<description><![CDATA[Coding HTML at the cutting edge, make use of HTML5 and CSS3 to create fully responsive layouts that look great on screens of all sizes.]]></description>
				<content:encoded><![CDATA[<p>Responsive Design is becoming more and more popular as businesses realise it&#8217;s quicker and cheaper to spend a little longer creating a responsive site which looks great on screens of all sizes rather than building separate sites for desktops, tablets and mobile devices.</p>
<p>Gone are the .mobli sites. Goodbye m.mysite.com. Hello media queries, fluid layouts and data driven designs. Here are my top tips for creating responsive front end builds:</p>
<h2>Content is king</h2>
<p>Responsive design isn&#8217;t something that can be tagged on to the end of a project, it needs to be integral to the planning and design from the beginning. Rather than concentrating on specific design elements the site should be built based upon the content which is going to be most important.</p>
<p>By deciding initially which messages and content is most important and which content is ancillary you can then build up a layout which highlights the most important content throughout as the site gracefully falls back to a basic layout.</p>
<h2>Widths are all relative</h2>
<p>Responsive designs all start from a fluid layout. That is to say a layout in which all the widths are considered as percentages rather than having fixed pixel or em values. The design you are building from will be a specific width, so as you&#8217;re building the layout you need to keep a calculator to hand and for each element width you use measure the pixel width of the element and its container in your design, then work out that as a percentage. Don&#8217;t be tempted to round these values down to neaten up the stylesheet, keep 5 0r 6 decimal places otherwise you will begin to get rounding errors creeping in and disrupting the total width.</p>
<h2>Pixels aren&#8217;t evil</h2>
<p>Some fans of fluid layouts will tell you that in a responsive design there shouldn&#8217;t be any references to sizes measured in pixels. I don&#8217;t necessarily agree with this. There are cases when having a fixed pixel size is important. For example if you&#8217;re using a background image for an element, and you don&#8217;t want to use background-size to stretch it for compatibility, it&#8217;s quite acceptable to set it to a fixed pixel width and height. Maybe for the company logo, or a graphical button.</p>
<p>Also, element heights and vertical margins and paddings may be set in pixels or ems. Column heights may resize based on the amount of content in them, and especially if the widths are resizing responsively you can&#8217;t expect the height to be fixed. Therefore to set the margins and paddings based on a percentage of their height is nonsense. It makes more sense to have a fixed margin of say 1em, then perhaps collapse that to 0.5em below a certain screen size.</p>
<h2>Resolutions aren&#8217;t always what they first seem to be</h2>
<p>It may seem like a simple question to find out what size design to use for say, the iPhone4 or the Samsung Galaxy Tab, but ti&#8217;s not always that straight forward.</p>
<p>The iPhone 3 has a resolution of 320 x 480, and the iPhone 4 has twice that&#8230; but it also has twice the pixel density so although it still reports the same screen size there is actually twice the resolution based on the retina display.</p>
<p>There are also issues in the Android browsers whereby the browser is actually more intelligent than simply having a set screen size. It will attempt to provide a resolution that will best fit the content being provided.</p>
<p>The bottom line is to remember you aren&#8217;t building for specific devices, you are building for all devices. So just make sure it scales well over a range of screen resolutions, then let the device choose which size it wants to display your site at.</p>
<h2>CSS3 content is naughty but nice</h2>
<p>It&#8217;s nice to be able to have shorter captions on mobile devices, for example a button might say &#8220;Login to Shop&#8221; on larger screens, and simply &#8220;Login&#8221; on mobile devices. You can use the css3 content attribute to achieve this, by setting the text for the mobile version initially then using a conditional css3 tag to append &#8220;to Shop&#8221; for screens larger than, say, 800px.</p>
<pre class="qoate-code">

/* Add extended button caption for larger screens */
.button:after{
content: ' to Shop';
}
@media only screen and (max-width: 800px){
/* Remove 'to shop' from button caption */
.button:after{ content: ''; }
}

</pre>
<p>This is a bit naughty really. CSS is supposed to only be used to describe styles and what you&#8217;re doing here is using it to hold content. It&#8217;s certainly bad if you&#8217;re expecting any of this content to be picked up by search engines. But I think that if it&#8217;s used sparingly and in the right place it can be another useful tool in the Responsive shed.</p>
<h2>Choose your image sizes carefully</h2>
<p>There is no standard way of serving different image sizes for responsive sites. Ideally, you would just use a css attribute in the stylesheet and a media query to target different resolution images to different browser resolutions. However often browsers will pre-load all images in the stylesheet, whether they are used or not, which defeats the point of providing low-res images for small screens.</p>
<p>The two main options are:</p>
<ol>
<li>Use JavaScript to set a cookie with containing the browser resolution. Then point your images src to a server side script which will look at this cookie and serve up the relevant image. The downside of this technique is the extra server overhead placed on every image call.</li>
<li>Always point your image paths to the low-res version, and include the hi-res path in an element attribute. Then use JavaScript to switch out these paths based on the screen size. The downside of this is that larger devices will have to load both images and there is the chance that if the page is a little slow in loading you may see the low-res images for a moment before the JS kicks in.</li>
</ol>
<p>There is no right answer here, other than to look at each project and each image instance  individually and make a decision based on the requirements. Maybe there is only a main showcase image that you need to provide a fallback for, maybe mobile load times are crucial so the images should be as light as possible.</p>
<h2>IE still takes up all your testing time</h2>
<p>As much as HTML5 saves us time by offering us rounded corners, transforms, transitions and gradients without having to add endless plugins, the truth is that you still end up spending the most amount of time fixing legacy internet explorer issues. We hoped that once ie6 got decommissioned, life would become easier, but ie7 and ie8 still throw up a lot of problems, not least their lack of support for media queries.</p>
<h2>HTML5 and CSS3 &#8211; the time is now</h2>
<p>HTML5 allows us to write neater, more concise code and create great effects without having to rely on external libraries or tool kits. However as soon as you decide you want to make these features work on anything but the newest generation of browsers you quickly find yourself delving back into fallbacks, hacks and JS plugins. This puts a lot of people off using HTML5 and CSS3 but the truth is that HTML5 is designed to be used now.</p>
<p>Most of the features like rounded corners and background gradients can degrade gracefully without any extra code. A great tool for finding out which features you can use safely and which need fallbacks in place is <a href="http://html5please.com/">http://html5please.com/</a>.</p>
<p>Use it now or loose it!</p>
<h3> Some Useful Links</h3>
<ul>
<li><a href="http://html5please.com/">html5please.com</a> &#8211; Directory of HTML5 and CSS3 features with their browser compatibility and fallback requirements</li>
<li><a href="http://www.alistapart.com/articles/responsive-web-design/">alistapart.com/articles/responsive-web-design</a> &#8211; Great introduction to Responsive Design</li>
<li><a href="http://coding.smashingmagazine.com/2011/01/12/guidelines-for-responsive-web-design/">coding.smashingmagazine.com/2011/01/12/guidelines-for-responsive-web-design</a> &#8211; Smashing Magazine&#8217;s Responsive Design overview with links to articles on each aspect</li>
<li><a href="http://resizemybrowser.com/">resizemybrowser.com</a> &#8211; Great tool for testing browser sizes based on common devices</li>
</ul>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2012/11/building-a-responsive-design-top-tips/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gerber uses Tweetedtrips.com</title>
		<link>http://sandjam.co.uk/sandjam/2012/11/gerber-uses-tweetedtrips-com/</link>
		<comments>http://sandjam.co.uk/sandjam/2012/11/gerber-uses-tweetedtrips-com/#comments</comments>
		<pubDate>Sun, 11 Nov 2012 16:44:12 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Google Maps]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[social networking]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=719</guid>
		<description><![CDATA[US Outdoors giant Gerber release their stunning new brand site, including a location map powered by Tweeted Trips]]></description>
				<content:encoded><![CDATA[<p>US outdoors giant Gerber have a launched their new brand site, centred around their &#8220;Hello Trouble&#8221; campaign which sees their ambassadors tour the country spreading the message of Gerber Gear. Their trip is being tracked by a live tweet map powered by Tweetedtrips.com, a site I built and run independently.</p>
<p>Their site features some stunning design and a really nice implementation of infinite scrolling. It&#8217;s the kind of site that is designed to be played with, it&#8217;s very usable, intuitive and begs to be explored.</p>
<p><a href="http://www.gerbergear.com/unstoppable/hellotrouble/#/" class="button orange" target="_blank"><span>Check Out GerberGear.com</span></a></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2012/11/gerber-uses-tweetedtrips-com/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Award Winning</title>
		<link>http://sandjam.co.uk/sandjam/2012/09/award-winning/</link>
		<comments>http://sandjam.co.uk/sandjam/2012/09/award-winning/#comments</comments>
		<pubDate>Tue, 18 Sep 2012 17:30:52 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Awards]]></category>
		<category><![CDATA[social networking]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=695</guid>
		<description><![CDATA[I have just discovered that one of the sites I built has won an award! The Magnum Boots Fieldtesters campaign won the Insider Magazine 2012 award for Best Digital Marketing Campaign in April 2012. Other winners at the awards included top brands like First Direct, NHS, Halfords, Ebuyer, and Belling....]]></description>
				<content:encoded><![CDATA[<p>I have just discovered that one of the sites I built has won an award!</p>
<p>The <a title="Magnum Boots Field Testers" href="http://sandjam.co.uk/sandjam/portfolio/magnum-boots-field-testers/">Magnum Boots Fieldtesters</a> campaign won the Insider Magazine 2012 award for Best Digital Marketing Campaign in April 2012.</p>
<p>Other winners at the awards included top brands like First Direct, NHS, Halfords, Ebuyer, and Belling.</p>
<p>Congratulations to the whole team at 9XB including the terrific designers and SEO experts who helped make this site such a runaway success.</p>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2012/09/award-winning/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Preventing Contact Form Spam</title>
		<link>http://sandjam.co.uk/sandjam/2012/09/preventing-contact-form-spam/</link>
		<comments>http://sandjam.co.uk/sandjam/2012/09/preventing-contact-form-spam/#comments</comments>
		<pubDate>Sun, 09 Sep 2012 10:58:38 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Code Chat]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[tricks]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=679</guid>
		<description><![CDATA[This is a problem which comes up time and time again. Every time you add a contact form to a website, you open yourself up to spam attacks. Solving this problem involves striking the right balance between making life easy for the person filling in the form, and the person...]]></description>
				<content:encoded><![CDATA[<p>This is a problem which comes up time and time again. Every time you add a contact form to a website, you open yourself up to spam attacks. Solving this problem involves striking the right balance between making life easy for the person filling in the form, and the person receiving the spam at the other end.</p>
<h2>Captcha</h2>
<p>Adding a test to the form that the user must complete before submitting it is the most resilient way. One of the most popular is <a href="http://www.google.com/recaptcha/captcha">reCaptcha</a> which uses imperfectly scanned books to test the user by presenting them with two scanned words. The first word, Captcha knows what it should be and the second word is used to help identify the scan. If enough users provide the same identify the second word, it is promoted to a known word.</p>
<p>Cleverly, this helps translate imperfect book scans as well as providing a robust identity check.</p>
<p>However this can be annoying for users, and will reduce the chance of a user completing the form. This should only be used where the level of security is more important than the volume of submissions you require.</p>
<h2>Javascript</h2>
<p>Spambots are the automated scripts which crawl the web looking for forms to fill in. Since these are usually performed using server-side page scrapes rather than browsers, Javascript usually isn&#8217;t run before the form is submitted.</p>
<p>One solution is to have a field on the form which is filled by Javascript before the form is submitted. The downside of this is that your page will fail if Javascript isn&#8217;t enabled, and it wouldn&#8217;t take much for a hacker to manually inspect the page and add the extra field in to their spam.</p>
<p>You may want to combine client-side Javascript form validation with spam checking. This provides a neater and quicker form submission process, but unless you provide a Javascript fallback you are cutting off accessibility and non-Javascript users.</p>
<h2>Cookies</h2>
<p>In the same way that bots don&#8217;t execute Javascript, they usually won&#8217;t carry site cookies around with them either. Using a server-side or client-side cookie to make sure the user has visited the site before submitting the form could be quite a neat way of validating them. Once again though, some users may choose to turn off cookies in their browsers, and depending on how your validation script works, it may fail if the first page a user lands on is the contact page.</p>
<h2>Time Dependence</h2>
<p>If a bot submits your form it is likely that it will either load your page and then imminently submit the form, or scrape the contents, store it somewhere and at some later date start sending submissions.</p>
<p>By creating an encoded token based upon the time of page creation and sending that though with the form you can get a good idea of whether the user may be real or not. For example I may create a field with the value of</p>
<pre class="qoate-code">time()/date('d')</pre>
<p>Which is the unix timestamp, divided by the day of the month, to obscure the value and make it difficult for bots to spot a pattern.</p>
<p>When the form is submitted, check that this field is passed though, and if it took less than say, 5 seconds to submit the form after the page loaded or more than 30 minutes, return a form error.</p>
<h2>Conclusion</h2>
<p>The best solution is probably to use a combination of some of the above techniques, depending on how high profile the form is going to be and the security you require from respondents.</p>
<p>Relying on the same technique for all your sites introduces the inherent danger that once one form is compromised, it&#8217;s likely that they all will be. Keeping the bots on their toes is the only way of staying ahead of them.</p>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2012/09/preventing-contact-form-spam/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Example Runkeeper Post</title>
		<link>http://sandjam.co.uk/sandjam/2012/08/example-runkeeper-post/</link>
		<comments>http://sandjam.co.uk/sandjam/2012/08/example-runkeeper-post/#comments</comments>
		<pubDate>Wed, 22 Aug 2012 16:06:25 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Misc]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=640</guid>
		<description><![CDATA[This is an example post to show how the Runkeeper WordPress Plugin can be used to insert a preview of your activity in to any post. Here is a cycle ride around Ecuup Reservoir. &#160; The new version of the plugin supports shortcodes and allows the frame size and position...]]></description>
				<content:encoded><![CDATA[<p>This is an example post to show how the <a title="Runkeeper WordPress Plugin" href="http://sandjam.co.uk/sandjam/2010/04/runkeeper-wordpress-plugin/">Runkeeper WordPress Plugin</a> can be used to insert a preview of your activity in to any post.</p>
<p>Here is a cycle ride around Ecuup Reservoir.</p>
<div id="runkeeper" title="http://runkeeper.com/user/peterasmith/activity/25780715,-300,-300" style="overflow:hidden; width:600px; height:400px;"></div>
<p>&nbsp;</p>
<p>The new version of the plugin supports shortcodes and allows the frame size and position to be controlled.</p>
<p><a href="http://sandjam.co.uk/sandjam/2010/04/runkeeper-wordpress-plugin/" class="button blue" target="_blank"><span>Find out More</span></a></p>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2012/08/example-runkeeper-post/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Post Snippits WordPress Plugin</title>
		<link>http://sandjam.co.uk/sandjam/2012/08/post-snippits-wordpress-plugin/</link>
		<comments>http://sandjam.co.uk/sandjam/2012/08/post-snippits-wordpress-plugin/#comments</comments>
		<pubDate>Wed, 22 Aug 2012 15:51:02 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[snippits]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=634</guid>
		<description><![CDATA[This plugin for WordPress allows you to define custom snippits of code or text which you might want to appear in several posts or pages. This makes it easier if you need to update common pieces of text or code as they can all be found in one place. You...]]></description>
				<content:encoded><![CDATA[<p>This plugin for WordPress allows you to define custom snippits of code or text which you might want to appear in several posts or pages.</p>
<p>This makes it easier if you need to update common pieces of text or code as they can all be found in one place.</p>
<p>You may find this useful for defining advertising code that you want to appear only in certain posts, or common pieces of information like addresses or phone numbers.</p>
<p>It also avoids problems with the WordPress WYSIWYG editor cleaning up JavaScript or CSS snippits entered in the post editor.</p>
<h2>Usage</h2>
<ul>
<li>Download and install the plugin</li>
<li>Use the Settings &gt; Post Snippits page to define your snippits. You can create as many snippits as you like, just give each one a different name.</li>
<li>Include the snippit in a post or page by using the shortcode <strong>[snippit name]</strong> where &#8220;name&#8221; is the name you defined in the settings page</li>
</ul>
<p>&nbsp;</p>
<p><a href="http://wordpress.org/extend/plugins/post-snippits/" class="button blue" target="_blank"><span>Download the Plugin</span></a></p>
<h2>Donate</h2>
<p>If you like this plugin, why not donate? Donations make free plugins possible.</p>
<form action="https://checkout.google.com/api/checkout/v2/checkoutForm/Merchant/430020626837638" id="BB_BuyButtonForm" method="post" name="BB_BuyButtonForm" target="_top">
<table cellpadding="5" cellspacing="0" width="1%">
<tr>
<td align="right" width="1%" style="vertical-align:top; padding-top:10px; padding-right:1em;">
<select name="item_selection_1">
<option value="1">£5.00 - Much appreciated</option>
<option value="2">£3.00 - Better than nothing</option>
<option value="3">£10.00 - Very kind, thanks</option>
</select>
<p>                <input name="item_option_name_1" type="hidden" value="Much appreciated"/>                <input name="item_option_price_1" type="hidden" value="5.0"/>                <input name="item_option_description_1" type="hidden" value=""/>                <input name="item_option_quantity_1" type="hidden" value="1"/>                <input name="item_option_currency_1" type="hidden" value="GBP"/>                <input name="shopping-cart.item-options.items.item-1.digital-content.description" type="hidden" value="Thanks for the donation, you're helping to keep the internet working and making everyone feel good."/>                <input name="shopping-cart.item-options.items.item-1.digital-content.url" type="hidden" value="http://sandjam.co.uk/sandjam/portfolio/post-snippits-wordpress-plugin/"/>                <input name="item_option_name_2" type="hidden" value="Better than nothing"/>                <input name="item_option_price_2" type="hidden" value="3.0"/>                <input name="item_option_description_2" type="hidden" value=""/>                <input name="item_option_quantity_2" type="hidden" value="1"/>                <input name="item_option_currency_2" type="hidden" value="GBP"/>                <input name="shopping-cart.item-options.items.item-2.digital-content.description" type="hidden" value="Thanks for the donation, you're helping to keep the internet working and making everyone feel good."/>                <input name="shopping-cart.item-options.items.item-2.digital-content.url" type="hidden" value="http://sandjam.co.uk/sandjam/portfolio/post-snippits-wordpress-plugin/"/>                <input name="item_option_name_3" type="hidden" value="Very kind, thanks"/>                <input name="item_option_price_3" type="hidden" value="10.0"/>                <input name="item_option_description_3" type="hidden" value=""/>                <input name="item_option_quantity_3" type="hidden" value="1"/>                <input name="item_option_currency_3" type="hidden" value="GBP"/>                <input name="shopping-cart.item-options.items.item-3.digital-content.description" type="hidden" value="Thanks for the donation, you're helping to keep the internet working and making everyone feel good."/>                <input name="shopping-cart.item-options.items.item-3.digital-content.url" type="hidden" value="http://sandjam.co.uk/sandjam/portfolio/post-snippits-wordpress-plugin/"/>            </td>
<td align="left" width="1%">                <input alt="" src="https://checkout.google.com/buttons/buy.gif?merchant_id=430020626837638&w=117&h=48&style=white&variant=text&loc=en_US" type="image"/>            </td>
</tr>
</table>
</form>
<div id="runkeeper" title="http://runkeeper.com/user/peterasmith/activity/25780715,-300,-300" style="overflow:hidden; width:600px; height:400px;"></div>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2012/08/post-snippits-wordpress-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Netbook review: Acer Aspire One</title>
		<link>http://sandjam.co.uk/sandjam/2012/08/netbook-review-acer-aspire-one/</link>
		<comments>http://sandjam.co.uk/sandjam/2012/08/netbook-review-acer-aspire-one/#comments</comments>
		<pubDate>Mon, 20 Aug 2012 13:09:39 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Review]]></category>
		<category><![CDATA[Cycling]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=607</guid>
		<description><![CDATA[I recently spent a year cycle touring abroad and one piece of kit seemed like a bit of a luxery before setting off, but proved to be incredably useful and great value for money. The Acer Aspire One is a small, lightweight netbook with all the features I&#8217;d need in...]]></description>
				<content:encoded><![CDATA[<p>I recently spent a year <a title="Online and On Tour" href="http://sandjam.co.uk/sandjam/portfolio/online-and-on-tour/">cycle touring abroad</a> and one piece of kit seemed like a bit of a luxery before setting off, but proved to be incredably useful and great value for money.</p>
<p>The Acer Aspire One is a small, lightweight netbook with all the features I&#8217;d need in a laptop but at only £199 I could treat it as roughly as I like and not have to worry too much if it gets damaged or stolen.</p>
<h2>The Specs</h2>
<p>Processor: Intel Atom Processor N450 (512KB L2 cache, 1.66GHz)</p>
<p>Chipset: Mobile Intel NM10 Express</p>
<p>Memory: 1GB DDR2 667 SDRAM</p>
<p>Video: 10.1″ (1024 x 600) high-brightness (200-nit) TFT display</p>
<p>Video Conferencing: Integrated Acer Crystal Eye webcam, 1280 x 1024 resolution, stereo speakers, Integrated digital microphone</p>
<p>Storage: 250GB hard drive, 5400RPM</p>
<p>Ports: Multi-in-one card reader, headphones, line-out, microphone, ethernet, USB x 3, VGA out</p>
<p>Wireless: Acer® InviLink Nplify 802.11b/g/n</p>
<p>Dimensions: 10.2″ (258.5mm) W x 7.3″ (185.0mm) D x 0.9” (24.0) H, 2.8 lb. (1.25kg) with six-cell battery</p>
<p>Operating System: Windows 7 Starter and Android dual boot</p>
<h2>The Pros</h2>
<p>Small and light enough to easily slip into a bicycle pannier. It spent days rattling around, survived freezing nights in the desert and days on end of 100F+ temperatures. After a year of frequent use the battery life still seems good and apart from a few cosmetic scratches and scrapes it is still holding up well.</p>
<p>Perfect for backing up photos along the way. The camera&#8217;s SD card fits straight in and the good capacity hard drive easily supports a year&#8217;s worth of photos and downloads.</p>
<p>Quick and powerful wifi receiver would always find points that the iPhone couldn&#8217;t see, and wouldn&#8217;t drop out or fail.</p>
<p>In-built webcam and mic meant I could keep in touch with home using Skype.</p>
<h2>The Cons</h2>
<p>Windows 7 Starter edition doesn&#8217;t include all the features of the full package. The only instance of this that troubled me though was not being able to change the desktop wallpaper. If you can put up with that though, the operating system runs surprisingly quickly.</p>
<p>The duel boot option with Android seems like a most pointless endeavour which I can&#8217;t believe anybody has ever made use of. There&#8217;s really nothing useful you can do with Android on a netbook and if I could have been bothered I&#8217;d have removed the Android partition altogether. It&#8217;s not difficult to set it up to boot straight into Windows though and then you can simply ignore Android (sorry Google).</p>
<p>The pre-installed Acer Video Conferencing software seemed to fail sometimes when trying to Skype, meaning the video would only be available to one side of the call. Updating the drivers, or removing this extra layer of management might solve this issue, but I never quite got around to trying that for fear of losing it altogether.</p>
<h2>Conclusion</h2>
<p>Other people have recommended iPads or other tablets as a more light-weight solution for touring with, but for the cost involved and the extra features you can get from a netbook I would definitely recommend this option. I probably wouldn&#8217;t use this as a day-to-day laptop once I&#8217;m home, but as a travelling companion you can&#8217;t get much better.</p>
<p>&nbsp;
<div id="runkeeper" title="http://runkeeper.com/user/peterasmith/activity/25780715,-300,-300" style="overflow:hidden; width:600px; height:400px;"></div>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2012/08/netbook-review-acer-aspire-one/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Target _blank is out the window</title>
		<link>http://sandjam.co.uk/sandjam/2012/08/opening-links-in-a-new-window/</link>
		<comments>http://sandjam.co.uk/sandjam/2012/08/opening-links-in-a-new-window/#comments</comments>
		<pubDate>Wed, 15 Aug 2012 14:39:29 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Code Chat]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[tricks]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=593</guid>
		<description><![CDATA[Clients will often ask me to target external site links to open in a new window. Of course the correct answer is &#8220;No, it&#8217;s not up to a site to determine how a link should work, the user can decide that when browsing.&#8221; Not only is it bad practice but...]]></description>
				<content:encoded><![CDATA[<p>Clients will often ask me to target external site links to open in a new window. Of course the correct answer is</p>
<blockquote><p>&#8220;No, it&#8217;s not up to a site to determine how a link should work, the user can decide that when browsing.&#8221;</p></blockquote>
<p>Not only is it bad practice but the<strong> target=&#8221;_blank&#8221;</strong> tag has been depreciated now and will cause a page to fail strict validation.</p>
<p>The truth is though that it <strong>is</strong> important to avoid taking traffic away from your site and whenever I have launched my own sites I find myself trying to achieve the same thing.</p>
<h2>So here&#8217;s my solution</h2>
<p>Use JavaScript to look through all links, determine whether they link to another domain and add the target after the page loads. This way the page will still validate, the code will be tidier and you won&#8217;t have to remember to manually change the link target every time one is added.</p>
<pre class="qoate-code">

$("a[href^=http]").each(
function(){
nonwww = location.hostname.replace("www.", "");
if(this.href.indexOf('http://'+location.hostname) == -1 &amp;&amp; this.href.indexOf('http://'+nonwww) == -1) {
$(this).attr('target', '_blank');
}
}
)

</pre>
<p>&nbsp;
<div id="runkeeper" title="http://runkeeper.com/user/peterasmith/activity/25780715,-300,-300" style="overflow:hidden; width:600px; height:400px;"></div>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2012/08/opening-links-in-a-new-window/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>10 Easy SEO Wins</title>
		<link>http://sandjam.co.uk/sandjam/2011/05/10-easy-seo-wins/</link>
		<comments>http://sandjam.co.uk/sandjam/2011/05/10-easy-seo-wins/#comments</comments>
		<pubDate>Mon, 09 May 2011 13:41:09 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[SEO]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[tricks]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=684</guid>
		<description><![CDATA[Optimising your site for search engines is an important part of the development process and there are dozens of ways of making sure your content stands out in the rankings. Here are my top tips that take very little implementation and will imminently improve your visibility in search. If you&#8217;re...]]></description>
				<content:encoded><![CDATA[<p>Optimising your site for search engines is an important part of the development process and there are dozens of ways of making sure your content stands out in the rankings.</p>
<p>Here are my top tips that take very little implementation and will imminently improve your visibility in search. If you&#8217;re interested in getting a more thorough review of your site&#8217;s SEO performance, <a title="Contact" href="http://sandjam.co.uk/sandjam/contact/">get in touch</a>.</p>
<h2>Insist on www.</h2>
<p>It doesn&#8217;t matter whether your URL starts with <strong>www.</strong> or not, but it is important that you don&#8217;t have duplicate content at <strong>http://www.mydomain.com</strong> and <strong>http://mydomain.com</strong>. A simple solution is to add an entry in to your .htaccess file in the domain root to 301 redirect any addresses which aren&#8217;t prefixed with www. to the equivalent address with www.</p>
<pre class="qoate-code">

RewriteEngine on

# insist on www
RewriteCond %{HTTP_HOST} !^(www.|$) [NC]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

</pre>
<h2>Insist on Trailing Slashes</h2>
<p>Make sure your URLs don&#8217;t have duplicate content with and without a trailing slash. If your URLs don&#8217;t end in a file extension like <strong>.html</strong> then it is good practice to insist on a trailing slash which will mark the end of the URL. Once again, your <strong>.htaccess</strong> file can keep an eye on this and make sure that any URLs which don&#8217;t end in a slash are 301 redirected to a URL with a slash. For example <strong>mydomain.com/page1</strong> would redirect to <strong>mydomain.com/page1/</strong></p>
<pre class="qoate-code">

RewriteEngine on

# insist on trailing slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ %{REQUEST_URI}/ [L,R=301]

</pre>
<h2>XML Sitemap</h2>
<p>Make sure you have an XML sitemap which lists all the pages in your site. The location of the sitemap should be referenced in your <strong>robots.txt</strong> file. It doesn&#8217;t matter what your sitemap file is called, just make sure it is correctly named in the robots file.</p>
<pre class="qoate-code">

robots.txt
User-agent: *
Sitemap: http://www.mydomain.com/sitemap.xml

</pre>
<h2>Title Tags</h2>
<p>Make sure your page title tags are unique, not too long and contain the page title followed by the brand. e.g.</p>
<pre class="qoate-code">

&lt;title&gt;10 Easy SEO Wins | Sandjam&lt;/title&gt;

</pre>
<h2>Only One H1</h2>
<p>Make sure there is only one H1 tag on each page, and it should be around the actual content title on the page. Not around the logo, or header image or nav button.</p>
<h2>Verify Your Site</h2>
<p>Set up your site in Google Webmaster Tools and Bing. Each will ask you to add a tag to your header or a file to your domain to prove you own it. Once verified you will be able to track any crawl errors, sitemap errors and other ways of improving your site&#8217;s visibility.</p>
<h2>Home Page Content</h2>
<p>You can easily get tied up in the design and functionality of your site and end up creating a home page which has very little text on. Make sure there is space on your home page for a couple of sentences of text explaining what the site does, including all your main keywords. It doesn&#8217;t need to be prominent for the user, just prominent for search engines.</p>
<h2>Canonical Links</h2>
<p>Some pages in your site are going to produce duplicate content, that&#8217;s unavoidable. For example search results, category indexes, preview pages. These types of pages should all include a canonical tag in the header to tell search engines which page you would rather they used. This will avoid you getting penalised for the duplicate content on these pages.</p>
<pre class="qoate-code">

&lt;link rel="canonical" href="http://www.mydomain.com/product/black-hat/"/&gt;

</pre>
<h2>Alt Tags</h2>
<p>It may seem like an obvious one, but remembering to add good alt tags to images is something I often see getting missed out. Good image alt tags will not only help the page ranking, but help your images appear in image searches too.</p>
<p>Why stop at images? adding title tags to links or buttons is less important, but still good practice and gives you the option to add different keywords in the title to those in the link. e.g.</p>
<pre class="qoate-code">

&lt;a href="gallery.html" title="Photos from Antigua and Barbuda"&gt;View Gallery&lt;/a&gt;

</pre>
<h2>Just Make a Great Site</h2>
<p>SEO is an important tool, but I think it&#8217;s also important to not loose focus on what really matters. You can spend hours trying to trick search engines in to thinking that your site is important. The best thing you can do is to create good, clean HTML markup with genuine well constructed content that your market will appreciate. Sell your site well, and you&#8217;ve already got a good head start on your SEO strategy.</p>
<p>&nbsp;
<div id="runkeeper" title="http://runkeeper.com/user/peterasmith/activity/25780715,-300,-300" style="overflow:hidden; width:600px; height:400px;"></div>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2011/05/10-easy-seo-wins/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>YouTube Data Class</title>
		<link>http://sandjam.co.uk/sandjam/2011/03/youtube-data-class/</link>
		<comments>http://sandjam.co.uk/sandjam/2011/03/youtube-data-class/#comments</comments>
		<pubDate>Tue, 15 Mar 2011 15:56:06 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Code Chat]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[tricks]]></category>
		<category><![CDATA[youtube]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=690</guid>
		<description><![CDATA[This is a class I&#8217;ve used several times and it demonstrates some of the useful data endpoints offered by YouTube. Often I will have to ask users or a web service for YouTube videos, and these may come in the form of share URLs, embed code or video URLs. This...]]></description>
				<content:encoded><![CDATA[<p>This is a class I&#8217;ve used several times and it demonstrates some of the useful data endpoints offered by YouTube.</p>
<p>Often I will have to ask users or a web service for YouTube videos, and these may come in the form of share URLs, embed code or video URLs. This class allows you to extract the video ID from each of these sources, which can be saved separately and used to either retrieve video data or embed the video in a page at a later date.</p>
<p><a href="http://sandjam.co.uk/demos/youtube.php" class="button blue" target="_blank"><span>Try the Demo</span></a></p>
<pre class="qoate-code">

&lt;?php
/**
* Simple class to extract YouTube Video ID and display video details
*
* @author     Peter Smith - sandjam.co.uk
* @version    1.0 10-9-12
*/
class YouTube {
public function __construct(){

}

/**
* Extract the video id from a YouTube URL or share code
*
* @param $str:String - URL or share code from YouTube
* @return $vid:String/False
*/
public function getVideoId($str){
// get video id from url in the format http://anything/videoid
preg_match("/(.*\/)([0-9a-zA-Z_-]*)$/i", $str, $matches);
if (isset($matches[2]) &amp;&amp; $matches[2]!='') { $vid = $matches[2]; }

// get video id from url in the format http://anything/watch?v=videoid&amp;anything
preg_match("/(.*\/)watch\?v\=([0-9a-zA-Z_-]*)\&amp;?.*$/i", $str, $matches);
if (isset($matches[2]) &amp;&amp; $matches[2]!='') { $vid = $matches[2]; }

// get video id from embed code in the format &lt;iframe width="xxx" height="xxx" src="http://www.youtube.com/embed/videoid" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;
preg_match("/iframe.*\/embed\/(.*)\"/iU", $str, $matches);
if (isset($matches[1]) &amp;&amp; $matches[1]!='') { $vid = $matches[1]; }

if (!isset($vid)) { return false; }

$vid = trim($vid);

return $vid;
}

/**
* Get the video details from YouYube data api
*
* @param $vid:String - YouTube Video Id
* @return $details:Array
*/
public function getVideoDetails($vid){
// attempt to load video to check it exists. This returns 404 if any errors with the videoid
$response = @file_get_contents('http://gdata.youtube.com/feeds/api/videos/'.$vid);

// response is not xml (error code)
if (substr($response, 0, 5) !='&lt;?xml') {
echo "$vid - This does not seem to be a valid YouTube video";
return false;
}

// assume thumbnail image exists in the usual location
$image = "http://i.ytimg.com/vi/$vid/0.jpg";

// parse video details xml
$videoXml = new SimpleXMLElement($response);

$title = $videoXml-&gt;title;

$details = array(
'title'        =&gt; (string) $videoXml-&gt;title,
'description'    =&gt; (string)$videoXml-&gt;content,
'author'        =&gt; (string)$videoXml-&gt;author-&gt;name,
'author_url'    =&gt; (string)$videoXml-&gt;author-&gt;uri,
'date'            =&gt; (string)$videoXml-&gt;published,
'image'        =&gt; (string)$image
);

return $details;
}

/**
* Compose the embed html code from a video id
*
* @param $vid:String, [$width:Int, $height:Int]
* @return $html:String
*/
public function getEmbedCode($vid, $width=600, $height=400){
$html = '&lt;iframe frameborder="0" width="'.$width.'" height="'.$height.'" allowfullscreen="" src="http://www.youtube.com/embed/'.$vid.'?fs=1&amp;amp;feature=oembed&amp;amp;wmode=opaque"&gt;&lt;/iframe&gt;';
return $html;
}
}
?&gt;

</pre>
<div id="runkeeper" title="http://runkeeper.com/user/peterasmith/activity/25780715,-300,-300" style="overflow:hidden; width:600px; height:400px;"></div>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2011/03/youtube-data-class/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Captionator using JQuery</title>
		<link>http://sandjam.co.uk/sandjam/2011/02/captionator-using-jquery/</link>
		<comments>http://sandjam.co.uk/sandjam/2011/02/captionator-using-jquery/#comments</comments>
		<pubDate>Sun, 27 Feb 2011 18:49:08 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Code Chat]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=279</guid>
		<description><![CDATA[A nice effect is to have the caption for a text field within the field instead of having a separate label. However it can be frustrating for a user if they have to delete the text before they can type into it. This JavaScript class looks for texfields with a...]]></description>
				<content:encoded><![CDATA[<p>A nice effect is to have the caption for a text field within the field instead of having a separate label.<br />
However it can be frustrating for a user if they have to delete the text before they can type into it.</p>
<p>This JavaScript class looks for texfields with a class of captionate and adds the label as the default text which will clear when a user clicks it.</p>
<p>The benefits of this method are that it retains the proper markup by requiring field labels and it falls back gracefully by not hiding the label if the browser doesn&#8217;t support Javascript.</p>
<h2>Demo</h2>
<form>
<fieldset><label for="namefield">Your Name</label><input id="namefield" class="captionate" type="text" name="namefield" /></fieldset>
</form>
<p>&nbsp;</p>
<h2>Code</h2>
<pre class="qoate-code">
&lt;script type="text/javascript"&gt;// &lt;![CDATA[
captionator = {
	captions:Array(),

	init:function() {
		$.each($('input.captionate'), function() { 
			id = $(this).attr('id');
			label = $("label[for='"+id+"']");
			if (label.length==0){ label = $(this).val(); }
			$(label).css('display', 'none');
			captionator.captions[id] = label.text();
			if ($(this).val()=='') { $(this).val(captionator.captions[id]); }

			$(this).click(function() {
				id = $(this).attr('id');
				if ($(this).val()==captionator.captions[id]) { $(this).val(''); }
			});

			$(this).blur(function() {
				id = $(this).attr('id');
				if ($(this).val()=='') { $(this).val(captionator.captions[id]); }		   
			});		
		});	
	}
}

$(document).ready(function() {
	captionator.init();
});
// ]]&gt;&lt;/script&gt;
&lt;fieldset&gt;&lt;label for="namefield"&gt;Your Name&lt;/label&gt;
&lt;input id="namefield" class="captionate" type="text" name="namefield" /&gt;&lt;/fieldset&gt;
</pre>
<div id="runkeeper" title="http://runkeeper.com/user/peterasmith/activity/25780715,-300,-300" style="overflow:hidden; width:600px; height:400px;"></div>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2011/02/captionator-using-jquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CSS Triangles</title>
		<link>http://sandjam.co.uk/sandjam/2011/02/css-triangles/</link>
		<comments>http://sandjam.co.uk/sandjam/2011/02/css-triangles/#comments</comments>
		<pubDate>Sun, 20 Feb 2011 12:22:44 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Code Chat]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[fonts]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[tricks]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=258</guid>
		<description><![CDATA[Creating triangles using css alone]]></description>
				<content:encoded><![CDATA[<p>Found a really interesting post on <a href="http://davidwalsh.name">David Walsh&#8217;s</a> blog about <a href="http://davidwalsh.name/css-triangles">creating triangles with CSS</a>.</p>
<p>The method uses a box with zero size and coloured borders to create the effect.</p>
<pre class="qoate-code">
div.arrow-up {
float:left;
width:0px;
height:0px;
border-left:5px solid transparent; /* left arrow slant */
border-right:5px solid transparent; /* right arrow slant */
border-bottom:5px solid #2f2f2f; /* bottom, add background color here */
margin:0 auto; /* centers the arrow within the parent container */
font-size:0px;
line-height:0px;
}
</pre>
<style type="text/css"> div.arrow-up { float:left; width:0px; height:0px; border-left:10px solid transparent; border-right:10px solid transparent; border-bottom:10px solid #2f2f2f; margin:0 auto; font-size:0px; line-height:0px; } span.arrow { display:inline-block; width:0px; height:0px; border-top:3px solid transparent; border-bottom:3px solid transparent; border-left:3px solid #2f2f2f; margin:0 auto; font-size:0px; line-height:0px; }</style>
<p>Produces the following: </p>
<div class="arrow-up"></div>
<p> &nbsp; </p>
<p>I like the fact that it&#8217;s using really creative CSS to produce a solution which is, I think, lots neater and reusable than cutting out little triangle graphics. I could imagine using this in breadcrumb trails for example. </p>
<p>Home <span class="arrow"> </span> Categories <span class="arrow"> </span> Page</p>
<p>To see this effect taken to the extreme, take a look at the <a href="http://www.cssplay.co.uk/menu/flag">Union Jack created using just CSS.</a>
<div id="runkeeper" title="http://runkeeper.com/user/peterasmith/activity/25780715,-300,-300" style="overflow:hidden; width:600px; height:400px;"></div>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2011/02/css-triangles/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Are sitemaps still necessary?</title>
		<link>http://sandjam.co.uk/sandjam/2011/01/are-sitemaps-still-neccessary/</link>
		<comments>http://sandjam.co.uk/sandjam/2011/01/are-sitemaps-still-neccessary/#comments</comments>
		<pubDate>Wed, 12 Jan 2011 11:33:30 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=604</guid>
		<description><![CDATA[Back in the old days all sites would have a sitemap which would show a nice family tree pointing out all the pages included on the site. But is that still necessary in the current age of dynamic content? This is a discussion I have had with other developers and...]]></description>
				<content:encoded><![CDATA[<p>Back in the old days all sites would have a sitemap which would show a nice family tree pointing out all the pages included on the site. But is that still necessary in the current age of dynamic content? This is a discussion I have had with other developers and SEO consultants, and my opinion is that no, a front-end sitemap isn&#8217;t needed for most sites. Here&#8217;s my argument.</p>
<h2>Sitemaps help users find pages on the site</h2>
<ul>
<li>If a user needs to go to a sitemap to find something on your site then it means the navigation structure and layout isn&#8217;t good enough.</li>
<li>A site search tool is a better way of finding content than a sitemap. Make sure the search works well and is easy to interpret.</li>
<li>How many times have you actually clicked on a sitemap to find something recently? Most of the time, if I can&#8217;t find something straight away I will go back to Google, or find a different site that will serve me the information more easily.</li>
</ul>
<h2>Sitemaps help search engines index the site</h2>
<p>Sure, a sitemap will help make sure that all your site pages are linked to from the front page and help indexing. But this is the job of an XML sitemap, and there&#8217;s no need to duplicate the work on a front-end sitemap.</p>
<p>The XML sitemap is essential and should link to all the site pages, providing information on their importance and update frequency. The name of the sitemap should be specified in the robots.txt file and doesn&#8217;t necessarily have to be sitemap.xml.</p>
<p>There are server side tools like <a href="http://code.google.com/p/googlesitemapgenerator/">Google Sitemap Generator</a> which will crawl your site internally and create xml sitemaps or you can dynamically create your sitemap.xml file using a php script.</p>
<p>In order to make a sitemap useful to search engines you need to include absolutely all the site pages on there. However, if you have a site with hundreds of old news stories on, for example, you may only only want to show the highlights to users on a front-end sitemap to avoid making it look too complicated.</p>
<h2>It&#8217;s just something people expect to see there, isn&#8217;t it?</h2>
<p>Maybe some people do expect to see it there, but in my opinion it is looking increasingly old fashioned to have a sitemap link. Modern savvy web users may look down on sites with dated phrases like &#8220;sitemap&#8221; or &#8220;webmaster&#8221;. My advice is to use that important header or footer space to push your SEO message or highlight a site search that will help users far more than sitemaps ever have.
<div id="runkeeper" title="http://runkeeper.com/user/peterasmith/activity/25780715,-300,-300" style="overflow:hidden; width:600px; height:400px;"></div>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2011/01/are-sitemaps-still-neccessary/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Thumbnails for sharing with Facebook</title>
		<link>http://sandjam.co.uk/sandjam/2010/11/thumbnails-for-sharing-with-facebook/</link>
		<comments>http://sandjam.co.uk/sandjam/2010/11/thumbnails-for-sharing-with-facebook/#comments</comments>
		<pubDate>Tue, 09 Nov 2010 17:02:38 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Code Chat]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[social networking]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=215</guid>
		<description><![CDATA[Facebook&#8217;s integration which allows you to post a page to Facebook is really clever. A bit too clever in fact. The integration allows you to pass the url and title though to the sharing window. The sharing window then goes and take s a look at the page and selects...]]></description>
				<content:encoded><![CDATA[<p>Facebook&#8217;s integration which allows you to <a href=" http://www.facebook.com/sharer.php?u=http://sandjam.co.uk/sandjam/%2F&amp;amp;t=Sandjam">post a page to Facebook</a> is really clever.</p>
<p>A bit too clever in fact.</p>
<p>The integration allows you to pass the url and title though to the sharing window. The sharing window then goes and take s a look at the page and selects the first few images it finds as likely candidates to use as thumbnail options.</p>
<p>However there&#8217;s no functionality built in there to tell Facebook which images you&#8217;d like it to use.</p>
<p>The <a href="http://developers.facebook.com/search?q=Facebook_Share/Specifying_Meta_Tags">Facebook Developers documentation</a> suggests specifying the image in a meta tag</p>
<pre class="qoate-code">

&lt;link rel="image_src" href="http://media.clickonf5.org/image/logo.png" /&gt;

</pre>
<p>However it seems that the sharing window doesn&#8217;t actually pay any attention to this, and certainly doesn&#8217;t allow you to specify multiple images.</p>
<p>I discovered this problem recently when I wanted to allow users to post a link to Facebook, but none of the images on the page were relevant to use as thumbnails.</p>
<p>The solution I ended up using was to look at the the header information before the page loaded, and if the client requesting the page was the Facebook sharer page, I present just a page with the thumbnails I want to choose from. Then exist the script as the sharer doesn&#8217;t need to see any more of the page.</p>
<pre class="qoate-code">
if (strstr($_SERVER['HTTP_USER_AGENT'], 'facebookexternalhit')) {
  ?&gt;
  &lt;img src="http://mysite.com/images/facebookimage1.gif" alt="" /&gt;
  &lt;img src="http://mysite.com/images/facebookimage2.gif" alt="" /&gt;
  &lt;?php
  exit();
}
</pre>
<div id="runkeeper" title="http://runkeeper.com/user/peterasmith/activity/25780715,-300,-300" style="overflow:hidden; width:600px; height:400px;"></div>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2010/11/thumbnails-for-sharing-with-facebook/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google dips its toe into font libraries</title>
		<link>http://sandjam.co.uk/sandjam/2010/07/google-dips-its-toe-into-font-libraries/</link>
		<comments>http://sandjam.co.uk/sandjam/2010/07/google-dips-its-toe-into-font-libraries/#comments</comments>
		<pubDate>Sun, 04 Jul 2010 10:19:58 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Code Chat]]></category>
		<category><![CDATA[fonts]]></category>
		<category><![CDATA[Google Maps]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=203</guid>
		<description><![CDATA[Google releases a beta version of its font directory and API]]></description>
				<content:encoded><![CDATA[<p>Finding a way to get non-standard fonts into web pages has always been a challenge. A designer will produce a beautiful layout using fonts that they have carefully chosen, then the developer sighs and either just converts it to Arial and hopes no one notices, or chooses a method of font substitution.</p>
<h2>Graphics</h2>
<p>Cutting up graphics and embedding them as images is time consuming, a nightmare to update and doesn&#8217;t allow for dynamic text. It&#8217;s the best way to make sure your site looks exactly like the design you&#8217;re working from, but don&#8217;t let an SEO guy see it.</p>
<h2>Flash</h2>
<p>I&#8217;ve used Flash based font replacement with <a href="http://www.mikeindustries.com/blog/sifr">Sifr</a> in the past. It always felt clunky though, I worry about the overheads of using lots of Flash font replacement on a page and you risk it failing for browsers which don&#8217;t support Flash like iPhones.</p>
<h2>Javascript</h2>
<p>The new families of Javascript based font replacement are really clever. <a href="http://cufon.shoqolate.com/generate/">Cufon</a>, for example, lets you upload a font file which it converts into path information which it then uses to draw the fonts using the HTML 5 &lt;canvas&gt; element.</p>
<p>Google love their Javascript apis so its not surprising that they&#8217;ve jumped on the bandwagon over at the <a href="http://code.google.com/webfonts">Google font directory</a>. Google are a bit more <a href="http://news.bbc.co.uk/1/hi/technology/8522004.stm">concerned about copyright</a> though and so they provide a  small selected of open source fonts rather than allowing you to upload any font.</p>
<p>Let&#8217;s have a go at an example:</p>
<pre class="qoate-code">

&lt;link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Tangerine"&gt;

&lt;style&gt;
p.tangerine { font-family: 'Tangerine', serif; font-size: 48px; }
&lt;/style&gt;

&lt;p class="tangerine"&gt;Sandjam goes Tangerine!&lt;/p&gt;

</pre>
<p>Produces:</p>
<p>&nbsp;</p>
<p class="tangerine">Sandjam goes tangerine</p>
<p>It works! Thanks Google, now just build up your font collection and I&#8217;m in.
<div id="runkeeper" title="http://runkeeper.com/user/peterasmith/activity/25780715,-300,-300" style="overflow:hidden; width:600px; height:400px;"></div>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2010/07/google-dips-its-toe-into-font-libraries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Javascript variable names in Internet Explorer</title>
		<link>http://sandjam.co.uk/sandjam/2010/05/javascript-variable-names-in-internet-explorer/</link>
		<comments>http://sandjam.co.uk/sandjam/2010/05/javascript-variable-names-in-internet-explorer/#comments</comments>
		<pubDate>Tue, 11 May 2010 11:14:14 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Code Chat]]></category>
		<category><![CDATA[internet explorer]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=192</guid>
		<description><![CDATA[The more I work with JavaScript the more I enjoy it. One of the things I like best is that it is a front-end language where you generally don&#8217;t have to worry about cross-browser compatibility. It usually just works&#8230; Usually&#8230; This one tripped me up and it took me a...]]></description>
				<content:encoded><![CDATA[<p>The more I work with JavaScript the more I enjoy it. One of the things I like best is that it is a front-end language where you generally don&#8217;t have to worry about cross-browser compatibility. It usually just works&#8230;</p>
<p>Usually&#8230;</p>
<p>This one tripped me up and it took me a while to pin down what the problem was. Turns out the variable name &#8220;class&#8221; is reserved in IE but not in other browsers (Firefox/Chrome).</p>
<p>My code used a variable to insert a css class onto an element, something like:</p>
<pre class="qoate-code">
var class = "blue";
element.innerHTML = "&lt;span class='" + class + "'&gt;comment&lt;/span&gt;";
</pre>
<p>I think this is because IE allows you to reference the css class of an object through this attribute, rather than using the &#8220;className&#8221; attribute.</p>
<p>I guess this is another example of IE trying to make our lives &#8220;more compatible&#8221; but actually making it hard work for everyone.</p>
<p>I also discovered IE8&#8242;s <a href="http://blogs.msdn.com/jscript/archive/2008/03/13/jscript-debugger-in-internet-explorer-8.aspx">new debugger</a> during this time though which actually tells you where your JS errors lie, rather than just saying &#8220;Line 1 character 2342&#8243;.</p>
<p>Finally something to make a developer&#8217;s life easier in IE!
<div id="runkeeper" title="http://runkeeper.com/user/peterasmith/activity/25780715,-300,-300" style="overflow:hidden; width:600px; height:400px;"></div>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2010/05/javascript-variable-names-in-internet-explorer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RunPeter</title>
		<link>http://sandjam.co.uk/sandjam/2010/04/runpeter/</link>
		<comments>http://sandjam.co.uk/sandjam/2010/04/runpeter/#comments</comments>
		<pubDate>Wed, 07 Apr 2010 12:04:13 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Code Chat]]></category>
		<category><![CDATA[Google Maps]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=119</guid>
		<description><![CDATA[I think Runkeeper is an amazing tool &#8211; I use it when cycling and I think it&#8217;s really interesting to plot your route and analyse your stats. One of the biggest problems I have with it is that an IPhone battery will last maybe 3-4 hours while constantly logging GPS....]]></description>
				<content:encoded><![CDATA[<p>I think <a href="http://runkeeper.com">Runkeeper</a> is an amazing tool &#8211; I use it when <a href="http://sandjam.co.uk/sandjam/category/about-me/cycling/">cycling</a> and I think it&#8217;s really interesting to plot your route and analyse your stats.</p>
<p>One of the biggest problems I have with it is that an IPhone battery will last maybe 3-4 hours while constantly logging GPS. This is fine when running, but on a  bike you might be out all day.</p>
<p>I&#8217;d like to be able to manually drop &#8220;breadcrumbs&#8221; along my way, which will be logged and show my route in real time to friends online.</p>
<p>I&#8217;m not going to pretend I&#8217;ve made a tool that&#8217;s going to compete with runkeeper, this is purely me playing around with the Google Maps API.</p>
<p>I&#8217;m using the Google Gears Geolocation functionality which gets your latitude and longitude either from your browser&#8217;s location settings or your GPS if you are on a mobile device. I&#8217;m using an <a href="http://www.htc.com/www/product/hero/overview.html">HTC Hero</a> which runs the Android operating system, so Google Gears is already bundled. Looks like IPhones don&#8217;t (unsurprisingly!).</p>
<p>I&#8217;m going to try and get it up and running for the <a href="http://sandjam.co.uk/sandjam/2010/02/leeds-to-amsterdam-cycle/">Leeds to Amsterdam ride</a> so that people can track my progress along the way&#8230; should they want to.</p>
<p>Check it out: <a href="http://sandjam.co.uk/runpeter/">http://sandjam.co.uk/runpeter/</p>
<p></a>and</p>
<p><a href="../../runpeter/add/">http://sandjam.co.uk/runpeter/add/</a></p>
<p>(You will need to <a href="http://gears.google.com/">install Google Gears</a> on your machine to use it)
<div id="runkeeper" title="http://runkeeper.com/user/peterasmith/activity/25780715,-300,-300" style="overflow:hidden; width:600px; height:400px;"></div>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2010/04/runpeter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Runkeeper WordPress Plugin</title>
		<link>http://sandjam.co.uk/sandjam/2010/04/runkeeper-wordpress-plugin/</link>
		<comments>http://sandjam.co.uk/sandjam/2010/04/runkeeper-wordpress-plugin/#comments</comments>
		<pubDate>Tue, 06 Apr 2010 07:36:45 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Code Chat]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[runkeeper]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=96</guid>
		<description><![CDATA[The Runkeeper plugin for WordPress lets you embed a preview of your activities in to posts using a custom field or shortcode. Take a look at an Example of the plugin in action. Version 2.0 The new version offers two options for adding maps in to posts: Create a custom...]]></description>
				<content:encoded><![CDATA[<p>The Runkeeper plugin for WordPress lets you embed a preview of your activities in to posts using a custom field or shortcode.</p>
<p>Take a look at an <a title="Example Runkeeper Post" href="http://sandjam.co.uk/sandjam/2012/08/example-runkeeper-post/">Example of the plugin in action</a>.</p>
<h2>Version 2.0</h2>
<p>The new version offers two options for adding maps in to posts:</p>
<ul>
<li>Create a custom field called<strong> &#8220;runkeeper&#8221;</strong> and paste in the &#8220;Share&#8221; link from your activity on Runkeeper</li>
<li>Use the shortcode <strong>[runkeeper url="example"]</strong> at any point in your post where you would like the map to appear, replacing &#8220;example&#8221; with the &#8220;Share&#8221; link from Runkeeper.</li>
</ul>
<p>The new version also allows you to change the width, height and offset of the preview using the Settings page. Go to <strong>Settings &gt; Runkeeper</strong> in the admin menu. The default values are: Width: 600px, Height: 400px, X: 300px, Y: 300px</p>
<p><a href="http://wordpress.org/extend/plugins/runkeeper-plugin/" class="button blue" target="_blank"><span>Find Out More and Download</span></a></p>
<h2>Custom Fields in Posts</h2>
<p>If you&#8217;ve not used custom fields in your posts before, it&#8217;s really simple.</p>
<p>When you add a new post, look down the page to the section called <strong>&#8220;Custom Fields&#8221;</strong>. Click <strong>&#8220;Enter New&#8221;</strong>, then add the &#8220;Name&#8221; &#8220;runkeeper&#8221; and the value is the address of the activity you want to embed. If you don&#8217;t have the <strong>Custom Fields</strong> section on the page, you may need to select it from the <strong>Screen Options</strong> menu in the top right.</p>
<p>Take a look at the example below.</p>
<p><img class="alignnone size-full wp-image-259" title="Custom field example" src="http://sandjam.co.uk/sandjam/wp-content/uploads/2010/04/field.png" alt="" width="600" height="162" /></p>
<h2>Shortcodes</h2>
<p>Shortcodes are tags enclosed in square brackets which can be entered anywhere in the post. When the post is displayed on the front end, the shortcode will be replaced with dynamic content, in this case a Runkeeper map.</p>
<p>An example shortcode for the Runkeeper plugin is:</p>
[runkeeper url="http://runkeeper.com/user/peterasmith/activity/25780715"]
<p>&nbsp;</p>
<h2>Donate</h2>
<p>If you like this plugin, why not donate to help keep this project going.</p>
<form action="https://checkout.google.com/api/checkout/v2/checkoutForm/Merchant/430020626837638" id="BB_BuyButtonForm" method="post" name="BB_BuyButtonForm" target="_top">
<table cellpadding="5" cellspacing="0" width="1%">
<tr>
<td align="right" width="1%" style="vertical-align:top; padding-top:10px; padding-right:1em;">
<select name="item_selection_1">
<option value="1">£5.00 - Much appreciated</option>
<option value="2">£3.00 - Better than nothing</option>
<option value="3">£10.00 - Very kind, thanks</option>
</select>
<p>                <input name="item_option_name_1" type="hidden" value="Much appreciated"/>                <input name="item_option_price_1" type="hidden" value="5.0"/>                <input name="item_option_description_1" type="hidden" value=""/>                <input name="item_option_quantity_1" type="hidden" value="1"/>                <input name="item_option_currency_1" type="hidden" value="GBP"/>                <input name="shopping-cart.item-options.items.item-1.digital-content.description" type="hidden" value="Thanks for the donation, you're helping to keep the internet working and making everyone feel good."/>                <input name="shopping-cart.item-options.items.item-1.digital-content.url" type="hidden" value="http://sandjam.co.uk/sandjam/portfolio/post-snippits-wordpress-plugin/"/>                <input name="item_option_name_2" type="hidden" value="Better than nothing"/>                <input name="item_option_price_2" type="hidden" value="3.0"/>                <input name="item_option_description_2" type="hidden" value=""/>                <input name="item_option_quantity_2" type="hidden" value="1"/>                <input name="item_option_currency_2" type="hidden" value="GBP"/>                <input name="shopping-cart.item-options.items.item-2.digital-content.description" type="hidden" value="Thanks for the donation, you're helping to keep the internet working and making everyone feel good."/>                <input name="shopping-cart.item-options.items.item-2.digital-content.url" type="hidden" value="http://sandjam.co.uk/sandjam/portfolio/post-snippits-wordpress-plugin/"/>                <input name="item_option_name_3" type="hidden" value="Very kind, thanks"/>                <input name="item_option_price_3" type="hidden" value="10.0"/>                <input name="item_option_description_3" type="hidden" value=""/>                <input name="item_option_quantity_3" type="hidden" value="1"/>                <input name="item_option_currency_3" type="hidden" value="GBP"/>                <input name="shopping-cart.item-options.items.item-3.digital-content.description" type="hidden" value="Thanks for the donation, you're helping to keep the internet working and making everyone feel good."/>                <input name="shopping-cart.item-options.items.item-3.digital-content.url" type="hidden" value="http://sandjam.co.uk/sandjam/portfolio/post-snippits-wordpress-plugin/"/>            </td>
<td align="left" width="1%">                <input alt="" src="https://checkout.google.com/buttons/buy.gif?merchant_id=430020626837638&w=117&h=48&style=white&variant=text&loc=en_US" type="image"/>            </td>
</tr>
</table>
</form>
<div id="runkeeper" title="http://runkeeper.com/user/peterasmith/activity/25780715,-300,-300" style="overflow:hidden; width:600px; height:400px;"></div>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2010/04/runkeeper-wordpress-plugin/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
		<item>
		<title>Leeds to Amsterdam Cycle</title>
		<link>http://sandjam.co.uk/sandjam/2010/02/leeds-to-amsterdam-cycle/</link>
		<comments>http://sandjam.co.uk/sandjam/2010/02/leeds-to-amsterdam-cycle/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 12:39:40 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[Cycling]]></category>

		<guid isPermaLink="false">http://sandjam.co.uk/sandjam/?p=15</guid>
		<description><![CDATA[Keep up to date with this year's expedition: 200 mile round trip from Leeds to Amsterdam by bike.]]></description>
				<content:encoded><![CDATA[<p>Last year we made from Leeds to Liverpool along the Leeds Liverpool canal on our bikes. Really enjoyed ourselves, so decided that this year&#8217;s challenge should be from Leeds to Amsterdam!</p>
<h2>Leeds to Hull</h2>
<p>Set off at 10am on Friday from Leeds city centre. Weather looks promising and we made it to Selby in good time and spirits (25 miles). After lunch we join the Trans-Pennine trail eastwards to Hull. Nice route, well signed and over a lovely sunny afternoon we couldn&#8217;t ask for anything more.</p>
<p>Unfortunately, as we arrived at the outskirts of Hull it turned out that the route was going to be a bit longer than we expected and worst, the heavens opened. The last hour of the ride through Hull to the port was wet and not very pretty.</p>
<p>Leeds to Hull &#8211; 72 miles</p>
<h2>Rotterdam to Amsterdam</h2>
<p>Day two brought us a morning of rain, and setting off on the wrong foot found us a bit lost cycling through Europort. It&#8217;s around 25 miles to get to Rotterdam city from the port, which took us the morning in the rain. Pretty miserable by time we got there, but decided to press on and luckily it brightened up after lunch.</p>
<p>It&#8217;s no surprise that the cycle routes in Holland are just amazing &#8211; well signed, big and well kept. Some of the cycle paths in Holland are in better nick than some of the roads in Leeds! The route out of Rotterdam takes you North past canals and windmills, through pretty villages and fields. The wind can be a bit rough over the flat open fields, but the good news is there are no hills to contend with! The slightly longer route can take you through Gouda but at that stage we didn&#8217;t want to make things more difficult for ourselves.</p>
<p>My rough measurements on Google Maps had placed the route at around 60 miles. The final count came out nearer 84, which was a bit of a shock. It was hard work and we arrived in Amsterdam around 7pm. A long day, but so rewarding when we made it there.</p>
<p>We stayed at the <a href="http://www.hotel-hestia.nl/">Hotel Hestia</a> which I can&#8217;t recommend highly enough &#8211; very reasonable and great homely quality.</p>
<h2>Amsterdam to Rotterdam</h2>
<p>The next day was forecast to be rainier still so we decided to have a good night out then get the train back to Rotterdam. We still had the ride to Europort to deal with, which was a pretty wet affair. Found the cycle route to the port though, which certainly was better that the route through in the industrial estates on the way out.</p>
<h2>Hull to Leeds</h2>
<p>We were all worn out by this point, but the last leg was straight forward enough. Dry, but an awful wind which made for hard riding.</p>
<p>Overall, I&#8217;d really recommend the ride &#8211; it would have been loads better if we&#8217;d had sun all the way but you can make the best of it either way. The next question is&#8230; where next?
<div id="runkeeper" title="http://runkeeper.com/user/peterasmith/activity/25780715,-300,-300" style="overflow:hidden; width:600px; height:400px;"></div>
]]></content:encoded>
			<wfw:commentRss>http://sandjam.co.uk/sandjam/2010/02/leeds-to-amsterdam-cycle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
