A cleaner, faster foundation for a technical certification business.

Last updated: August 27, 2026

←  Selected work
Case study — redesign, WordPress rebuild & content systems

A cleaner, faster foundation for a technical certification business.

EngineCert’s existing site mixed WPBakery pages with newer native WordPress structures, making the frontend slow to change and difficult to keep consistent. The rebuild translates a complete wireframe into a block-native system, gives repeated service content a single source of truth and carries legacy Industry News into a structure designed for continued publishing.

Client
ECO, Inc. — vehicle certification and regulatory-compliance consultancy
Role
Full-stack WordPress rebuild and technical implementation, delivered white-label
Stack
GeneratePress, GenerateBlocks, custom PHP, ACF and n8n
Stage
Staging build and pre-launch QA; final launch work remains in progress
Before / after

From a mixed frontend to one visual and content system.

The new direction does more than change the palette. Page structure, service content, navigation and editorial components now share a consistent set of patterns that can be reused instead of reconstructed page by page.

Full previous ECO homepage scaled to fit without cropping
Before Full page · scaled to fit
Full rebuilt ECO staging homepage scaled to fit without cropping
After Full page · scaled to fit
The problem

Two frontend generations were sharing one website.

The existing site had grown across WPBakery and more recent native WordPress work. The result was not one editable system but overlapping structures, inconsistent presentation and a growing number of content and frontend errors.

A full wireframe defined the new information architecture: core company pages, approximately twenty service and subservice pages, fourteen homepage service cards and a dedicated Industry News section. The aesthetic had to align with a newer sibling site without copying its implementation constraints.

The news archive added migration risk. Legacy articles under /news/ could carry search value, so the rebuild needed a deliberate path into /industry-news/, including redirects and a structure that supports future editorial automation.

Sector
Engine, vehicle and powertrain certification and emissions compliance
Was
WordPress with mixed WPBakery and native page structures
Content
Core pages, service hierarchy and a legacy technical-news archive
Goal
A coherent, maintainable and performance-conscious publishing foundation
What changed

Four systems replaced page-by-page maintenance.

01

One block-native frontend

The wireframe was rebuilt with GeneratePress, GenerateBlocks and a focused custom theme layer. Reusable typography, spacing, buttons, cards, headers and content sections replace the former mix of builder output and one-off markup.

02

Service content managed once

The fourteen primary service cards are modelled as structured content rather than copied homepage blocks. Thumbnails, descriptions and related page data can be updated centrally and reused across service grids and individual destinations.

03

Industry News became a real publishing section

Legacy material is mapped into a dedicated news structure with categories, archives, author presentation, related-article components and planned 301 redirects from old URLs. The migration protects useful content without preserving the old frontend.

04

Automation stops at editorial approval

n8n collects newsletter messages from a dedicated Gmail intake, parses each item, sends the prepared context to Claude and routes the result either to the Industry News post type or to an error-notification path. Publication remains a deliberate decision for the EngineCert team.

Editorial system

Industry News became a product surface. n8n became the preparation layer.

The legacy archive was not simply moved into a new template. It became a focused destination for regulatory analysis, categories, search, industry events and frequently asked questions — all assembled from reusable publishing components.

Full ECO Industry News staging page with five selected FAQs and no client-logo section, scaled to fit without cropping
Industry News Full page · five selected FAQs

The page brings regulatory updates, research, events and reference material into one structured publishing surface. Taxonomies, query loops and shared cards let new material enter the system without rebuilding the page around every article.

Behind it, a published n8n workflow turns a newsletter inbox into a controlled preparation queue. A Gmail trigger collects messages, a loop handles them one at a time, and dedicated parsing steps extract the useful newsletter content before an AI request is assembled.

Claude returns the contextualised material, which is parsed and checked before n8n sends a structured item to the custom WordPress carb-news endpoint. Failed AI parsing follows a separate Gmail notification branch, so an exception does not disappear silently inside the automation.

The boundary is deliberate: n8n prepares; the EngineCert team decides. Generated content remains unpublished until a reviewer checks the source, technical framing and relevance, then chooses publish or discard. Final payload handling, permissions and failure behaviour remain part of the pre-launch audit.

The build

A rebuild from the wireframe, not a reskin of the old pages.

The site was developed locally, versioned in a private repository and moved through a staging approval process. That kept the live site available while templates, content models and migration rules were tested as a complete system.

GeneratePress supplies the lean theme foundation; GenerateBlocks composes the page and query-loop structures; a custom child theme carries the visual system. A custom functionality plugin owns service and Industry News behaviour that should not be coupled to presentation.

ACF fields keep repeated metadata editable, including service descriptors and author profiles. Shared card components support both services and related news, while the pre-launch pass will check migrated content, redirects, brand consistency and responsive behaviour before the production switch.

Theme
GeneratePress + custom child theme and SCSS component layer
Blocks
GenerateBlocks page structures, templates and query loops
Content
Custom post types, taxonomies and ACF-managed metadata
Automation
Gmail intake, n8n orchestration, Claude contextualisation, WordPress REST delivery, error alerts and a human publication gate
SEO
Structured migration, redirects and preserved editorial URLs where appropriate
Delivery
Local development, private Git repository, staging and launch QA
Engineering decisions

The foundation was designed for the next edit, not just launch day.

Content model

Centralise what regulations can change

Service labels and descriptions can become outdated. Structured records let the team update that information once instead of finding every copied card.

Editorial safety

Automate preparation, not accountability

The content pipeline can collect and contextualise source material, but publication still requires a deliberate human decision from the EngineCert team.

Migration

Move URLs with a map, not by accident

Legacy news and renamed services are handled as migration decisions with explicit destinations and redirects, rather than cleanup performed after launch.

Next

Is your website carrying two generations of frontend decisions?

A rebuild is the opportunity to resolve the content model, editing workflow, performance foundation and migration plan together — before another layer is added.

A spreadsheet-grade import experience inside Gravity Forms.

Last updated: August 27, 2026

←  Selected work
Case study — application UX & data workflows

A spreadsheet-grade import experience inside Gravity Forms.

Schools onboarding to Gradelink already had their Staff, Classes, Students and Grades in spreadsheets. The work turned a custom Gravity Forms field into a Vue 3 application where those linked records can be imported, corrected and validated before the main onboarding form is submitted.

Client
Gradelink — K–12 student information system software company
Role
WordPress, Gravity Forms and Vue engineering, delivered white-label
Stack
Gravity Forms, Vue 3, Pinia, PHP, MySQL and OpenSpout
Scope
Custom field types, Excel/CSV import, linked data, resumable sessions and generated outputs
Product surface

A guided import, with the control of a spreadsheet.

The interface keeps bulk operations fast without making data quality invisible. Users can map an unfamiliar workbook, preview the result, then work directly with the imported records and their validation state.

Gradelink bulk-import wizard with fictional staff records and spreadsheet column mapping controls
Import Upload, select, map and preview
Gradelink linked-record workspace with fictional Staff, Classes, Students and Grades data and a cell-level validation error
Review Inline CRUD, bulk actions and cell-level errors

Interface screenshots contain fictional demonstration school, staff, contact and record data. No client, school, staff or student data is shown.

The problem

Uploading a CSV is easy. Trusting what is inside it is not.

Schools moving from another system rarely arrive with a clean template. Grade levels appear as “3”, “Grade 3” or “3rd Grade”; states may be names or abbreviations; phone formats vary; required columns are missing or named differently.

The records are also connected. A class needs a teacher already present in Staff, and one person can have an additional teaching role that must become a separate record in Gradelink’s target model. A flat file alone cannot preserve those rules.

The whole process happens before the school has an account. It has to survive page navigation, reloads and Save & Continue while still behaving like one coherent dataset inside a multi-page Gravity Forms flow.

Sector
EdTech and K–12 school onboarding
Input
Excel or CSV exports from a school’s previous system
Entities
Staff, Classes, Students and multiple Grade datasets
Constraint
Unauthenticated, multi-page and resumable before final submission
What the tool does

Four layers make bulk import safe enough for onboarding.

01

Turns one form field into an application

A custom Gravity Forms field type renders the Vue interface inside the existing Gravity Forms journey. Staff, Classes, Students and Grades become tabs with their own tables, pagination, inline editing and bulk operations.

02

Maps unfamiliar spreadsheets deliberately

The wizard separates file upload, worksheet selection and column mapping. A live preview makes the mapping visible before import, while normalisers translate common grade, state and phone variations into accepted values.

03

Uses the form’s own validation rules

Every imported row runs through Gravity Forms validation. Required fields, formats and configured choices stay aligned with the form admin instead of being copied into a second validator, and errors return to the exact cell that needs attention.

04

Preserves relationships while the dataset changes

Dynamic fields resolve a Class teacher against Staff created in the same session. Related-record checks prevent destructive edits, and Gradelink’s dual-role rule can create the additional Teacher record the destination model requires.

The build

Several Gravity Forms, presented as one linked dataset.

Each entity remains a separate nested Gravity Form, so field configuration and validation stay manageable in WordPress. The Vue application receives those form definitions from PHP and presents them as a single tabbed import workspace.

Rows are stored in dedicated MySQL tables generated for each linked form, keyed to the main form’s Save & Continue token. The dataset can be paginated, edited and resumed without packing hundreds of records into serialized entry metadata.

On final submission, the import session is attached to the Gravity Forms entry and one CSV is generated for each required entity. Hash-verified download and regenerate links make those artifacts available from the entry-detail screen without exposing the underlying upload directory.

Fields
Custom bulk-import and dynamic-dropdown Gravity Forms fields
Interface
Vue 3, Vite and a shared Pinia store
Parsing
Spatie SimpleExcel backed by Box/OpenSpout
Storage
Session-scoped custom MySQL tables, one schema per linked form
Resume
Gravity Forms autosave and Save & Continue token
Output
Generated CSVs with secure download and regeneration links
Engineering decisions

The difficult parts sit between the layers.

Validation

One rule engine, not two

Reusing Gravity Forms validation means an admin can change field requirements or choices without silently leaving the importer’s rules behind.

Persistence

Store rows as rows

Dedicated tables support filtering, pagination, bulk edits and relationships while keeping the eventual Gravity Forms entry compact and understandable.

Reuse

Carry proven plumbing forward

An internal namespaced toolkit supplied secure documents and generic data-store patterns, leaving this build to focus on Gradelink’s import and linking rules.

Next

Moving complex data through a WordPress workflow?

The upload is rarely the hard part. The real work is preserving validation, relationships, resumable state and usable feedback from source file to final output.

A subscription-based compliance platform for the air-cargo industry.

Last updated: August 27, 2026

←  Selected work
Case study — platform engineering & business workflows

A subscription-based compliance platform for the air-cargo industry.

World AVSEC turns the records behind TSA air-cargo compliance into a multi-role application: companies, facilities, employees, training, documents, subscriptions and partner authorisations in one system. WordPress and WooCommerce provide the foundation; the product logic lives in a custom application layer built around the way the supply chain actually works.

Client
World AVSEC — US aviation-security compliance company
Role
Full-stack platform engineering and long-term product development, delivered white-label
Stack
WordPress, WooCommerce Subscriptions, custom PHP, Vue.js and MySQL
Scope
Multi-role accounts, recurring billing, compliance records, documents and cross-company workflows
Product surface

Records inside one company. Trust between many companies.

The account area has to do two jobs at once: keep each facility’s compliance evidence current, then expose the right evidence when another business needs to verify and authorise a working relationship.

World AVSEC driver compliance screen with fictional STA expiry and training records
Compliance STA and training status at facility level
World AVSEC partner relationship screen with fictional facilities, compliance states and authorisation actions
Network Facility relationships and authorisation evidence

Interface screenshots contain fictional demonstration names, organisations, contact details, addresses and compliance records. No customer or user data is shown.

The problem

The compliance data was scattered. The obligation was not.

Air-cargo companies need current records for drivers, security threat assessments, mandatory training, facilities, vehicles, screening equipment and supporting documents. When those records live in spreadsheets, folders and email threads, answering a compliance question becomes a search exercise.

The data is relational. A user belongs to a company; a company can operate several facilities; each facility has its own employees, evidence, assets and subscription state. A flat membership plugin cannot represent that hierarchy safely or clearly.

The supply chain adds a second problem. An Indirect Air Carrier may need to work with an authorised representative in another market. Finding that facility, requesting a connection and exchanging authorisation evidence are part of the same operational workflow as the underlying compliance records.

Sector
TSA-regulated air-cargo security and logistics
Users
Indirect Air Carriers, authorised representatives, airlines and cargo screening facilities
Model
Company → facilities → users, drivers, records, assets and documents
Business
Recurring subscriptions at company and facility level
What the platform does

Four layers turn records into an operating system.

01

Models the business hierarchy

Role-aware registration creates the user, company and first facility together. From there, each organisation manages its facilities, employees, fleet, airport zones, screening equipment and secure documents in the right context.

02

Makes billing part of application state

WooCommerce Subscriptions is more than checkout. Company and facility access are gated by subscription status, and status-change hooks activate or deactivate the corresponding facilities without duplicating a second billing system.

03

Keeps evidence attached to the people and places it describes

Driver records hold STA numbers, status and expiry dates alongside required training and certificates. Teams can filter expired records, request training in bulk and export the current state when it needs to leave the platform.

04

Connects companies through an explicit workflow

Facilities can be found by location and capability, connection requests can be accepted or rejected, and authorisation letters can be generated as PDFs. Partner access builds on those relationships instead of exposing operational data publicly.

The build

A WordPress codebase organised like a product.

The custom domain plugin separates models, controllers, data stores, enumerations and email classes behind a namespaced autoloader. Business rules have a defined home instead of accumulating in a theme file or a chain of page-builder callbacks.

WooCommerce handles products, orders and recurring payments; the application layer maps those events onto companies and facilities. A custom theme and a partial Vue.js frontend provide the account experience without forcing every screen into a single frontend framework.

Google Places supports structured facility addresses. Secure document handlers keep upload and download permissions inside the platform, while a custom HTML-to-PDF layer turns signed authorisation records into portable evidence.

Core
Custom WordPress plugin and theme, PHP OOP and MySQL
Billing
WooCommerce + WooCommerce Subscriptions
Frontend
Server-rendered account screens with focused Vue.js components
Location
Google Maps Places autocomplete and geocoding
Documents
Secure uploads and downloads, plus generated PDF letters
Accounts
Role-aware registration, activation, 2FA and password-reuse protection
Engineering decisions

Where the architecture carries the business rules.

Data model

Model the supply chain, not a membership list

Companies, facilities and users are separate entities because ownership, billing, permissions and compliance evidence do not all live at the same level.

Commerce

Use subscription events as domain events

Payment state has a direct operational consequence. Mapping WooCommerce status changes onto facilities keeps billing and product access in one source of truth.

Maintainability

Give every rule a durable home

The domain plugin keeps models, persistence, workflows and email behaviour explicit, so the platform can evolve without turning the theme into the application.

Next

Building a portal that standard plugins cannot describe?

WordPress can support complex operational products when the data model, permissions, billing events and workflows are designed as one system. That architecture is the work — the interface is only where it becomes visible.

A calmer, clearer and faster digital experience for a family law firm.

Last updated: August 22, 2026

←  Selected work
Case study — redesign & WordPress rebuild

A calmer, clearer and faster digital experience for a family law firm.

A solo family-law practice had a website that read like a firm brochure — at the exact moment its visitors needed a guide. The work reframed the client journey and moved the frontend off Elementor onto GeneratePress and GenerateBlocks, migrating in place so every URL, page and piece of SEO equity survived the change.

Client
Solo family-law attorney, US Midwest
Role
Design direction and full frontend rebuild, working directly with the owner
Stack
GeneratePress + GenerateBlocks Pro on WP Engine
Scope
~24 pages, plus a new practice-area silo
Before / after

Same content. A different reading experience.

Nothing was rewritten. The copy, the practice areas and the URLs are the ones the firm already had — what changed is the order they arrive in and how much work the visitor has to do to find what applies to them.

Anonymized recreation of the former family-law homepage built with Elementor
Before Elementor build, headings set entirely in capitals
Anonymized recreation of the redesigned block-native family-law homepage
After GeneratePress + GenerateBlocks, block-native

Client identity, contact details and imagery have been anonymized. The layouts shown are faithful recreations of the original pages.

The problem

A brochure, at the moment someone needs a guide.

“It feels more like a traditional law firm brochure than a client acquisition tool. I don’t think the site immediately connects with those concerns or clearly guides them toward contacting us.”

The firm’s owner, at kickoff

People land on a family-law site in the middle of a divorce, a custody dispute or a support modification. They arrive overwhelmed, and they are holding one question: can this firm help me, and what do I do next?

The old site answered neither quickly. Practice areas sat behind a dropdown, the attorney herself appeared well below the fold, reviews were not visible at all, and every heading on the page was set in capitals — which flattens hierarchy and makes a page harder to scan precisely when a visitor has the least patience for scanning it.

Underneath the design problem was a structural one. The frontend was built in Elementor, which meant every page carried the builder’s markup and asset weight, and any future change meant editing inside the builder rather than reusing a component.

Sector
Family law — divorce, custody, support, modification
Practice
Solo attorney with one assistant
Was
WordPress + Elementor
Goal
More qualified consultation enquiries — call, booking or form
What changed

Four decisions did most of the work.

01

Practice areas move to the front

The first thing a visitor sees is whether their situation is one this firm handles. Practice areas came out of the navigation dropdown and onto the page as a labelled index, so recognition happens in seconds rather than after a hunt.

02

Trust signals became visible, not implied

The attorney appears prominently and early — she was comfortable with that, and for a solo practice she is the offer. Alongside her: client reviews shown with their star ratings, and the credentials that actually differentiate her — guardian ad litem and mediator certifications, continuing-education speaking, and press coverage of a landmark case.

03

One next step, explained before it is asked for

The contact form is the primary action, with the phone number present throughout rather than parked on a contact page. The intake process is laid out as its own section — call, schedule, meet, review and sign, begin — because someone deciding whether to make that call wants to know what happens after it. The firm does not offer free consultations, so no call to action pretends otherwise.

04

Typography carries hierarchy again

Headings came out of all-capitals and into a real type scale, on consistently light backgrounds with no heavy dark breaks. The brief the owner gave was “clean, light, airy” — for an audience arriving under stress, the calm is functional, not decorative.

The rebuild

A migration in place, not a new site.

The site had years of accumulated search equity on URLs that were working. A from-scratch rebuild would have meant a new permalink structure, a redirect map to maintain, and a period of ranking volatility for a practice whose enquiries come largely from local search.

So the live site was cloned, and Elementor was swapped out for GeneratePress and GenerateBlocks in place, slug for slug. Blog posts were clean prose and moved across directly; the builder-made service pages were rebuilt as blocks. Almost nothing needed redirecting.

A new estate-planning practice area was added as a proper silo — one landing page with four service pages nested under it — using copy the owner had already written, used as supplied.

The contact form was written directly rather than pulled in from a form plugin: fewer moving parts, no plugin licence to renew, and no third-party script on the page carrying the firm’s most sensitive traffic. Scheduling runs through an embedded booking tool, and tag management was consolidated into the client’s own container so she owns her tracking outright.

Theme
GeneratePress + GenerateBlocks Pro, on the client’s own licence
Hosting
WP Engine
Forms
Custom-coded contact form — no form plugin
Booking
Embedded scheduling
Tracking
Client-owned tag manager container
Migration
Clone and swap in place, same slugs, no redirect map
Judgement calls

The decisions that were not on the brief.

Scope

Migrate, don’t rebuild

A clean rebuild is faster to quote and easier to execute. Cloning and swapping in place is more fiddly, but it keeps the URLs, the media library and the rankings — which is what the client is actually paying to protect.

Sequencing

One go-live, not two

The signed proposal had the new homepage launching first, with the old builder still running the rest of the site. I argued against my own accepted terms: a visible stretch of two different designs and two performance profiles costs more credibility than a later launch does.

Detail

Catch the wrong address

The approved design carried a street address the firm had moved away from. Caught and corrected before build, not after a client walked to the wrong building — the kind of error a page builder will happily ship at any scale.

Next

Sitting on a page builder you have outgrown?

Most of these rebuilds start the same way: the site still works, but every change is slow, the pages are heavier than they should be, and nobody wants to touch the URLs. That migration is a solved problem — it just has to be done deliberately.