<?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>Numiko Labs</title>
	<atom:link href="http://numiko.com/labs/feed/" rel="self" type="application/rss+xml" />
	<link>http://numiko.com/labs</link>
	<description>Notes and inspiration, fresh from our studio.</description>
	<lastBuildDate>Tue, 11 Dec 2012 17:17:18 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Top 5 Photoshop Tips for Designers Starting Out</title>
		<link>http://numiko.com/labs/2012/12/photoshoptips/</link>
		<comments>http://numiko.com/labs/2012/12/photoshoptips/#comments</comments>
		<pubDate>Tue, 11 Dec 2012 17:15:10 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://numiko.com/labs/?p=464</guid>
		<description><![CDATA[Let’s face it; Photoshop is the tool of the trade and something no designer should be without today. The unrivalled power within that harbours the potential to create stunning visuals is not easy to master; however, there are plenty of tricks at your disposal to help you get by. With the year nearly behind us,...  <a href="http://numiko.com/labs/2012/12/photoshoptips/" title="Read Top 5 Photoshop Tips for Designers Starting Out">Read more &#187;</a>]]></description>
				<content:encoded><![CDATA[<p>Let’s face it; Photoshop is the tool of the trade and something no designer should be without today. The unrivalled power within that harbours the potential to create stunning visuals is not easy to master; however, there are plenty of tricks at your disposal to help you get by.</p>
<p>With the year nearly behind us, the designers at Numiko have huddled together to bring Christmas around early. Their gift to you is an indispensable guide to Photoshop containing priceless tips you’ll soon be unable to live without!</p>
<p><strong>Stay smart with Smart Objects</strong><br />
One of the most common issues we face within web design today is the duplication of modular content. Up until the release of Adobe Photoshop CS2, designers had to make multiple copies of individual page assets if they needed to appear on different templates.</p>
<p>While you could argue there is nothing wrong with this type of workflow, problems begin to arise when amends fly into your inbox. Whether it was a change in colour, typography or even the shape and size of a module; designers adopting this workflow would have to ensure they carefully amended each duplicated asset. Something far from ideal, given there could be countless instances of this module spanning multiple pages.</p>
<p>More recent versions of Photoshop take away this troublesome task of repeating the same change(s) multiple times with the introduction of smart objects.</p>
<p>Smart objects are effectively smaller Photoshop documents nested within your main Photoshop document. A selection of layers or a folder within your existing document can be converted into a smart object by right clicking the desired layers and selecting ‘Convert to smart object’. Once you have a smart object, double clicking on the layer’s icon will open an additional window which contains the nested file’s contents. Upon making any changes to this new window and saving, the nested document will then update itself in your main Photoshop document.</p>
<p>So how does this differ from our problem presented above? Upon saving, the updated contents of any smart object will then update any duplicated instances of it too. This means you could have, for example, five copies of a footer duplicated over multiple templates, all of which will only need to be edited and updated once.</p>
<p><strong>Control your Layer Comps</strong><br />
As time goes on, the structure of your Photoshop documents will begin to grow more complex. With a plethora of page templates to consider, you better hope you have an organised method of keeping each one easily accessible and under control.</p>
<p>Most designers today tend to arrange their layers into carefully labelled folders, calling upon each one when required by changing its visibility. This, however, is a rather inefficient way of working when Layer Comps are just around the corner.</p>
<p>Layer Comps are the solution to getting every single layer related to a single page template or design visible with a single click. With Photoshop open and your latest design in front of you, heading to Window &amp;gt; Layer Comps is your first step. Next up, clicking the new Layer Comp icon at the bottom of this panel will prompt you to name your currently visible template. This will then make a note of which layers are currently visible (and invisible) and make an entry in the Layer Comps panel for later use.</p>
<p>From here just a single click on any empty square to the left of a template’s name in the Layer Comps window will hide any unrelated layers and make anything belonging to that template visible. Gone are the days of hiding and showing the layers manually &#8211; simply create a Layer Comp for each page you design and you’ll be laughing. Just remember you’ll need to click the update button with your Layer Comp selected every time you’re ready to commit your amends to it.</p>
<p>This, however, is not where Layer Comps end.</p>
<p>There is one more incredibly handy function. Deep within File &amp;gt; Scripts lies the ultimate solution to preparing your work for approval and client send off – Layer Comps to files. This script will simply run through your page templates that have been added to the Layer Comps panel and export them to your hard drive. The output will be in a file format of your choice, with the filename of each template inherited from each Layer Comp.</p>
<p>Organisation is the key!</p>
<p><strong>Be Non Destructive</strong><br />
With tools such as the Paint bucket, Eraser and the Smudge cursor, Photoshop was intended to be a messy affair. While these elements of destruction do offer a great flexibility to creating pixel perfect assets, working in a non-destructive workflow has its advantages too.</p>
<p>To define non-destructive in Photoshop terms: it’s the act of using any supplied assets or imagery without editing them directly. There are obviously times where you’ll need to retouch a photograph by adding sombreros to a row of gleeful cats, but all other editing should be done without touching the original file if possible.</p>
<p>Take for example a client supplied image that needs to fit into a homepage carousel. Chances are the image will be too tall, too wide or even both. This, however, is a good thing that can work to your advantage.</p>
<p>Simply create a new solid colour layer or shape layer below, one which is exact the size you’d like your supplied asset to be. From here, right click the asset’s layer and select Create clipping mask. This will make the asset only show through the available pixels of the layer below. This allows you to freely move around the image in any way you wish within the designated space, without needing to cut off (and destruct) any unwanted imagery.</p>
<p>If you’d prefer to keep everything within one layer though, take a look at alpha channels. They offer exactly the same functionality too.</p>
<p>Why’s this a good thing then? Well should any amends fly through the door asking for a previously hidden area of the asset to be made visible, that’s something you can do without needing to open the original file again. It’s still intact within your document and awaiting changes.</p>
<p>You could then take this tip a step further by reading on…</p>
<p><strong>Keep key graphical elements in Smart Objects</strong><br />
When designing a website in Photoshop, every single element that is associated to that design – whether it is client logos, affiliate branding or even imagery – should be present in its original form. This grants developers who are coding your design or clients who require Photoshop documents to be supplied, access to everything they need within one file.</p>
<p>To achieve this, the best practice is to import any asset at its full size into your document and then convert it to a Smart Object before use. Should anyone need to get hold of this asset, it can then easily be found in the same place all your other assets are: within the Photoshop document.</p>
<p>Aside from being more organised and prepared for handovers, there is another advantage to being smart. Take this request for example: “make our logo twice as large”.</p>
<p>A common request to face, but a fatal one should you have misplaced the original asset. This is nothing to worry about when Smart Objects are in place. As all the original data from an individual asset still exists within a Smart Object, you can transform away, whilst maintain quality.</p>
<p><strong>Save and save often!</strong><br />
Sadly, the last but most important Photoshop tip of all is the one we all learn a little too late. The Adobe-software-crash-devil which drags your hard work down to the depths of unrecoverable computer hell rears his ugly side all too often. The more infuriating aspect to Photoshop crashing (frequently) is knowing full well that Save was just a few clicks away and available all along – something you didn’t utilise in time.</p>
<p>To keep the crashes at bay, we’d very much recommend saving into new files each time round. For example, the brand new template featuring that sparkly and clean header you’ve just spent a few hours on, save that as Design-v2.psd instead of overwriting. By working in multiple files, you have the ability to travel back in time should you need to revisit an earlier version of your creation for whatever reason.</p>
<p>Whilst we’d like to consider ourselves Photoshop gurus (at least our <a href="http://numiko.com/#/projects">portfolio</a> suggests so!), there&#8217;s always room for improvement. Feel free to share your very own Photoshop tips in the comments box.</p>
]]></content:encoded>
			<wfw:commentRss>http://numiko.com/labs/2012/12/photoshoptips/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Static Drupal Sites for High Traffic</title>
		<link>http://numiko.com/labs/2012/12/static-drupal-sites-for-high-traffic/</link>
		<comments>http://numiko.com/labs/2012/12/static-drupal-sites-for-high-traffic/#comments</comments>
		<pubDate>Thu, 06 Dec 2012 11:11:50 +0000</pubDate>
		<dc:creator>Andy Tawse</dc:creator>
				<category><![CDATA[drupal]]></category>
		<category><![CDATA[server-side]]></category>
		<category><![CDATA[high performance]]></category>
		<category><![CDATA[s3]]></category>

		<guid isPermaLink="false">http://numiko.com/labs/?p=418</guid>
		<description><![CDATA[We recently created the Stand Up To Cancer website for Channel 4. I&#8217;m going to talk about the technical challenges involved in creating a site to support a high profile, one-off broadcast like this. Unlike a TV series where problems can be ironed out as the weeks pass, there was only chance to get it...  <a href="http://numiko.com/labs/2012/12/static-drupal-sites-for-high-traffic/" title="Read Static Drupal Sites for High Traffic">Read more &#187;</a>]]></description>
				<content:encoded><![CDATA[<p>We recently created the <a href="http://su2c.channel4.com">Stand Up To Cancer website</a> for Channel 4. I&#8217;m going to talk about the technical challenges involved in creating a site to support a high profile, one-off broadcast like this. Unlike a TV series where problems can be ironed out as the weeks pass, there was only chance to get it right, and with the public donating to an important cause the site had to stay up.</p>
<p>We love Drupal and we needed content management. The question was &#8211; how can we serve potentially thousands of pages a second? The answer was &#8211; not with Drupal! We needed to move beyond standard Drupal caching, and beyond even the excellent <a href="http://drupal.org/project/boost">Boost module</a>. Instead, our Drupal module publishes pages to <a href="http://aws.typepad.com/aws/2011/02/host-your-static-website-on-amazon-s3.html">Amazon S3</a> and this acts as the origin for a heavily CDN-cached site that can be edited like any other content managed site.</p>
<p>By serving static pages and not touching Drupal at all we removed a lot of potential problems &#8211; complex server setup, strange database errors, the <a href="http://drupal.org/node/158043">White Screen of Death</a> &#8211; that are possible when a complex, database-heavy site comes under severe strain.</p>
<h2>Our Caching Module</h2>
<p>Our module takes inspiration from Boost by saving a static copy of a page during the exit hook. But where we differ is that this happens on a &#8220;crawl&#8221; of the site that is itself initiated in the exit hook, triggered by a flag set by a node delete, insert or update hook. So the basic flow is:</p>
<ul>
<li>content editor saves a node</li>
<li>in hook_exit() we start the crawl &#8211; requests to the current node and any related pages are made using drupal_http_request() with an added querystring parameter</li>
<li>now in the separate request, the querystring parameter is detected and during hook_exit() we save the contents of the output buffer to S3</li>
</ul>
<p>This separate request allows us the view the page once it&#8217;s completely built (rather than during the request that created it) and to get its content as an anonymous user.</p>
<p>A page doesn&#8217;t exist in isolation so related pages need to be kept up to date. Fortunately, on this site related pages meant taxonomy View lead pages for media nodes and not much else. This meant we could hardcode the logic for this on a case-by-case basis. For a more complex site many more pages (or the whole site) may need to be republished when one page changes.</p>
<p>We also added a &#8220;Publish whole site&#8221; option that crawled all nodes of a certain type and various other lead pages that were not nodes &#8211; useful if site-wide changes were made or if anything went wrong with the publish process.</p>
<p>Indeed, error handling paramount and was important to allow fast diagnosis of any problems on the night. Thankfully there were no major problems, but detailed logging meant I could monitor usage by content editors and be reassured that everything was working. In unpredictable situations like this &#8211; high traffic, contacting external systems, live TV broadcast! &#8211; log as much relevant data as you can (while keeping it manageable &#8211; there&#8217;s no point having an overwhelming amount of data that&#8217;s impossible to understand quickly).</p>
<h2>S3</h2>
<p>At first I thought it would be a good idea to <a href="http://code.google.com/p/s3fs/wiki/FuseOverAmazon">mount S3 locally</a> so that I could transparently use normal filesystem functions to deal with the static files. Turns out that due to the way S3 deals with directories (or doesn&#8217;t, it doesn&#8217;t really have a concept of directories) this was unreliable. The official Amazon S3 class is really nice to use anyway:</p>
<pre class="brush: php; title: ; notranslate">
    $response = $s3-&gt;create_object(
      $bucket,
      $filename,
      array(
        &quot;acl&quot;=&gt;AmazonS3::ACL_PUBLIC,
        &quot;body&quot;=&gt;$data,
        &quot;contentType&quot;=&gt;&quot;text/html&quot;,
        &quot;headers&quot;=&gt;array(
          &quot;Cache-Control&quot;=&gt;&quot;public, max-age=&quot; . $html_cache_control
        )
      )
    );
</pre>
<p>This saves the $data to S3 as the correct content type, setting permissions and the cache header to work with the CDN. We made cache max-age times for various objects configurable through the Drupal interface for easy tweaking.</p>
<h2>Assets</h2>
<p>We used the Drupal <a href="http://drupal.org/project/amazons3">S3 module</a> so that CMS-uploaded assets were sent to S3 as well. We&#8217;ve used this in the past and it transparently deals with this for us.</p>
<p>One image-related difficulty was that some generated images hadn&#8217;t been saved to S3 by the time the caching module saved the HTML, resulting in references to images on the Drupal server. We didn&#8217;t want this under any circumstances so at first I stopped any page with a local image URL being published and returned an error. Later, it became obvious that the best solution was to brute-force replace all offending paths in the HTML with the S3 one &#8211; eventually the image would be generated.</p>
<h2>Frequent Updated Content</h2>
<p>Some of content needed to be more dynamic &#8211; the home page live feed and the total amount raised on the right-hand column. For these we had a separate publishing mechanism. Data was published to JSON files (again to S3) when content was updated and these were loaded regularly and interpreted by the front end. In this way key content could be kept fresh while the bulk of the site was cached for longer periods.</p>
<h2>On the Night</h2>
<p>So with S3 and Akamai taking care of the end-user traffic, Drupal was left untouched by the general public, removing most of the worries that come when a site is released into the wild for the first time. We think taking the principle of the Boost module one step further and publishing on-demand to an external server gives us the right trade-off between performance and flexibility for a site like this, and didn&#8217;t require a huge investment in setup time.</p>
]]></content:encoded>
			<wfw:commentRss>http://numiko.com/labs/2012/12/static-drupal-sites-for-high-traffic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Field Collection Import/Export in Drupal 7</title>
		<link>http://numiko.com/labs/2012/07/field-collection-importexport-in-drupal-7/</link>
		<comments>http://numiko.com/labs/2012/07/field-collection-importexport-in-drupal-7/#comments</comments>
		<pubDate>Fri, 13 Jul 2012 16:49:54 +0000</pubDate>
		<dc:creator>Andy Tawse</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://numiko.com/labs/?p=413</guid>
		<description><![CDATA[The Field Collection module has become essential to our work with Drupal, allowing us to create &#8220;compound&#8221; fields &#8211; fields within fields. When using the Node Export module to export nodes from one Drupal instance to another, Node Export doesn&#8217;t provide a way to transfer the field collection data. It turns out that it&#8217;s easy...  <a href="http://numiko.com/labs/2012/07/field-collection-importexport-in-drupal-7/" title="Read Field Collection Import/Export in Drupal 7">Read more &#187;</a>]]></description>
				<content:encoded><![CDATA[<p>The Field Collection module has become essential to our work with Drupal, allowing us to create &#8220;compound&#8221; fields &#8211; fields within fields. When using the Node Export module to export nodes from one Drupal instance to another, Node Export doesn&#8217;t provide a way to transfer the field collection data. It turns out that it&#8217;s easy to programmatically import and export field collection instances though. This will export all the field collections on a site and store them in an array:</p>
<pre class="brush: php; title: ; notranslate">
  $rows = db_query(&quot;SELECT * FROM field_collection_item;&quot;)-&gt;fetchAll();

  $export = $all_ids = array();

  foreach($rows as $row){
    $all_ids[] = $row-&gt;item_id;
  }

  $items = entity_load(&quot;field_collection_item&quot;, $all_ids);

  foreach($items as $item){
    $export[] = $item-&gt;export();
  }
</pre>
<p>This is thanks to the field collection entity&#8217;s controller class EntityAPIController implementing a handy export() method.</p>
<p>Then to import a field collection exported to $export_str:</p>
<pre class="brush: php; title: ; notranslate">
  $con = new EntityAPIController(&quot;field_collection_item&quot;);
  $entity = $con-&gt;import($export_str);
  $con-&gt;save($entity);
</pre>
<p>The exported JSON contains an item_id. If you unset this the collection will be saved with a new item_id (generally a good idea) but there are some circumstances where you might want to import the field collection with its original ID (this will maintain the references to the field collections host but be careful!)</p>
<p>Importing and exporting is never fun with Drupal but the above code should help with any tasks (in my case populating a site with test data needed by Selenium tests) that require field collections to be moved between sites.</p>
]]></content:encoded>
			<wfw:commentRss>http://numiko.com/labs/2012/07/field-collection-importexport-in-drupal-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Designing and developing for interactive whiteboards</title>
		<link>http://numiko.com/labs/2012/05/designing-and-developing-for-interactive-whiteboards/</link>
		<comments>http://numiko.com/labs/2012/05/designing-and-developing-for-interactive-whiteboards/#comments</comments>
		<pubDate>Mon, 21 May 2012 16:05:27 +0000</pubDate>
		<dc:creator>tom</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[education]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[interactive whiteboards]]></category>
		<category><![CDATA[kids]]></category>
		<category><![CDATA[UX]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[design]]></category>

		<guid isPermaLink="false">http://numiko.com/labs/?p=388</guid>
		<description><![CDATA[I’m writing this partly as a note to myself, but also in the hope it’ll help others too. We’ve recently been developing a few games and activities for interactive whiteboards, and found that they have a few kinks that it can be hard to keep track of during the design and dev process. So I...  <a href="http://numiko.com/labs/2012/05/designing-and-developing-for-interactive-whiteboards/" title="Read Designing and developing for interactive whiteboards">Read more &#187;</a>]]></description>
				<content:encoded><![CDATA[<p>I’m writing this partly as a note to myself, but also in the hope it’ll help others too.</p>
<p>We’ve recently been developing a few games and activities for interactive whiteboards, and found that they have a few kinks that it can be hard to keep track of during the design and dev process. So I thought I’d try and put down everything we’ve learned in one place.</p>
<p><strong>Avoid putting critical controls in the top third of the screen. </strong>The majority of your audience is kids – kids who are still growing, and often aren’t tall enough to reach up to the top of a whiteboard. It’s also important for accessibility for people in wheelchairs who might not be able to reach as high as others. Schools install their whiteboards at different heights too, so keep any essential controls low on the screen if you want them to be accessible.</p>
<a href="http://numiko.com/labs/wp-content/uploads/2012/05/whiteboard_small_kids.jpg"><img title="Small kids can't reach the top!" src="http://numiko.com/labs/wp-content/uploads/2012/05/whiteboard_small_kids.jpg" alt="" width="470" height="219" /></a>
<p>Controls that are used by the teacher, like mute, are fine to go nearer the top as the kids don’t need to be able to reach them – in fact, some controls are probably best kept out of the reach of meddling kids anyway to avoid accidental quitting or restarting.</p>
<p>Lots more whiteboard development tips after the jump&#8230;</p>
<p><span id="more-392"></span></p>
<p><strong>Keep text over a certain size if you want it to be read by a class. </strong>There are loads of different modes of use to consider when you’re designing for education: solo use at a computer, groups round a laptop, child using a whiteboard, teacher teaching from a whiteboard…</p>
<p>Important text needs to be large enough so it can be read by children in a classroom. What needs to be legible depends on the content and the lesson, so it’s difficult to lay down hard and fast rules, but you should be able to identify key information.</p>
<a href="http://numiko.com/labs/wp-content/uploads/2012/05/whiteboard_class.jpg"><img class="alignnone size-full wp-image-405" title="Small whiteboard, big classroom" src="http://numiko.com/labs/wp-content/uploads/2012/05/whiteboard_class.jpg" alt="" width="470" height="262" /></a>
<p>Conversely (depending on your users) too much over-large text can make content for older children feel too kiddy, which will turn them off it quicker than you can write out “I will research my audience” a hundred times.</p>
<p>Personally, I’ve always thought that lessons where the teacher just read stuff off a screen were deathly dull, so maybe think about how you can help the teacher present information in a more interesting way than a big wall of text. That’s just my opinion, though!</p>
<p><strong>Keep colour contrast high. </strong>Whiteboard content needs to work in all manner of classrooms, which will probably vary from dank dungeons to bright-as-the-sun computer labs. There are colour contrast checker tools that make this easy, if time-consuming. Plan for it, and do it while you’re designing, because there’s nothing more annoying than having to go back through all your designs and change everything, again.</p>
<a href="http://numiko.com/labs/wp-content/uploads/2012/05/whiteboard_contrast.jpg"><img class="alignnone size-full wp-image-403" title="Contrast problems in a well-lit classroom" src="http://numiko.com/labs/wp-content/uploads/2012/05/whiteboard_contrast.jpg" alt="" width="470" height="203" /></a>
<p>Consider including high-visibility modes to help teachers who have crappy low contrast projectors or sunny windows with no curtains.</p>
<p>Don’t make people scroll. Keeping everything on screen at once will make thing easier for teachers, because scrolling means locating the scroll bar and dragging your finger down the board, rather than a quick click of the mouse. If you really do need to scroll, think about how you can minimise the pain – for example, “proper” touchscreen interfaces let you scroll by dragging any point on the screen.</p>
<p><strong>The option to go full-screen is good.</strong> It helps teachers focus the class on the content rather than what’s in their bookmarks or any other screen clutter.</p>
<p><strong>An interactive whiteboard is basically a big touchscreen,</strong> and it’s worth bearing that in mind when you’re planning functionality<strong>.</strong> A lot of traditional web HTML content is fine, but for more interactive elements it’s easy to trip yourself up by designing for a single user with a mouse and keyboard. If you’ve got guidelines for designing for iPad then take a look at those because they’re probably relevant – just don’t go too far the other way and neglect the needs of your desktop users.</p>
<p>The touchscreen interface has some important implications:</p>
<p><strong>There’s no mouse cursor.</strong> Well, there kind of is, but not in the way it works on a desktop. When you put your finger on the whiteboard the cursor will jump to that point and simulate a mouse button press. Release your finger and you’ll get a mouse button release. Otherwise the cursor will just sit in the same spot until you interact.</p>
<p><strong>You can’t hover over things on a whiteboard.</strong> This means no mouse over events, so no interactions on rollover. Don’t rely on rollover popups to deliver information, because they ain’t happening.</p>
<p>When you’ve pressed you can drag the cursor around, which will probably display rollovers (depending on how you’ve coded them) but this behaviour seems inconsistent across different brands and is not obvious to the user.</p>
<p>Similarly, don’t rely on being able to tell when the user has moved their mouse out of something, or even “moved the mouse” at all. It seems obvious, but those events are so common in desktop apps that it’s easy to forget about them. On an interactive whiteboard, there is no mouse. And no-one can hear you scream because your app relies on rollovers and now you have to change it all.</p>
<p><strong>Beware press and hold.</strong> On some models of IWB (but not all) pressing and holding in one place for a few seconds will be interpreted as a right-mouse-button click. Maybe that’s what you want – but it probably isn’t.</p>
<p><strong>Fingers are less precise than a mouse cursor (and more chunky).</strong> When you’re used to the sensitive, high-spec interface of an iPhone it’s not as obvious, but for uncoordinated kids using a crappy old unbranded whiteboard it can be an issue. Make sure that hit areas are big enough for fingers and well-defined, with as little overlap or confusion as possible. I know that’s good advice generally, but it goes double for a whiteboard.</p>
<p>The minimum suggested hit area for mobile is 50px (I imagine this varies by device etc) – there’s no standard for whiteboards as far as I can tell, but just bear this in mind.</p>
<p>The user’s hand and arm will likely block some of their view of the screen when they reach to interact; showing critical information right below where someone’s interacting will require them to bend their arm or head in an uncomfortable way to spot the cue – if they don’t miss just it altogether. Some whiteboards use overhead projectors which can make the problem even worse by making your entire body cast a shadow.</p>
<a href="http://numiko.com/labs/wp-content/uploads/2012/05/whiteboard_shadow.jpg"><img class="alignnone size-full wp-image-404" title="Casting a big shadow" src="http://numiko.com/labs/wp-content/uploads/2012/05/whiteboard_shadow.jpg" alt="" width="470" height="258" /></a>
<p>Some whiteboards will have whiteboard pens, which will give a more precise interaction area and additional controls, but as with most things here it’s best to not assume that classrooms will have the latest, shiniest equipment. Whiteboard pens sometimes contain widgets that make the board interpret them differently as well, which may cause unexpected behaviour.</p>
<p><strong>It takes more effort to move around a whiteboard.</strong> When you’re using a mouse, moving to the other side of the screen is a mere flick of the wrist. But on a whiteboard, dragging something from the left to the right involves keeping your finger firmly on the screen and moving your arm (and probably your whole body) a metre or so.</p>
<p>Whiteboards can be very unresponsive, so if your activity includes fast or precise movement bear that in mind. Some brands are pretty bad at detecting taps occurring close together in time (eg double clicking).</p>
<p><strong>Testing is difficult.</strong> Different brands of whiteboard offer hugely varied levels of contrast, responsiveness, types of interaction and all kinds of other totally non-obvious stuff. It’s relatively common to encounter those most premature-hair-greying of bugs: something to do with a specific piece of hardware that you don’t have access to.</p>
<p>There’s not much you can do about this except be aware of it and try to build resilient, flexible apps that can be easily tweaked if it looks like a specific thing is causing a problem.</p>
<p>We had trouble when a client’s whiteboard showed weird text distortion artefacts and serious unresponsiveness when ours was completely fine. This mysteriously fixed itself after a day or so, which was just as well because we had no idea what was causing it and no way of fixing it.</p>
<p><strong>The people who are testing your content are probably not teachers.</strong> Unless they are, in which case it’s fine. But it’s possible that some errors are coming up because the person doing the testing is unfamiliar with interactive whiteboards. This sounds like a bit of a cop-out, but all child interaction with the board will be teacher-moderated, or at least guided, and most teachers will have experience with boards in general (and specifically the quirks of <em>their</em> board).</p>
<p>It’s not something to rely on, but it is worth bearing in mind when you’re bug-hunting. For example: almost all teachers use fingers to interact and pens to write with on the board &#8211; that&#8217;s how they&#8217;re designed to work. But our testers were using the pens to interact with all the content, which was throwing up some weird results.</p>
<p><strong>Celebrate the teacher!</strong> This ties into the “too much crap on screen is boring” bit. You may or may not actually get a say in what the content is that you’re creating, or how it works, but if you do then try to make something that lets the teacher teach, rather than just be a drone who exists only to click through a slideshow.</p>
<p>Use interactivity, audio, quizzes and reveals to make something that can help the teacher inspire their class. There’s a wealth of information online about what makes good teaching content, so check that out, look at presentation skills and information and talk to teachers. The teachers will appreciate it, and so will their pupils!</p>
]]></content:encoded>
			<wfw:commentRss>http://numiko.com/labs/2012/05/designing-and-developing-for-interactive-whiteboards/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Programmatically adding a node reference field to a type in Drupal 7</title>
		<link>http://numiko.com/labs/2011/12/programmatically-adding-a-node-reference-field-to-a-type-in-drupal-7/</link>
		<comments>http://numiko.com/labs/2011/12/programmatically-adding-a-node-reference-field-to-a-type-in-drupal-7/#comments</comments>
		<pubDate>Thu, 22 Dec 2011 12:40:25 +0000</pubDate>
		<dc:creator>Andy Tawse</dc:creator>
				<category><![CDATA[drupal]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://numiko.com/labs/?p=381</guid>
		<description><![CDATA[It wasn&#8217;t obvious how I could add new node reference fields to a content type. I had to work it out from node_reference_field_info() and from examining existing fields with field_info_field(). After some experimentation, this worked: &#8220;gallery_image&#8221; is the machine name of the type that will be referenced by the field &#8211; put as many in...  <a href="http://numiko.com/labs/2011/12/programmatically-adding-a-node-reference-field-to-a-type-in-drupal-7/" title="Read Programmatically adding a node reference field to a type in Drupal 7">Read more &#187;</a>]]></description>
				<content:encoded><![CDATA[<p>It wasn&#8217;t obvious how I could add new <a href="http://drupal.org/project/references">node reference</a> fields to a content type. I had to work it out from node_reference_field_info() and from examining existing fields with field_info_field(). After some experimentation, this worked:</p>
<pre class="brush: php; title: ; notranslate">
$field = array(
    &quot;field_name&quot;=&gt;;&quot;field_field_name&quot;,
    &quot;label&quot;=&gt;&quot;Field label&quot;,
    &quot;type&quot;=&gt;&quot;node_reference&quot;,
    &quot;settings&quot;=&gt;array(
      &quot;referenceable_types&quot;=&gt;array(
        &quot;gallery_image&quot;=&gt;&quot;gallery_image&quot;
      ),
    ),
    &quot;cardinality&quot;=&gt;&quot;-1&quot;
  );

  field_create_field($field);

  $instance = array(
    &quot;field_name&quot;=&gt;&quot;field_field_name&quot;,
    &quot;label&quot;=&gt;&quot;Field label&quot;,
    &quot;type&quot;=&gt;&quot;node_reference&quot;,
    &quot;widget&quot;=&gt;array(
      &quot;type&quot;=&gt;&quot;options_select&quot;
    ),
  );

  $instance[&quot;entity_type&quot;] = &quot;node&quot;;

  foreach(array(&quot;type1&quot;, &quot;type2&quot;, &quot;type3&quot;) as $type){
    $instance[&quot;bundle&quot;] = $type;  
    field_create_instance($instance);
  }
</pre>
<p>&#8220;gallery_image&#8221; is the machine name of the type that will be referenced by the field &#8211; put as many in here as you need (yes, the format really is &#8220;machine_name&#8221;=&gt;&#8221;machine_name&#8221;). &#8220;cardinality&#8221; is the number of references in the field, -1 being unlimited. In the example, the field will be added to 3 types &#8211; type1, type2 and type3.</p>
]]></content:encoded>
			<wfw:commentRss>http://numiko.com/labs/2011/12/programmatically-adding-a-node-reference-field-to-a-type-in-drupal-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CSS Specificity Wars</title>
		<link>http://numiko.com/labs/2011/07/css-specificity-wars/</link>
		<comments>http://numiko.com/labs/2011/07/css-specificity-wars/#comments</comments>
		<pubDate>Mon, 18 Jul 2011 17:56:41 +0000</pubDate>
		<dc:creator>James Hyatt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://numiko.com/labs/?p=347</guid>
		<description><![CDATA[Working on a project the other day I came across a problem with some existing CSS where the selectors for basic elements all included the ID&#8217;s for the layout containers. this was causing huge problems when any external mark-up was dropped into the page. The generic styles were already so specfiic that they were over-riding...  <a href="http://numiko.com/labs/2011/07/css-specificity-wars/" title="Read CSS Specificity Wars">Read more &#187;</a>]]></description>
				<content:encoded><![CDATA[<p>Working on a project the other day I came across a problem with some existing CSS where the selectors for basic elements all included the ID&#8217;s for the layout containers.</p>
<pre class="brush: css; title: ; notranslate">
#main #content #inner h3
</pre>
<p>this was causing huge problems when any external mark-up was dropped into the page. The generic styles were already so specfiic that they were over-riding most other CSS styles. Before you know it you needed to tag everything with:</p>
<pre class="brush: css; title: ; notranslate">
#main #content #inner #something .get .my .point
</pre>
<p>to make the styles to cascade properly.</p>
<p>It&#8217;s worth remembering that although</p>
<pre class="brush: css; title: ; notranslate">
#main #content a {color:black}
</pre>
<p>looks fairly innocuous but when you later to need to change the style of an anchor tag you&#8217;ll be stuck needed to add a lot of specification and worse external mark-up, unaware of your overly described selectors will end up being overridden. Before you know it your rules are flowing off the page and every new change requires a train of selectors, tags and classes.</p>
<p>It&#8217;s worth then noting how CSS decided what styles to use &#8211; Other people have done a better job than I would manage so I&#8217;ll just point you towards a few articles that cleverly explain the problem:</p>
<p><a href="http://iamacamera.org/default.aspx?id=95">http://iamacamera.org/default.aspx?id=95</a></p>
<p><a href="http://iamacamera.org/default.aspx?id=95">http://coding.smashingmagazine.com/2007/07/27/css-specificity-things-you-should-know/</a></p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://numiko.com/labs/2011/07/css-specificity-wars/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>You Arent Gonna Need It &#8211; Code Reuse</title>
		<link>http://numiko.com/labs/2011/03/you-arent-gonna-need-it-code-reuse/</link>
		<comments>http://numiko.com/labs/2011/03/you-arent-gonna-need-it-code-reuse/#comments</comments>
		<pubDate>Wed, 02 Mar 2011 14:25:32 +0000</pubDate>
		<dc:creator>Andy Tawse</dc:creator>
				<category><![CDATA[development]]></category>

		<guid isPermaLink="false">http://numiko.com/labs/?p=327</guid>
		<description><![CDATA[Here are two related articles (by Mike Mooney) where I found myself agreeing with every point and feeling relief that others have come to the same conclusions as I have over the years. The Framework Myth says you don&#8217;t need an internal omnipotent framework. I agree &#8211; over the years we have built up a...  <a href="http://numiko.com/labs/2011/03/you-arent-gonna-need-it-code-reuse/" title="Read You Arent Gonna Need It &#8211; Code Reuse">Read more &#187;</a>]]></description>
				<content:encoded><![CDATA[<p>Here are two related articles (by Mike Mooney) where I found myself agreeing with every point and feeling relief that others have come to the same conclusions as I have over the years.</p>
<p><a href="http://mooneyblog.mmdbsolutions.com/index.php/2010/12/07/the-framework-myth">The Framework Myth</a> says you don&#8217;t need an internal omnipotent framework. I agree &#8211; over the years we have built up a small collection of re-usable code, based on experience of <em>actually needing that code in our situation</em>. Coders love to code, and I have to admit feeling a thrill at writing my own APIs but &#8220;you are probably not getting paid to fulfill your dreams, you are getting paid to write the damn code.&#8221;</p>
<p><a href="http://mooneyblog.mmdbsolutions.com/index.php/2010/07/30/reusable-code-is-bad/">Reusable Code is Bad</a> is a headline in the tradition of <a href="http://www.flamingspork.com/blog/2005/08/08/comments-are-evil/">hyperbolic blog post</a> headlines, but &#8220;never build something to be reused until you actually have two systems that actually need to reuse it <em>right now</em>.&#8221; is something that makes sense to me.</p>
<p>Crucially, I think, everybody&#8217;s situation is different so you always have to judge for yourself. But as I look back over a decade of projects, how much unused reusable code did I write? How many times did I sweat over whether to take the time to &#8220;add another layer of abstraction and logical branching to my function&#8221; and how many times was I wrong when I decided to? Less and less as experience has taught me not to.</p>
<p>You should understand the principles of code reuse, no doubt, but learn to use your own judgement in your current situation. As with all advice, just because Google/Facebook/37 Signals/some-guy-with-a-blog says it&#8217;s a good idea, doesn&#8217;t mean it is for you.</p>
]]></content:encoded>
			<wfw:commentRss>http://numiko.com/labs/2011/03/you-arent-gonna-need-it-code-reuse/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Useful New Bits &amp; Pieces in Drupal 7</title>
		<link>http://numiko.com/labs/2011/01/useful-new-bits-pieces-in-drupal-7/</link>
		<comments>http://numiko.com/labs/2011/01/useful-new-bits-pieces-in-drupal-7/#comments</comments>
		<pubDate>Thu, 27 Jan 2011 14:11:06 +0000</pubDate>
		<dc:creator>Andy Tawse</dc:creator>
				<category><![CDATA[drupal]]></category>

		<guid isPermaLink="false">http://numiko.com/labs/?p=320</guid>
		<description><![CDATA[Everyone knows about the big changes in Drupal 7 but the details matter too, especially when they&#8217;re the kind of details that make life simpler and save time every day. Here&#8217;s some nice ones in Drupal 7. db_query No need to mess about with fetching rows any more, db_query() returns a Traversable object which can...  <a href="http://numiko.com/labs/2011/01/useful-new-bits-pieces-in-drupal-7/" title="Read Useful New Bits &#038; Pieces in Drupal 7">Read more &#187;</a>]]></description>
				<content:encoded><![CDATA[<p>Everyone knows about the big changes in Drupal 7 but the details matter too, especially when they&#8217;re the kind of details that make life simpler and save time every day. Here&#8217;s some nice ones in Drupal 7.</p>
<h3>db_query</h3>
<p>No need to mess about with fetching rows any more, db_query() returns a Traversable object which can be foreach-ed. Also, placeholders no longer need quote marks. (The Numiko API has taken care of these conveniences for a while now, glad they are no longer needed).</p>
<h3>Comments</h3>
<p>It&#8217;s now easy to output comments separately, meaning they can be placed anywhere on a node. No more hacking it.</p>
<h3>Profiling</h3>
<p>The Devel module now integrates the XHProf Profiler, which looks useful for finding bottlenecks in code.</p>
<h3>Checkboxes</h3>
<p>Now simple and logical to create on types. Previously I always had to refer to how I did it the last time.</p>
<h3>More Granular Permissions</h3>
<p>Which is good, and they are more logical. It will require a bit more thought from developers when defining roles e.g. all of the following permissions would generally be required as a base for a site editor: &#8220;Use the administration toolbar&#8221;, &#8220;View the administration theme&#8221;, &#8220;Use the administration pages and help&#8221;, &#8220;Access the administrative overlay&#8221;, &#8220;View the administrative dashboard, &#8220;Access the content overview page&#8221;.</p>
<p>Thankfully the infamous &#8220;Administer content&#8221; permission has been tamed.</p>
<h3>Content List Page</h3>
<p>This page now has sortable columns, and an &#8220;Updated&#8221; column, instantly making content easier to find and identify. AJAX auto-complete filtering here would make it complete.</p>
]]></content:encoded>
			<wfw:commentRss>http://numiko.com/labs/2011/01/useful-new-bits-pieces-in-drupal-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Facebook: Where did Post-Authorize Redirect URL go? (aka Oh facebook developers, what have you done this time?! )</title>
		<link>http://numiko.com/labs/2010/12/facebook-where-did-post-authorize-redirect-url-go-aka-oh-facebook-developers-what-have-you-done-this-time/</link>
		<comments>http://numiko.com/labs/2010/12/facebook-where-did-post-authorize-redirect-url-go-aka-oh-facebook-developers-what-have-you-done-this-time/#comments</comments>
		<pubDate>Mon, 06 Dec 2010 13:34:39 +0000</pubDate>
		<dc:creator>Andy Tawse</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://numiko.com/labs/?p=315</guid>
		<description><![CDATA[If you&#8217;re having problems getting the facebook login callback to fire &#8211; for example, you&#8217;re using one of the social plugins and are not getting redirected back to the right place on login &#8211; you might be looking to set the &#8220;Post-Authorize Redirect URL&#8221; &#8211; except, it&#8217;s not there any more! Facebook seems to read...  <a href="http://numiko.com/labs/2010/12/facebook-where-did-post-authorize-redirect-url-go-aka-oh-facebook-developers-what-have-you-done-this-time/" title="Read Facebook: Where did Post-Authorize Redirect URL go? (aka Oh facebook developers, what have you done this time?! )">Read more &#187;</a>]]></description>
				<content:encoded><![CDATA[<p>If you&#8217;re having problems getting the facebook login callback to fire &#8211; for example,  you&#8217;re using one of the social plugins and are not getting redirected back to the right place on login &#8211; you might be looking to set the &#8220;Post-Authorize Redirect URL&#8221; &#8211; except, it&#8217;s not there any more!</p>
<p>Facebook seems to read this from the canvas URL now instead &#8211; so try setting that to be the same as your Site URL.</p>
<p>Incidentally, I only had this problem when working from localhost &#8211; with sites on the public Internet,  setting the site URL only worked fine.</p>
]]></content:encoded>
			<wfw:commentRss>http://numiko.com/labs/2010/12/facebook-where-did-post-authorize-redirect-url-go-aka-oh-facebook-developers-what-have-you-done-this-time/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Drupal &#8211; number of registrations by month</title>
		<link>http://numiko.com/labs/2010/11/drupal-number-of-registrations-by-month/</link>
		<comments>http://numiko.com/labs/2010/11/drupal-number-of-registrations-by-month/#comments</comments>
		<pubDate>Fri, 12 Nov 2010 14:51:44 +0000</pubDate>
		<dc:creator>Andy Tawse</dc:creator>
				<category><![CDATA[drupal]]></category>
		<category><![CDATA[mySQL]]></category>
		<category><![CDATA[stats]]></category>

		<guid isPermaLink="false">http://numiko.com/labs/?p=309</guid>
		<description><![CDATA[Useful query &#8211; shows how many users registered on a Drupal site each month: select count(uid), month(from_unixtime(created)) as bmonth, year(from_unixtime(created)) as byear from users group by bmonth, byear order by byear, bmonth; SELECT count(uid), MONTH(FROM_UNIXTIME(created)) as bmonth, YEAR(FROM_UNIXTIME(created)) as byear FROM users GROUP BY bmonth, byear ORDER BY byear, bmonth;]]></description>
				<content:encoded><![CDATA[<p>Useful query &#8211; shows how many users registered on a Drupal site each month:</p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">select count(uid), month(from_unixtime(created)) as bmonth, year(from_unixtime(created)) as byear from users group by bmonth, byear order by byear, bmonth;</div>
<pre>SELECT count(uid), 

  MONTH(FROM_UNIXTIME(created)) as bmonth, 

  YEAR(FROM_UNIXTIME(created)) as byear 

FROM users 

GROUP BY bmonth, byear 

ORDER BY byear, bmonth;</pre>
]]></content:encoded>
			<wfw:commentRss>http://numiko.com/labs/2010/11/drupal-number-of-registrations-by-month/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
