Navigate home

Having recently installed iOS 6, I thought I’d try the new navigation features. Ok Siri, “navigate home”. After a few seconds, the response was “I couldn’t find an address for Chris Weedall – home”.
20120923-232226.jpg
Ok, first let’s check the basics – I’ve previously set up my home address with Siri, and this address is attached to my contact card, marked as home. Also if I go to Settings -> General -> Siri -> My Info, the correct contact card is selected.

The response from Siri “I couldn’t find an address” could mean one of two things:

  1. There isn’t an address flagged as “home” for me – well there is one there
  2. It can’t find my address on the map – lets test that then

When I try to navigate to my town the directions returned are to a place with the same name but in Somerset, some 230 miles away. So it can’t find my address. Lets go about this another way then:

  1. Remove the “home” address entry from my contact card (or move it to another address slot)
  2. Go to the Maps app, and stick a pin in the road outside my house (it needs to be in the road to resolve an address, minus a house number and full postcode)
  3. Click on the dropped pin and select “Add to contacts”
  4. Select “Add to existing contact” and pick my contact card
  5. This is the important bit – go to Contacts and edit my contact card, setting the address type of this new address to “Home”

This works a treat. The only downside is that the address isn’t now a full postal address, but you could keep the full address as a second address on the contact card.

Your system is too old

I’m posting this because I had trouble installing KODAK Home Center software on Windows XP, and my Google-foo failed to find an answer. Perhaps this will help someone else…

I’ve just had an hour of fun completing what should have been a 10 minute job. After setting up a Kodak ESP 1.2 All-in-One super duper wireless printer/copier/scanner it was time to install the software. First of all the driver CD wouldn’t be recognised by the laptop. No problem, download from the website. Installing, then the message “Your system is too old”, and setup cancelled. What?! No! Can’t be, it definitely says XP on the box, and the website (except XP 64bit but nobody ever used that, right?). Windows XP – I know it’s 11 years old and 2 (nearly 3) versions of Windows out of date, but you’ve got what you’ve got, and for almost everything it’s fine (no VS2012 though, grr). And anyway I’ve kind of ripped up the box now.

Back to the driver CD (perhaps its different software), it works fine in another machine so it must be the DVD drive. Copied contents to a flash drive, this time the installer properly loads up, still with the same apologetic message, but this time the chance to install the plain printer driver. That works via USB, but the point of a wireless printer is that it can go on the opposite side of the room, and the scanner doesn’t work either.

I then notice that autorun had started the installer on the 2nd machine, which is also XP, and it is happy to install the full software bundle. Hmm, a puzzle. Both have SP3 and are of a similar vintage. The first is Media Centre Edition but that can’t be it surely, unless it only looks for Home and Pro and rejects everything else? Thankfully at this point, I notice the problem PC only has 70mb of disk space on the C drive. I wonder… Sure enough, after freeing up 2gb of space (just to be sure), it installs like a charm, and so far has been super ninja awesome.

Moral of this story: It’s always disk space. Apart from when it’s a reboot. Actually it’s almost always a reboot, but today it was lack of disk space.

Footnote: to those who think I should have checked this first, all apps are on E and data on F, just the OS and occasional apps that really must go on C live on the system drive. But yeah, I guess I should have checked that earlier.

WordPress Child Page Menus

Whilst helping Michelle set up Kids Puzzles and Games I came across the need for the menus in the various sections to show child pages when in a section home page, and peer pages when viewing any content in a section.

The site structure is along the lines of:

  • Home page
    • Section home page
      • Section page
      • Another section page
    • Another section homepage
      • Etc

So in the Colouring Sheets section the menu will show types of colouring sheets, and when viewing a colouring sheet page you will also see types of colouring sheets. For an added twist, as the page titles repeat the name of the section they are in I needed to remove that repetition when displayed in a menu – e.g. Dinosaur Colouring Sheets is the title of a page in the Colouring Sheets section.

Example menu

My PHP isn’t great, and it took me a little while to find examples to put together to make the answer but this seems to do the trick. I’m sharing it in case you need to do something similar.

 <?php
 // get the title of the parent page
 $parent_title = get_the_title($post->post_parent);
 // get formatted array of child pages but don't echo them
 $child_pages = wp_list_pages('title_li=&child_of=2&echo=0');
 // replace any mention of the parent page title with an empty string
 $child_pages = str_replace($parent_title,'',$child_pages);
 // and now output the menu
 echo $child_pages;
 ?>

You’ll notice I’ve hard coded the page ID of the parent page – I can do this because each section has it’s own template. I know that $post->post_parent will give the ID of the parent page, but I needed that to be fixed for the section heading and for the section content (which is a child page of the section heading). Feel free to let me know if there is an easier way of doing this I’m all for keeping code simple.

Updated 17th April to remove extra semi-colons added by editing this post on the iPhone WordPress app!

Changing a bulb

How many programmers does it take to change a lightbulb?

I drive a mk II Renault Megane, which is a great car and I really enjoy driving it. It’s not fast, but those 80 frugal diesel slurping horses get me around just fine. Renault in their infinite wisdom; no doubt as part of the drive to make cars a “black box” that only the magicians at the garage can understand, decided that changing a headlight bulb should not be a simple task. There should be no opening of the bonnet and simply replacing the bulb. There should instead be a test of willpower and perseverance.

This is roughly what I had to do:

  • Turn the front wheels full lock so I could access the underside of the wheel arch
  • Remove a dirty, hard to remove plastic panel that felt like it might snap
  • Reach my arm from the elbow upwards through the resulting small hole with sharpish edges to feel the for the bulb, though from this position I couldn’t look through the light cover at the front of the car (to position my hand) and reach at the same time.
  • Except it’s not there – it is hidden behind a plastic cap (that I can’t see). Unscrew the cap (trying not to drop the cap inside the car)
  • A-ha – the bulb, I think. It has a plug attached to it (that I can’t see), and is held in place by a spring/clip (that I can’t see).
  • Go looking for a torch, that might help. Found Lauren’s wind-up penguin torch.
  • No that doesn’t really help much, though I can now kind of see some wires attached to a plug behind which is the bulb.
  • Catch 22 – the arm hole is big enough to either shine the torch through or put my arm in. Went for my arm as light on it’s own is unlikely to finish the job. Perhaps if it was a tractor beam torch…
  • Remove the plug (should I pull it by the wires or the plasticy bit – went for the plasticy bit)
  • Unclip the spring/clip (harder than it sounds, turns out it is only clipped at the top)
  • Remove the bulb (that I can’t see). Try not to drop the bulb
  • Oops – before doing that I should have tried to remember which side of the bulb mount the notch was facing (that I can’t see) as that helps in positioning the new bulb.

Putting the new bulb in place is then a matter of doing this in reverse, which is trickier than it sounds as the bulb is small and you need to locate the correct rotation for the notch, attach the spring/clip, attach the plug, and screw the cap on, all without being able to see what you are doing.

It turns out I was doing things the hard way. There is a great guide on the Megane Owners Club website that explains that jacking the car up and taking the wheel off first (I kid you not) is the best way to do this. I’ll try that next time.

Coding away from the keyboard

Whilst working on a program to automatically generate mazes, I realised that most of my spare time for this kind of thing is either when watching TV, or when I’m away from home, such as on the park and ride bus to and from work. As I was looking to solve the problem using JavaScript/HTML there is no compiler involved, so some kind of editor app for my phone would be ideal. Sure enough there are several in the App Store, I settled on Expresso HTML, well because it looks nice, has some useful shortcuts to characters such as “<", has a handy inbuilt browser to preview my efforts – oh and it's free.

20120115-162704.jpg
Coding on the go is fairly tough going, the virtual keyboard obscures half of the screen and doesn’t allow tabs (double space indentation!), but it is easy to switch between preview and editor mode, and you can work on multiple files. Ideal for small projects and experimenting on the go – it was enough to get my maze generator finished and working, details of how I got on to follow in a future post. If it had an in-built FTP client it would be great for making for emergency corrections.

Creating mazes

My wife creates printable activity sheets for children, and the subject of how to create mazes came up. Hand drawing leaves too many chances for mistakes, so we settled on using a spreadsheet – draw a grid, use the table eraser to make paths:

20120108-104933.jpg

Now this works fine, but being a developer I can’t help thinking there must be a way to programmatically generate these based on some parameters. Sure enough, solutions already exist, but this is a puzzle I’d like to solve on my own.

Over the next few posts I’m going to record my progress and my various attempts at creating a solution.

20120108-104920.jpg

Infinite scrolling with an ASP.net webform, jQuery, and a little bit of code

Infinite scrolling presents your content as one long page – as you read (scroll) toward the bottom of the content some more loads in below automatically (and hopefully seamlessly). This allows your site visitor to focus on content without being distracted by enforced navigation concepts such as paging. It also means you only serve as much content as the user wants to see, which is espacially useful in today’s increasingly mobile world. Twitter and Facebook are good examples of sites that do this well.

This post aims to give a hopefully simple example of how to achieve this using the following basic ingredients:

  • ASP.net/C# 4.0 (I’m using Visual Web Developer Express)
  • An ASP.net webform
  • A ScriptMethod
  • jQuery and a bit of JavaScript
  • Some data – in this case a list of pretend blog posts

How it works

The webform will display the first ten blog posts. When the user scrolls to the bottom of the page some JavaScript will call a method to return the next ten items. These are then appended to the bottom of the page. When the user scrolls to the bottom of that the process repeats until there are no blog posts left.

This is simplified for us by the use of a ScriptMethod, which is like a WebMethod in a web service, except you place it in a normal ASPX page as a static method decorated with the ScriptMethod attribute (code example below). ASP.net then kindly provides a nice JavaScript proxy for us to call this with one line of code. I’m then using jQuery to simplify the process of adding the resulting array of BlogPost items to the page.

Blog Post Repository

First things first, we need some data to display and so I have created a static class BlogPostRepository which provides access to a list of made up BlogPost items:


public class BlogPost
{
	public string Title { get; set; }
	public string Summary { get; set; }

	public BlogPost(string title, string summary)
	{
		Title = title;
		Summary = summary;
	}
}

public static class BlogPostRepository
{
	static List<BlogPost> posts;

	static BlogPostRepository()
	{
		posts = new List<BlogPost>();

		for (int i = 1; i <= 200; i++)
		{
			posts.Add(new BlogPost(string.Format("Post number {0}", i),
				string.Format("Discover my thoughts on the number {0}.", i)));
		}
	}

	public static List<BlogPost> GetPosts(int startAt, int howMany)
	{
		return (from p in posts
			select p).Skip(startAt).Take(howMany).ToList();
	}
}

The code behind page

The code behind for the web page is straightforward – bind the first ten posts to a ListView control during Page_Load, and the ScriptMethod GetPosts will return additional blog posts to the page on request:

protected void Page_Load(object sender, EventArgs e)
{
	if (!IsPostBack)
	{
		lvItems.DataSource = BlogPostRepository.GetPosts(0, 10);
		lvItems.DataBind();
	}
}

[System.Web.Services.WebMethod()]
[System.Web.Script.Services.ScriptMethod()]
public static List<BlogPost> GetPosts(int startAt, int howMany)
{
	return BlogPostRepository.GetPosts(startAt, howMany);
}

Note that GetPosts is decorated as a WebMethod and also a ScriptMethod. It also needs to be static.

The mark up

The key to making Script Methods work is the <asp:ScriptManager> which needs to have EnablePageMethods set to “true”:

<asp:ScriptManager runat="server" ID="ScriptManager1" EnablePageMethods="true">
</asp:ScriptManager>

This ensures that the necessary JavaScript helper methods are available.

Next up is a ListView control which I really like because of the control it offers over the output in your page. This takes care of the initial output of blog posts:

<asp:ListView runat="server" ID="lvItems">
	<LayoutTemplate>
		<div id="container">
			<asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
		</div>
	</LayoutTemplate>
	<ItemTemplate>
		<div class="post">
			<h2>
				<%# Eval("Title") %></h2>
			<p>
				<%# Eval("Summary") %></p>
		</div>
	</ItemTemplate>
	<AlternatingItemTemplate>
		<div class="post shade">
			<h2>
				<h2>
					<%# Eval("Title") %></h2>
				<p>
					<%# Eval("Summary") %></p>
		</div>
	</AlternatingItemTemplate>
</asp:ListView>       

You will notice that each blog post has a container DIV with a class of “post”, and that they are all held within a container DIV with an ID of “container”. Alternate posts have a shaded background thanks to some CSS and the additional “shade” class. The next thing is to add the JavaScript:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
    $(window).scroll(function () {
        if ($(window).scrollTop() == $(document).height() - $(window).height()) {
            GetPosts();
        }
    });
});

function GetPosts() {
    var howMany = 10;
    var startAt = $(".post").size();
    PageMethods.GetPosts(startAt, howMany, OnGetPostsComplete);
}

function OnGetPostsComplete(posts) {
    for (var i = 0; i < posts.length; i++) {
        var shade = (i % 2) != 0 ? " shade" : "";
        $("#container").last().append("<div class=\"post" + shade + "\"><h2>" +
                            posts[i].Title + "</h2><p>" +
                            posts[i].Summary + "</p></div>");
    }
}
</script>

Lets look at the script above. First I use jQuery to attach a function to the scroll event of the window. This will fire whenever the user scrolls to the bottom of the page, and simply calls the GetPosts method.

GetPosts uses jQuery to get a count of items in the page with the class “post”. This will equal the number of blog posts output so far. I can then call a JavaScript method provided for us by ASP.net because the GetPosts method in our code behind is decorated as a ScriptMethod. So PageMethods.GetPosts takes the same parameters as the C# code, plus in addition the name of the method to call when the asynchronous web call has completed – i.e. when we have the results of the call, in this case OnGetPostsComplete

OnGetPostsComplete takes the array of BlogPost items returned by the ScriptMethod and appends them to the end of the items already in the container DIV which holds all of the blog post DIVs. For effect I’m adding the “shade” class to alternate post items which I have defined in CSS to give them a different background colour.

What next

I haven’t tried this with a database as a data source so speeds will vary. When using the in-memory repository there was hardly a noticable delay at all in the new items being displayed. You might want to add an AJAX style “spinner” graphic to show when loading is occurring. This can easily be achieved using a hidden DIV and the jQuery toggle() method, e.g. $("#loading").toggle();. Toggle it on in GetPosts, and off again in OnGetPostsComplete.