eighteen73/universal-product-sort

Per-category WooCommerce product sorting plugin.

Maintainers

Package info

github.com/eighteen73/universal-product-sort

Type:wordpress-plugin

pkg:composer/eighteen73/universal-product-sort

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.0 2026-04-17 13:49 UTC

This package is auto-updated.

Last update: 2026-04-20 10:43:12 UTC


README

Category-specific product ordering for WooCommerce. Each product category can have its own drag-and-drop order in the admin; that order is applied on the storefront when customers browse that category (subject to the rules below).

Requirements

  • WordPress 6.8 or higher.
  • PHP 7.4 or higher.
  • WooCommerce — the plugin targets WooCommerce products (product), the product_cat taxonomy, and Woo’s “Sorting” list behaviour in admin. WooCommerce should be active before relying on this plugin.

What it does

Admin: per-category manual order

WooCommerce’s default product ordering UI uses a single menu_order on each product. This plugin stores a separate ordered list of product IDs per category in term meta, so “position 3 in Category A” does not have to match “position 3 in Category B.”

When you are on the Products list with:

  • Screen: Products (edit-product)
  • Order: “Custom ordering” / sort by Menu order (the orderby value is menu_order title)
  • Category filter: a single product category selected in the URL (product_cat=<slug>)

…the plugin replaces Woo’s default ordering script with **assets/js/admin-product-ordering.js**. Drag-and-drop sends an AJAX request (action: universal_product_sort_ordering) that:

  • Verifies capability (edit_products) and a dedicated nonce.
  • Ensures the product belongs to the filtered category.
  • Recomputes the category’s product order and saves it.

The response includes updated menu_order values for the list UI so the table stays consistent with the new sequence.

Where the order is stored

  • Term meta key: _universal_product_sort_category_order
  • Value: array of product IDs in display order for that category.

The repository (CategoryOrderRepository) reconciles stored IDs with products actually in the category: unknown IDs are dropped; products in the category but missing from the saved list are appended (after stored IDs), using Woo’s default menu_order title query as the basis for “current” category membership.

Frontend: when custom order applies

CategoryQueryOrdering hooks pre_get_posts and posts_clauses to apply the saved order when:

  • The query is for WooCommerce products and relates to product_cat (taxonomy archive, product_cat query var, or a tax_query that includes product_cat), and
  • The request has not set an explicit orderby query parameter — in that case the plugin only applies custom order if the resolved orderby is effectively “menu order” style (menu_order, menu_order title, or post__in).

Ordering uses SQL FIELD() on the resolved ID list, with products not in the list sorted after, then menu_order and post_title as tie-breakers.

Internal lookups (e.g. loading all product IDs in a category) set a query flag so the plugin does not recurse into its own ordering logic.

Caches

Resolved order per category is cached in the object cache (wp_cache_*) under the group universal_product_sort. Caches are invalidated when product–category relationships change, when categories are created/edited/deleted, and when order is saved.

Development

  • PHP namespace: Eighteen73\UniversalProductSort — PSR-4 autoload from includes/classes/.
  • Composer scripts: composer run lint / composer run format (PHPCS / PHPCBF).
  • npm scripts: lint, format, build, etc. — see package.json.

License

GPL-2.0-or-later.