Portfolio

E-commerce Development: car-mechanic-huntington.co.uk

The website project car-mechanic-huntington.co.uk was created with the aim of professionally presenting the services of a car workshop. The primary goal of t...

#Websites
E-commerce Development: car-mechanic-huntington.co.uk

#car-mechanic-huntington.co.uk, a professional website for a car workshop

Almost nobody arrives at a garage website out of curiosity. They arrive because something is wrong with the car, or because an inspection is due, and they arrive with one of three questions already formed: can you fix this, when can you take it, and where are you. Everything else on such a site is secondary to those three, and the build is worth judging by how quickly it answers them.

That framing decided the shape of this project. car-mechanic-huntington.co.uk presents the workshop’s services and lets a visitor book a slot. The audience is local car owners, people chasing a specific fault, and small businesses keeping a handful of vehicles on the road. The site went live in 2012 and took roughly six weeks.

The date matters for reading the rest of this. In 2012 a responsive layout was a line item in the scope, not a default. Flexbox was not in general use and CSS grid did not exist, so columns were floated and breakpoints were chosen against the actual handset widths people were carrying. That is where the Bootstrap grid came from: not fashion, but the alternative of writing the same thing from scratch and then maintaining it alone for years.

#Booking is a resource problem wearing a form’s clothing

The booking module looks like a contact form with a date field. It behaves nothing like one, because it allocates something there is a finite amount of.

A workshop does not have a calendar in the sense a consultant has a calendar. It has bays and it has mechanics, and an appointment is a combination of the two for a length of time that depends on the job. An oil change and an intermittent electrical fault occupy very different portions of a day. A data model that records a booking as a date and a time falls over on the first morning two people both want eight o’clock and there is one ramp.

From that follows the decision that is the whole point of the module. Availability shown in the browser is a photograph of a moment that has already passed. Ten or fifteen minutes can go by between the list rendering and the button being pressed, because the visitor goes off to check whether they can get the morning off work. So the availability check has to run again on the server at the moment of writing, and it has to run in a way that will not let two requests pass through the same free hour. An interface that merely greys out taken slots looks correct and will produce a double booking the first time two people are on the page at once.

There is a second consequence, and it concerns caching. Most of a garage site is stable: service descriptions, directions, opening hours. That content can sit in cache for a long time. The availability view is the exact opposite, since its only value is that it is current. A configuration that caches the whole site without exception will happily serve a week-old picture of the diary, and nobody notices until a customer is standing at a closed shutter. So the booking view is excluded from caching deliberately, not by accident.

#Why custom endpoints rather than a booking plugin

Booking plugins exist, and most of them model a hairdresser or a clinic: one practitioner, one chair, one fixed slot length. Bending that model to accept a second axis and a variable duration costs more than writing the booking write path yourself, and it leaves you maintaining somebody else’s assumptions in a part of the system where a wrong assumption produces a customer who was told to come at nine and cannot be seen.

So the calendar talks to the database through endpoints written for this site. The browser collects parameters and displays a result; it decides nothing. That split also keeps the workshop’s real capacity out of public view, which matters more than it sounds: the number of bays and the length assigned to each job type is commercial information, and a booking widget that computes availability client-side publishes all of it.

#Key functionalities and technologies used

Beyond booking, the scope covered several areas.

The responsive layout put phone-sized screens first for the things people actually want on a phone: the number, the address, and how to get there. The offer copy comes after those, because a question about a garage is usually asked from a car park or a roadside, not from a desk.

Social media integration pulls posts and reviews onto the page. This is the point where a site becomes dependent on a server nobody here controls, so the failure behaviour had to be settled at build time rather than discovered later. Responses are cached, and when the source does not answer the section shows the last known content or does not render at all. An empty box with an error message on a garage homepage reads as the whole site being broken, not as a third-party API having a bad afternoon.

Search work rested on semantic HTML5, tidy metadata and structured data describing a local business. For a local service three things matter most in machine-readable form: name, address and telephone in one unchanging shape, opening hours, and the area served. A mismatch between the address on the site and the address in external listings is a classic long-lived defect, because to a human reader both versions look fine.

WordPress was chosen as the editing surface for a specific reason. A workshop has no editorial team. Changes are made by the owner or by whoever is in the office, between two jobs, so editing opening hours must be possible without technical knowledge and without any risk that it breaks the layout.

The contact module holds a form, directions and a map. The map deserves its own section.

#The map is the most expensive thing on a contact page

An embedded map is ordered in a single sentence by the client and costs more than the rest of the contact page put together.

It is third-party script, third-party styles and a run of image tile requests, all from infrastructure outside our control. On a small site that one component is routinely heavier than every piece of content on the page. It also runs for every visitor, including the one who came for a phone number and will be gone in ten seconds.

The fix is to not load it with the page. What renders by default is a static image with the location marked and the address in text beside it; the interactive map starts only when someone touches it. A person who needed the address has it immediately, and a person who wants turn-by-turn directions spends one extra tap and gets the full tool. That ordering is the reverse of the intuitive one, which is why the heavy version so often ends up as the default.

#Challenges and programming solutions

Page weight was attacked in three places: image compression, caching of the content that rarely changes, and cutting the number of stylesheet and script files. The last of those carried weight in 2012 that it does not carry now, because browsers were opening a connection per file against a low parallel-request limit. Merging ten stylesheets into one was not housekeeping then; it removed nine round trips.

Content migration was the other substantial piece. An earlier version of the site existed, and parts of it survived only as archived copies, which we recovered through Web Archive. The easy half of such a migration is the text. The half that gets skipped is the addresses. A site that has been up for years has links in local directories, trade listings and emails already sent to customers, none of which anyone is going to update. Every old URL therefore needs a specific new one and a permanent redirect, rather than a blanket sweep to the homepage. The blanket sweep looks fine in a browser, because no error appears, and it discards whatever the old address had accumulated.

Personalised modules were the last challenge, and they sit in direct tension with caching, since caching pays precisely because many visitors receive the same document. The resolution is to separate the two: the page shell and the service copy are shared and cached, and the visitor-dependent fragments are fetched separately after load. Without that separation any personalisation invalidates the cache for the entire site and you are forced to pick one or the other.

#Tools and technologies

WordPress for editing, PHP and MySQL on the server, HTML5, CSS3 and JavaScript in the presentation layer, the Bootstrap grid and components for the responsive layout. Automated backups, version control for the code, and monitoring of search visibility round it out.

Backups carry the same caveat here as everywhere. A backup nobody has ever restored is a file, not a safeguard. The restore has to be performed at least once, on a separate environment, because the gaps in a backup only ever surface during a restore, and by then there is usually a reason to be in a hurry.

One note on plugins. Functional plugins are used where they earn their place, but security does not rest on one. A security plugin is code running inside the application it is meant to protect, so it starts working only once the request has already reached that application. Filtering traffic in front of the application, keeping the core current, restricting access to the admin area and holding a restorable backup all buy more than a dashboard counting blocked login attempts.

#Support and maintenance on WordPress

Maintenance here is a list with a boundary drawn around it rather than an open promise. It covers fixing faults, installing core, theme and plugin updates, reviewing logs, taking backups to an agreed policy, and small changes to content and presentation.

A site with a booking module adds an obligation an informational site does not have. Any update touching form handling or date handling is tested against a copy of production carrying real bookings. The reason is mundane rather than principled: on a clean install the diary is always empty, so no test ever reaches the path where the module can actually break. That path is collisions between two requests for the same slot, and the edge cases sitting at the boundaries of a working day.

Being explicit about what maintenance does not include belongs to the same boundary. It does not include a guarantee that an update will never break anything, because no site assembled from components maintained by independent teams can offer one honestly. It does include applying changes away from production first, and having the way back prepared before it is needed rather than improvised while the phone is ringing.

The practical effect on a garage is small and worth naming. Update windows sit outside opening hours, because a booking form that is down while someone is trying to reserve a slot costs a job rather than a page view. The same reasoning decides which changes wait for the next planned window and which are worth doing the same day.

#Summary and preliminary analysis of client requirements

Planning started with a set of questions that had to be answered before anything was built. What the site is for and who it serves. What was already on the client’s requirements list, which in this case included booking, links to social profiles and content matched to the visitor. How it should connect to the existing database, what the schedule allowed, and which examples the client wanted to point at. How much of the previous site to carry over and how much to write from scratch. And what the budget permitted, which is the question that decides whether a scope is delivered at once or in stages.

The answers set the order of work, and that order is the part worth repeating. Services, directions and contact came first, because they are what people open a garage site for. Booking came second, being the most complex element and the only one that genuinely changes how the office works, and the external integrations came last, because they are the least critical and the easiest to add after launch. What carries forward is method rather than content: check the availability of a finite resource on the server at the moment of writing, keep time-sensitive views out of cache, defer heavy third-party components until someone asks for them, and map old URLs one at a time during a migration. This project’s content model and integrations do not carry forward, written as they were for one workshop and one brief in the Websites category, so a second project starts with a scope analysis and the quote comes after it.

What scope did the car-mechanic-huntington.co.uk project cover?#
car-mechanic-huntington.co.uk sits in the Websites category and was first delivered in 2012. The entities behind it are WordPress, PHP, JavaScript, MySQL and HTML5.
How did delivery run for car-mechanic-huntington.co.uk?#
The build ran about six weeks and went live in 2012. It sits on WordPress, PHP, JavaScript, MySQL and HTML5. The layout came from the client. I built the templates and the content model against it, then checked the paths that carry traffic on a copy of production rather than on an empty install.
What was the hardest technical part of car-mechanic-huntington.co.uk?#
Holding WordPress, PHP, JavaScript, MySQL and HTML5 together took the most care. Content, configuration and code stay in separate layers, so a rollback after launch moves one of them and not all three. Edge cases surface on a production copy, which is why the checks run there.
What part of car-mechanic-huntington.co.uk could be reused on another build?#
WordPress, PHP, JavaScript, MySQL and HTML5 is the part that carries over; that layer looks much the same on the next build. What does not carry over is this project's content model and its integrations, written against one client's data for a Websites brief. A second build starts from a scope review, and the quote follows it.

Need an FAQ tailored to your industry and market? We can build one aligned with your business goals.

Let’s discuss