Work / CMS & E-commerce

Enterprise WordPress Platform

Editors needed to change pages without a release, so the site stayed on WordPress. Checkout rules and partner calls live in a PHP plugin I can diff. The theme is the templates.

  • Custom theme
  • Custom plugin
  • WooCommerce
  • API integration
  • Performance
  • Security
  • Cloudflare
  • SEO
  • Migration

01

Project overview

The client needed editors to change pages without a deploy. I left WordPress as that tool and put the shop rules in a plugin, not in a pile of builder widgets.

02

While someone is using it

Editors had to change a headline without a release. The catalog was slow if every visit rebuilt the same queries. A cache that ignored the cart cookie could show one shopper another shopper’s basket.

An editor publishes in WordPress. A shopper browses a cached catalog, then adds to a cart that is not cached. Checkout stays in the request. The slow partner call does not.

  1. An editor publishes

    The change is a page or a block pattern, not a deploy. The next anonymous visit can be served as cached HTML. Checkout rules are not in that page. They stay in the plugin.

  2. A shopper browses

    Catalog HTML for a visitor with no cart cookie can sit at Cloudflare. The same person, once they have a WooCommerce session cookie, bypasses that cache.

  3. They add to the cart

    Cart, checkout, and account are not public cache objects. One shopper’s basket is not stored as HTML another shopper can be given.

  4. They check out

    The payment handoff stays in the request. A slow partner call is scheduled from the plugin. The thank-you page does not wait on it, and it does not pretend the call already finished.

  5. Another shopper arrives

    They get their own cart. They cannot open the first shopper’s basket. A shop manager can open orders. An editor can change pages and cannot change those orders.

03

Business problem

Once the real rules live in a page builder, nobody can review them. Catalog pages also get slow if every visit rebuilds the same queries. Worse, a cache that ignores the cart cookie can show one shopper another shopper’s cart.

04

Requirements

  • Editors can change content without a deploy. Business rules cannot depend on a page-builder widget.
  • WooCommerce stays compatible with updates. Custom behavior lives in a plugin, not in edited plugin files.
  • Anonymous catalog pages cache. Cart, checkout and account pages do not.
  • External systems integrate through explicit APIs, not through shared database writes.
  • A migration can be rehearsed, and the public site keeps a rollback path.

05

Who can do what

Editors change pages. The shop manager runs orders. A customer only has their own cart. Checkout rules and the cache bypass are not buttons in the theme.

Action Editor Shop manager Customer
Change a page without a deploy Yes No No
Edit products and orders No Yes Own orders
Change checkout rules or partner calls No No No
Use cart, checkout, and account No No Own only
See another shopper’s basket No No No

Plugin settings and the Cloudflare bypass live in the deploy, not in a user role. A customer never gets that screen. A cart cookie is what keeps their HTML out of the public cache.

06

How it’s wired

Cloudflare sits in front of the site and caches anonymous HTML and assets according to rules, bypassing any request with a WooCommerce session cookie. PHP and WordPress run behind that. A custom theme renders templates. A custom plugin owns domain behavior, admin settings that actually matter, and REST endpoints. MySQL stores content and orders. Outbound integrations leave through the plugin, queued when the work is slower than a page view.

  1. Cloudflare
  2. WordPress theme
  3. Custom plugin
  4. MySQL
  5. REST integrations

07

What I used

These are the tools on this project. I didn’t add anything just to fill a stack diagram.

  • WordPress
  • PHP
  • WooCommerce
  • MySQL
  • Cloudflare
  • REST API

08

Technical challenges

  • Full-page caching and WooCommerce sessions disagree unless the cache key and bypass rules are explicit.
  • Logic trapped in the theme is hard to reuse from wp-cron, WP-CLI or a REST request.
  • Migrations fail when the new environment’s URLs, media and plugin versions were never rehearsed against a copy of production data.

09

Solution

Keep the theme presentational. Put integrations, checkout adjustments and admin tools in a plugin with a small service layer. Cache anonymous pages at Cloudflare and send cache-bypass headers, or cookie rules, for cart, checkout, account and preview. Expose a narrow REST surface for other systems instead of giving them database credentials. Run migrations against a staging copy, then switch traffic only after content, redirects and checkout smoke tests pass.

10

Implementation

The theme uses classic templates and block-ready patterns where editors need flexible landing pages, without rebuilding the catalog in a builder. The plugin registers its own hooks, settings and REST routes, and it escapes output and checks nonces on every state-changing admin action. WooCommerce customizations use documented hooks. Slow partner calls are scheduled, not executed inside the thank-you page request. SEO output comes from real titles, canonicals and structured data for content types the site actually publishes.

11

Testing

Smoke tests cover the catalog, a guest cart, checkout up to the payment handoff, and a logged-in account page. A cache test asserts that a cart cookie is not stored as a public CDN object. Plugin tests cover the REST permission checks and the nonce on admin actions. A staging migration is part of the release, not an afterthought.

12

Deployment

Code moves through version control. Uploads and the database move through a documented migration, not through editing production over FTP. Cloudflare holds the edge cache. PHP opcache and a persistent object cache reduce repeated MySQL reads for options and menus. Rollback is the previous release plus a database backup taken immediately before the migration.

13

Outcome

Editors still have WordPress. I still have a plugin, a cache rule that skips the cart, and a migration I had already run on a copy before the switch.

14

What I decided

  • A custom plugin for behavior and a custom theme for presentation, so a redesign does not require rewriting integrations.
  • Cloudflare bypass on commerce cookies, because a fast wrong cart is worse than an uncached checkout.
  • REST for integrations, so another system does not become coupled to WordPress table names.

Start a project