FCHubFCHub.co

Changelog

The full paper trail for a plugin that does one thing and refuses to apologise for it.

What changed, when, and — in most cases — why the version number moved.


August 2026

v1.1.0

Released 9 August 2026 — GitHub Release

Endpoints can now choose where they sit in the customer portal menu, instead of always queuing up behind Profile like everybody else.

Requested by @Joe-Bloggs in #62 and tracked in #141. The endpoint editor has a new Menu Placement field: put an endpoint at the top, directly under Dashboard, after any other built-in item, or at the very bottom. Existing endpoints keep the slot they already had, so upgrading moves nothing.

FluentCart's API drops every custom endpoint immediately before profile and offers no position argument, so the finished menu is reordered afterwards on fluent_cart/global_customer_menu_items. Items belonging to other plugins are passed through untouched — this reorders, it never curates.

Placement is anchored, not numbered, and that is the interesting part

FluentCart's menu is not the same for every visitor: it hides Licenses without Pro or with the license module off, and hides Subscription Plans from customers who have none. An absolute "position 2" would therefore land beside a different neighbour for different people — a promise nobody can keep.

So placement anchors to a named item and degrades honestly. Choose "After Licenses" on a site with no licenses and the endpoint takes the slot where Licenses would have been, by walking up to the nearest visible item. "Before Subscription Plans" walks down for the same reason. Either way it lands in the same visual gap rather than at the bottom of the menu.

Portal Extender has tests now

It had none. It has 57, covering placement resolution, hidden anchors, grouped endpoints, third-party items surviving a reorder, and the icon sanitiser whitelist from 1.0.4 — including a test that scans every permitted attribute for anything shaped like an event handler, so that whitelist cannot quietly widen later. The plugin is now in the CI matrix on PHP 8.4 and 8.5.

v1.0.4

Released 9 August 2026 — GitHub Release

Endpoint icons now appear on the front end, which is where icons are generally most useful.

Icons survive the trip to the customer portal

Reported by @Joe-Bloggs in #62: the icon showed in the admin, picked correctly, saved correctly — and then rendered as nothing at all in the portal.

FluentCart runs every portal menu icon through wp_kses() with a whitelist of svg, path and g. Nothing else survives. A Dashicon is a <span>, so it was deleted outright and could never render. Any SVG built from circle, rect, line or polyline came out as an empty <svg></svg>. And viewBox was stripped from everything, because wp_kses lowercases attribute names before matching while the whitelist key is camelCase.

Portal Extender now widens that whitelist through FluentCart's own fct_allowed_svg_tags filter, merging on top of it rather than replacing it, so other plugins' entries survive. The shape elements, the stroke and fill presentation attributes, lowercase viewbox and the Dashicon <span> are all allowed through.

It remains a whitelist. script, foreignObject, use, xlink:href, href, inline event handlers and style on SVG elements are still stripped, and that is covered by a test that throws a deliberately hostile icon at it.

Dashicons are actually loaded now

Surviving sanitisation is only half of it — WordPress does not load the Dashicons stylesheet on the front end for ordinary visitors, so the markup would have rendered as an empty box regardless. The stylesheet is now enqueued on the portal, and only when an active endpoint genuinely uses a Dashicon.

Reordering endpoints within the portal menu was requested in the same issue and is tracked separately in #141. No FluentCart change is needed for it — the interesting part is that FluentCart hides licenses and subscriptions from some visitors, so an absolute "position 2" is not a promise anyone can keep.

March 2026

v1.0.3

Released 6 March 2026 — GitHub Release

Fixed a fatal error when multiple FCHub plugins are active at the same time. The shared GitHubUpdater class used a class_exists guard that PHP's OPcache cheerfully ignored during early class binding — so the second plugin to load would redeclare the class and take the site down. Wrapped the class inside the conditional so OPcache actually respects it.

v1.0.2

Released 3 March 2026 — GitHub Release

Minimum PHP bumped to 8.1, minimum WordPress to 6.4. Functionally identical to v1.0.1. Your portal pages still work exactly the same — I just stopped pretending PHP 7.4 was acceptable.

v1.0.1

Released 3 March 2026 — GitHub Release

First release under the monorepo slash-tag convention. The plugin didn't change. The tag format did. Milestones come in all shapes and sizes.

v1.0.0

Released 3 March 2026 — GitHub Release

The initial release. FluentCart's customer portal is useful — but it only shows what FluentCart decides to show. This plugin adds custom pages to it, no PHP required. Build a "Manage Subscription" page with an embedded form. Add a help centre link. Stick a shortcode in there. Whatever your portal is missing, you can probably add it now.

Content sources

Six ways to populate a custom portal page:

SourceWhat it renders
WordPress PageRenders an existing page by ID — content, blocks, the lot
ShortcodeAny shortcode, executed in portal context
HTMLRaw HTML, for when you know exactly what you want
iframeEmbed external tools, forms, or dashboards
RedirectSends the user somewhere else — portal page as a nav shortcut
Post / CPTAny post or custom post type by ID

Icons and display

Three icon types for your custom nav entries: SVG (inline), Dashicons (WordPress native), or image URL. Supports dark mode out of the box — icons and labels adapt without extra configuration.

Reorder portal pages via drag-and-drop. Toggle endpoints active or inactive without deleting them. Slugs auto-generate from the page title, or set your own.

Cleanup

Full uninstall cleanup. When you remove the plugin, it removes its database entries. No ghost data lingering in your wp_options.

On this page