Wednesday, 7 January 2009

Plmygo goes live!

After a long hiatus, we are back....

The initial version of our transport information website for Plymouth City Council is now live - www.plymgo.com. The site is a 'mash-up' that combines Google maps with a range of other information sources to provide city residents with a single point of entry for information related to every mode of transport in the city. Soon website visitors will be able to combine journey planning information with geographic details of amenities such as schools, car parks and museums to generate easy to use 'point to point' routes that also outline the environmental and health costs/benefits of their chosen method of getting around the city.

Over the next twelve months the overall goal is to widen the scope of the site beyond journey planning to make it a comprehensive source of information about all aspects of the city.

Thursday, 12 June 2008

Simple FORMs are happy FORMs

Introduction

I spotted a nice tutorial about using jQuery to highlight fields and blocks of fields in forms over at Janko at Warp Speed this morning.

While the jQuery is spot on (gotta love the brevity / simplicity of jQuery), the form mark-up left a bit to be desired. I'm not picking on Janko here, you see this pattern repeated over the web.

Janko suggested the following markup:

<div class="row">
<div class="left">First name</div>
<div class="right"><input name="Text1" type="text" class="text" /></div>
<div class="clear"></div>
</div>

Clean Markup

There are few things that can be improved here:
  1. No labels. It is very important for people using assistive technologies (screen readers) that input elements (the text boxes) are associated with a label. Why? Close your eyes and tab about a web form. How do you know which field you are on? A label is tied to an input box and screen readers understand this association and can provide additional feedback to the user to help them orientate and navigate around a form.
  2. There's a lot of unnecessary
    's. Not really a big issue, but if they aren't needed, why put them in? It complicates your mark-up and, if you are paying for your bandwidth, why waste good money? Less mark-up also means your page loads faster too.

    Note: In the real world, you sometimes have to add semantically neutral mark-up to give you hooks to attach additional styles to or to work around various browser quirks, but in this case we can safely remove them.
  3. The clearing div. There are a number of techniques for avoiding this markup cruft. And in most cases, they can be removed completely.
Lets fix those issues and see what we end up with:

<div class='row'>
<label for='Text1'>First Name</label> <input id='Text1' name='Text1' type='text' />
</div>

Doesn't that look easier to understand?

Clean CSS

Now we have some clean markup, the CSS needed to style it becomes much cleaner too (I've left out the stuff that makes it pretty to keep things simple):

.row {
clear: both;
float: left;
width: 100%;
}
label {
float: left;
width: 150px;
cursor: pointer;
}

Let's look at those rules one at a time and explain what's going on:

.row {}

  • clear: both;
    We are using floats to achieve the desired layout. This ensures that each row appears underneath the one above instead of floating next to each other across the screen.
  • float: left;
    The row needs to fully contain its child elements (label, input). Without this, the row would collapse up into nothing and you would never see the background change when the input got focus (the whole point of Janko's post).
  • width: 100%;
    Floated elements will shrink to match their content. This makes sure that every row runs the full width of its container (usually a fieldset).
.row label {}
  • float: left;
    We want to label and the input elements to line up on the same row. Also, we want each of the input elements to line up vertically so we add a
  • width: 150px;
    to ensure that all the labels are the same width. Because we aren't floating the input elements, they automatically butt up next to the labels.
  • cursor: pointer;
    Not absolutely neccessary, but changing the cursor to the hyperlink (pointing finger) cursor indicates to a sited user that the label is clickable. If you click the label, most browsers will automatically switch focus to the linked input element (another very good reason to use labels).
Conclusion

I'm a big fan of the KISS principle: Keep It Simple, Stupid! Less code means less potential (programmer) errors, less work for the browser, lower bandwidth costs and increased readability. It's a win/win situation.

Go forth and simplify!

Zemanta Pixie

Thursday, 22 May 2008

CakePHP and Access sitting in a tree...

Introduction

A mentioned in a previous post, I'm currently working on a CakePHP powered website. One of the requirement for the project was the ability to create reports using a 3rd party reporting product.

We looked at several options but finally settled on Microsoft Access because a) the client already had it, and b) they had some experience of using Access to generate reports so the learning curve was less steep.

Getting the Data into Access


The CakePHP application uses a MySQL database so the natural step was to use ODBC (Open Database Connectivity) to link the tables into an Access MDB (Microsoft Database). From there, the client could use the Access GUI (Graphical User Interface) to create custom queries and reports.

I won't cover installing the MySQL ODBC Driver (otherwise know as MySQL Connector/ODBC) and linking the tables as there's plenty of documentation on the web that covers this step, and the instructions are slightly different for each version of Access.

Linking tables via ODBC is trivial in Access, but ODBC doesn't provide any schema information to Access for it to build the relationships between the (in this case 30+) tables. As the application is still in development the schema, although solid, may be subject to change. Adding the relationships between 30+ tables by hand using the relationship editor is both very time consuming and more importantly, very susceptible to human error.

Couple that with the need to keep updating the relationship diagram in access to reflect any changes in the MySQL database and you soon see this is going to be a nightmare to do by hand. Sounds like a job for automation!

It's been quite a while since I'd done any VBA (Visual Basic for Applications), the last being back in the days of Access2000 but it didn't take too long to get up to speed.

Automate it

My CakePHP application follows the CakePHP database naming conventions which might seem a little odd to someone who is used to Access, but I find them very intuitive.
  • Tables have plural names (posts, programmes, cities, people)
  • Primary keys are named 'id'
  • Foreign keys are named the singular table name followed by _id (post_id, programme_id, city_id, person_id)
The only potentially tricky bit is inflecting the singular foreign key names to their plural table names. A simple "plural" function takes care of that. In this case, none of my tables had 'non-standard' plural names (all plurals were the singular with 's' appended: post_id -> posts, project_id->projects, etc.).

With this information, it was relatively simple to create a VBA function that runs through all the fields in the linked tables and builds relationship objects that relate the foreign keys to their respective tables:

The Code
Function buildRelations()

Dim rel As Relation ' the relationship we are building
Dim tbl As TableDef ' the table we are processing
Dim fld As Field ' the field we are processing
Dim strForeignTable As String ' name of the foreign table
Dim intRelId As Integer ' counter used to create unique relationship names

' remove any exisiting relationships

Do While CurrentDb.Relations.Count > 0

CurrentDb.Relations.Delete (CurrentDb.Relations(0).Name)

Loop


' rebuild relationships
intRelId = 0

For Each tbl In CurrentDb.TableDefs

For Each fld In tbl.Fields

If Right(fld.Name, 3) = "_id" Then

' found foreign key

' generate foreign table name (plural)
strForeignTable = pluralise(Left(fld.Name, Len(fld.Name) - 3))

' build the relationship object
intRelId = intRelId + 1

Set rel = CurrentDb.CreateRelation("rel" & intRelId, tbl.Name, strForeignTable, dbRelationDontEnforce)
rel.Fields.Append rel.CreateField(fld.Name)
rel.Fields(fld.Name).ForeignName = "id"

' append the relationship to the database relationship collection
CurrentDb.Relations.Append rel

End If

Next

Next

MsgBox "Relationships have been rebuilt"

End Function

Private Function pluralise(str As String) As String

pluralise = str & "s"

End Function
You may need to expand the pluralise() function to deal with odd pluralisations (city_id->cities, person_id->people) in your own schema.

One word of caution. If you use Access' Query builder to build queries with linked tables, Access 'helpfully' tried to guess the primary and foreign keys for you which will mess things up royally. You can switch off this feature by unchecking 'Enable AutoJoin' in the Access Options dialog.

OpenCms – Initial Notes from OpenCms Days Conference: May 5th 2008, Cologne

OpenCms, the open source content management system, forms that basis for many of our successful web projects.

I attended (and presented at) the first international OpenCms conference in May 2008.

Here are some notes that I took at the event.

A complete conference programme can be found on the OpenCms Days website.The slides and video recordings of the presentations will be made available on the OpenCms website in the near future.

The key theme for the conference was that OCMS is a powerful platform that is widely used on major global, mission critical sites (e.g. pokemon.com and gardena.de) but the developer community is rather weak in comparison to that associated with other open source products (i.e. Drupal) with OCMS developers tending to ‘hang onto’ their code base, for the following reasons:

  • concerns about IPR - some companies have built successful businesses around sophisticated bespoke code and they are concerned that releasing that code will compromise their success
  • failure to coordinate between OpenCMS developers - with the result that those organisations that want to provide code to the community are not sure what is valuable and whether it is worthwhile making the effort to release
  • no clear sense among the community of whether there is a wider market for modules that OpenCMS developers have authored - for example Futurate have an ‘events module’, but is the market large enough to justify making it available for free or at a charge....?
There was wide agreement among delegates that the situation must change if the product is to move forward, and development of the OpenCms website to more actively support community code exchange seems the most likely outcome.

Delegates were reminded that the current OpenCms website contains a small list of modules and extensions, as does the OpenCms wiki. A comprehensive single point of call for developers and business managers does not exist however, nor does any method of determining the quality of any released code through approaches such as peer review or rating.

For readers who are interested in learning more about freely available code/documentation for OpenCms, the following links may be of interest:

I felt that the following modules/extensions are worth singling out as of particular interest:

Other notes

  • Alkacon are planning to release a number of further modules/extensions before the end of June, including a calendar, a basic blog, drag and drop of content elements, and a survey module. An indication of the direction for OpenCms over the next couple of years can be found in Alex Kandzior’s presentation when it is made available for download.
  • Packt Publishing have released a new OpenCms book for OpenCms 7 developers - and a review will be appearing in this blog over the next few weeks.
  • Version 7.0.5 of OepnCms will be available in July 08. Version 7.5 early 09.

I’ll make an announcement here when the slides and video from OpenCms days have been made available.

Thursday, 1 May 2008

Free RSS Module for OpenCMS

To coincide with my presentation at OpenCMS Days 2008, we have released our first completely free, open source module for OpenCMS 7.

This module which forms a core component of our recent project for Film London allows OpenCMS developers to easily create RSS feeds from OpenCMS content and external databases.

We have provided compiled code, source code and complete documentation.

Thanks to Steve Osguthorpe for preparing the code for release in time for the event in Cologne.

Friday, 18 April 2008

Facebook gets frightening

After a couple of months holiday from Facebook after a severe bout of 'Facebook Fatigue' (an increasingly common complaint?) I decided to try and get back into it a little and a new feature caught my eye.....'People you might know'.

Basically PYMK 'triangulates' social relationships by identfying Facebook members that are known to me and one or more friends, but haven't been added to my friends list yet. There were a couple of dozen potential friends in my PYMK list, most of them either people I knew but just hadn't bothered to 'friendify' or people that were friends of friends that I have never met.

So far, so good but one particular PYMK caught my eye - someone I had never met that was a friend of a work colleague and a friend of a friend (who had also never met). In other words Facebook had indentified a person that linked together two apparently unrelated social groups (a sort of social conduit). Initially this was pretty impressive, but then I wasn't so sure because it brought to mind a scary thought that had occurred to me when I recently applied for a new passport. A process which involved a professional colleague signing my passport photo which had to be accompanied by that person's passport number (thereby uniquely identifying that person to the UK Immigration and Passport Service). It's not much of a leap to see how a similar approach to PYMK could be applied to this information, thereby giving the authorities (assuming that they had the motivation and are unhindered by privacy laws) the facility to triangulate individuals to identify who they are associating with both directly and indirectly......

Wednesday, 16 April 2008

Another accessibility checker

Those of you that have read our previous posts about SharePoint accessibility, the disappearance of Bobby or my recent whitepaper on accessibility should appreciate that issues around accessible web design are close to the hearts of everyone here at Futurate, and in our never ending quest to find the perfect web-based automated accessibility testing tool we have found Wave.

What's nice about Wave is that rather than generating a somewhat impenetrable list of what's wrong with a site, it displays the page itself with problems (and good stuff like accesskeys) linked to specific page elements. You can see an example here - http://wave.webaim.org/report?url=www.futurate.com (rollover the icons for additional information).

For people who prefer Firefox to Internet Explorer a Wave toolbar is available which allows you to check the page you are on, at the click of a button.

It works rather well, but in order to try and determine whether a Wave report page is accessible don't try Waveing a Wave page......