{"id":281668,"date":"2026-02-16T19:33:25","date_gmt":"2026-02-16T19:33:25","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/advanced-post-order\/"},"modified":"2026-03-02T11:23:28","modified_gmt":"2026-03-02T11:23:28","slug":"bracket-post-order","status":"publish","type":"plugin","link":"https:\/\/mn.wordpress.org\/plugins\/bracket-post-order\/","author":23451845,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_crdt_document":"","version":"1.2.3","stable_tag":"1.2.3","tested":"6.9.4","requires":"6.2","requires_php":"7.4","requires_plugins":null,"header_name":"Bracket Post Order","header_author":"Bracket","header_description":"Drag-and-drop post ordering with per-taxonomy-term support. Reorder posts globally or within specific categories\/tags.","assets_banners_color":"","last_updated":"2026-03-02 11:23:28","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/wordpress.org\/plugins\/bracket-post-order\/","header_author_uri":"https:\/\/bracket.gr","rating":0,"author_block_rating":0,"active_installs":0,"downloads":209,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.2.2":{"tag":"1.2.2","author":"bracketdev","date":"2026-02-16 19:30:33"},"1.2.3":{"tag":"1.2.3","author":"bracketdev","date":"2026-03-02 11:23:28"}},"upgrade_notice":{"1.1.0":"<p>Major feature update: reset order, undo, mobile\/touch support, keyboard accessibility, WPML\/Polylang compatibility, and performance optimizations. All free.<\/p>","1.0.0":"<p>Initial release. If migrating from Simple Custom Post Order, your existing <code>menu_order<\/code> values are preserved \u2014 just enable the same post types in the Bracket Post Order settings.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3462862,"resolution":"128x128","location":"assets","locale":""},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3462862,"resolution":"256x256","location":"assets","locale":""},"icon.svg":{"filename":"icon.svg","revision":3462862,"resolution":false,"location":"assets","locale":false}},"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.2.2","1.2.3"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"Settings page \u2014 modern card-based UI with toggle switches for post types, taxonomies, and term ordering","2":"Global ordering \u2014 drag-and-drop rows on the standard post list table with order position column","3":"Per-term ordering \u2014 filter by a category, then drag posts into a term-specific order","4":"Term ordering \u2014 drag-and-drop taxonomy terms on the edit-tags screen","5":"Reset order \u2014 sort dropdown and reset button above the post list","6":"Undo \u2014 \"Order saved. Undo\" notice after every reorder"},"jetpack_post_was_ever_published":false},"plugin_section":[],"plugin_tags":[13016,3938,4648,2286,22237],"plugin_category":[],"plugin_contributors":[255985],"plugin_business_model":[],"class_list":["post-281668","plugin","type-plugin","status-publish","hentry","plugin_tags-custom-order","plugin_tags-drag-and-drop","plugin_tags-post-order","plugin_tags-reorder","plugin_tags-taxonomy-order","plugin_contributors-bracket","plugin_committers-bracketdev"],"banners":[],"icons":{"svg":"https:\/\/ps.w.org\/bracket-post-order\/assets\/icon.svg?rev=3462862","icon":"https:\/\/ps.w.org\/bracket-post-order\/assets\/icon.svg?rev=3462862","icon_2x":false,"generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p><strong>Bracket Post Order<\/strong> gives you complete control over how your content is sorted \u2014 directly from the native WordPress admin screens you already use. No new interfaces to learn, no separate reorder pages. Just drag and drop.<\/p>\n\n<p>A key feature is <strong>per-term post ordering<\/strong>: the ability to define a different post order for each individual category, tag, or custom taxonomy term. Show your products in one order on \"Summer Collection\" and a completely different order on \"Best Sellers\" \u2014 each term maintains its own independent sort.<\/p>\n\n<h4>Three Types of Ordering<\/h4>\n\n<p><strong>1. Global Post Ordering<\/strong>\nDrag-and-drop to reorder posts, pages, and custom post types on the standard admin list table. The new order is saved to <code>menu_order<\/code> and automatically applied on the front end.<\/p>\n\n<p><strong>2. Per-Term Post Ordering<\/strong>\nFilter your admin list by a category or taxonomy term, and the interface switches to per-term mode. Drag posts into the order you want for <em>that specific term<\/em>. Assign the same post to multiple categories \u2014 each one keeps its own sort. New posts added to a term automatically appear first (newest on top).<\/p>\n\n<p><strong>3. Taxonomy Term Ordering<\/strong>\nReorder categories, tags, and custom taxonomy terms themselves via drag-and-drop on the native <code>edit-tags.php<\/code> screen. The new term order is applied to <code>get_terms()<\/code> queries and navigation menus on the front end.<\/p>\n\n<h4>Key Features<\/h4>\n\n<ul>\n<li><strong>Reset Order<\/strong> \u2014 Reset post order by date or title with one click. Most requested feature across all ordering plugins.<\/li>\n<li><strong>Undo<\/strong> \u2014 \"Order saved. [Undo]\" link appears for 8 seconds after every reorder. Click to revert instantly.<\/li>\n<li><strong>Mobile\/Touch Support<\/strong> \u2014 Full touch drag-and-drop on phones and tablets via jQuery UI Touch Punch.<\/li>\n<li><strong>Keyboard Accessibility<\/strong> \u2014 Tab to a row, Enter to activate, Arrow keys to move, Enter to save, Escape to cancel. WCAG compliant.<\/li>\n<li><strong>Order Column<\/strong> \u2014 \"#\" column shows each post's position number at a glance.<\/li>\n<li><strong>WPML &amp; Polylang Support<\/strong> \u2014 Per-term ordering works correctly across languages.<\/li>\n<li><strong>Admin Bar Indicator<\/strong> \u2014 Shows current ordering mode (Global or Per-Term) in the admin bar.<\/li>\n<li><strong>Settings Link<\/strong> \u2014 Quick access from the Plugins page.<\/li>\n<\/ul>\n\n<h4>How It Works<\/h4>\n\n<ol>\n<li>Go to <strong>Settings &gt; Bracket Post Order<\/strong><\/li>\n<li>Toggle on the post types you want to reorder<\/li>\n<li>Toggle on taxonomies for per-term post ordering<\/li>\n<li>Toggle on taxonomies for term reordering<\/li>\n<li>Visit your admin list pages and start dragging<\/li>\n<\/ol>\n\n<p>Changes save automatically via AJAX \u2014 no page refresh needed.<\/p>\n\n<h4>Built for WordPress, Not Against It<\/h4>\n\n<ul>\n<li>Works directly inside native admin list tables (<code>edit.php<\/code> and <code>edit-tags.php<\/code>)<\/li>\n<li>Uses standard <code>menu_order<\/code> for global ordering \u2014 compatible with any theme<\/li>\n<li>Uses <code>term_order<\/code> for taxonomy terms \u2014 the same column WordPress defines<\/li>\n<li>Per-term order stored as term meta \u2014 clean, portable, conflict-free<\/li>\n<li>Front-end queries are modified transparently via <code>pre_get_posts<\/code> and <code>posts_clauses<\/code><\/li>\n<li>Explicit <code>orderby<\/code> parameters (date, title, etc.) are never overridden<\/li>\n<\/ul>\n\n<h4>Works With<\/h4>\n\n<ul>\n<li>Any public custom post type (portfolios, team members, testimonials, events, FAQs, services)<\/li>\n<li>WooCommerce products and product categories<\/li>\n<li>Any registered taxonomy with a UI<\/li>\n<li>Page builders that use standard <code>WP_Query<\/code> (Elementor, Divi, Beaver Builder)<\/li>\n<li>Themes that follow WordPress template hierarchy<\/li>\n<li>WPML and Polylang multilingual plugins<\/li>\n<\/ul>\n\n<h4>For Developers<\/h4>\n\n<p>Bracket Post Order provides hooks so you can extend or control its behavior:<\/p>\n\n<pre><code>\/\/ Filter: skip per-term ordering for a specific query\nadd_filter( 'bracket_po_apply_term_post_order', function( $apply, $term_id, $query ) {\n    \/\/ Return false to skip\n    return $apply;\n}, 10, 3 );\n\n\/\/ Filter: modify the retrieved term post order\nadd_filter( 'bracket_po_get_term_post_order', function( $ordered_ids, $term_id ) {\n    return $ordered_ids;\n}, 10, 2 );\n\n\/\/ Actions: fired after order is saved via drag-and-drop\ndo_action( 'bracket_po_global_order_updated', $post_ids );\ndo_action( 'bracket_po_term_post_order_updated', $term_id, $post_ids );\ndo_action( 'bracket_po_term_order_updated', $term_ids );\n\n\/\/ Actions: fired after order is reset\ndo_action( 'bracket_po_global_order_reset', $post_type, $sort_by );\ndo_action( 'bracket_po_term_post_order_reset', $term_id );\n<\/code><\/pre>\n\n<p>To apply per-term order in custom queries, set <code>orderby<\/code> to <code>menu_order<\/code> and include a <code>tax_query<\/code> with a single term:<\/p>\n\n<pre><code>$query = new WP_Query( [\n    'post_type' =&gt; 'product',\n    'orderby'   =&gt; 'menu_order',\n    'order'     =&gt; 'ASC',\n    'tax_query' =&gt; [ [\n        'taxonomy' =&gt; 'product-category',\n        'field'    =&gt; 'term_id',\n        'terms'    =&gt; 42,\n    ] ],\n] );\n<\/code><\/pre>\n\n<p>The plugin will automatically apply the saved per-term order via <code>FIELD()<\/code> SQL \u2014 posts not in the saved order appear first (newest on top).<\/p>\n\n<!--section=installation-->\n<h4>Automatic Installation<\/h4>\n\n<ol>\n<li>In your WordPress admin, go to <strong>Plugins &gt; Add New<\/strong><\/li>\n<li>Search for \"Bracket Post Order\"<\/li>\n<li>Click <strong>Install Now<\/strong>, then <strong>Activate<\/strong><\/li>\n<li>Go to <strong>Settings &gt; Bracket Post Order<\/strong> to configure<\/li>\n<\/ol>\n\n<h4>Manual Installation<\/h4>\n\n<ol>\n<li>Download the plugin ZIP file<\/li>\n<li>Upload the <code>bracket-post-order<\/code> folder to <code>\/wp-content\/plugins\/<\/code><\/li>\n<li>Activate the plugin through the <strong>Plugins<\/strong> menu<\/li>\n<li>Go to <strong>Settings &gt; Bracket Post Order<\/strong> to configure<\/li>\n<\/ol>\n\n<h4>Configuration<\/h4>\n\n<ol>\n<li>Navigate to <strong>Settings &gt; Bracket Post Order<\/strong><\/li>\n<li>In the <strong>Post Types<\/strong> card, toggle on each post type you want to reorder<\/li>\n<li>In the <strong>Per-Term Post Ordering<\/strong> card, toggle on taxonomies (taxonomies appear automatically based on your enabled post types)<\/li>\n<li>In the <strong>Term Ordering<\/strong> card, toggle on taxonomies whose terms you want to reorder<\/li>\n<li>Click <strong>Save Changes<\/strong><\/li>\n<\/ol>\n\n<p>That's it. Visit any enabled post type list and start dragging rows.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20this%20work%20with%20custom%20post%20types%3F\"><h3>Does this work with custom post types?<\/h3><\/dt>\n<dd><p>Yes. Any post type with <code>show_ui =&gt; true<\/code> appears in the settings. This includes WooCommerce products, portfolio items, team members, testimonials, events, and any custom post type registered by your theme or plugins.<\/p><\/dd>\n<dt id=\"how%20does%20per-term%20ordering%20work%3F\"><h3>How does per-term ordering work?<\/h3><\/dt>\n<dd><p>When you filter the admin post list by a taxonomy term (e.g., selecting a specific category from the dropdown), the plugin switches to per-term mode. An info notice appears confirming the mode. Drag posts into the order you want \u2014 that order is saved exclusively for that term.<\/p>\n\n<p>The same post can belong to multiple terms, and each term maintains its own independent order.<\/p><\/dd>\n<dt id=\"does%20the%20custom%20order%20appear%20on%20the%20front%20end%3F\"><h3>Does the custom order appear on the front end?<\/h3><\/dt>\n<dd><p>Yes. The plugin hooks into <code>pre_get_posts<\/code> and <code>posts_clauses<\/code> to automatically apply the saved order to front-end queries. For global ordering, it sets <code>orderby =&gt; menu_order<\/code>. For per-term ordering, it modifies the SQL <code>ORDER BY<\/code> clause using <code>FIELD()<\/code> so your saved order is respected while keeping pagination and other query parameters intact.<\/p><\/dd>\n<dt id=\"what%20if%20i%20set%20an%20explicit%20orderby%20in%20my%20query%3F\"><h3>What if I set an explicit orderby in my query?<\/h3><\/dt>\n<dd><p>The plugin never overrides explicit <code>orderby<\/code> parameters other than <code>menu_order<\/code>. If your query uses <code>orderby =&gt; date<\/code>, <code>title<\/code>, <code>meta_value<\/code>, or anything else, the plugin leaves it alone. This is by design \u2014 your code always takes priority.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20woocommerce%3F\"><h3>Does it work with WooCommerce?<\/h3><\/dt>\n<dd><p>Yes. Enable the \"Products\" post type and relevant product taxonomies in the settings. The plugin works with WooCommerce product categories and tags for both global and per-term ordering.<\/p><\/dd>\n<dt id=\"can%20i%20reorder%20taxonomy%20terms%20%28categories%2C%20tags%29%3F\"><h3>Can I reorder taxonomy terms (categories, tags)?<\/h3><\/dt>\n<dd><p>Yes. Enable term ordering for any taxonomy in the settings. Then go to that taxonomy's admin page (e.g., Posts &gt; Categories) and drag terms into your preferred order. The new order is applied to <code>get_terms()<\/code> queries on the front end.<\/p><\/dd>\n<dt id=\"how%20do%20i%20reset%20the%20order%3F\"><h3>How do I reset the order?<\/h3><\/dt>\n<dd><p>Click the \"Reset Order\" button above the post list table. Choose a sort method (Date newest\/oldest, Title A-Z\/Z-A) and confirm. For per-term mode, resetting removes the custom order for that term.<\/p><\/dd>\n<dt id=\"does%20it%20work%20on%20mobile%2Ftablet%3F\"><h3>Does it work on mobile\/tablet?<\/h3><\/dt>\n<dd><p>Yes. Version 1.1.0 includes full touch support. Drag-and-drop works on phones and tablets with properly sized touch targets.<\/p><\/dd>\n<dt id=\"is%20it%20accessible%20via%20keyboard%3F\"><h3>Is it accessible via keyboard?<\/h3><\/dt>\n<dd><p>Yes. Tab to any row, press Enter or Space to activate reorder mode, use Arrow Up\/Down to move the row, Enter to save, or Escape to cancel. Screen reader announcements are provided via ARIA live regions.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20wpml%20or%20polylang%3F\"><h3>Does it work with WPML or Polylang?<\/h3><\/dt>\n<dd><p>Yes. The plugin automatically detects WPML and Polylang and maps per-term ordering to work correctly across languages.<\/p><\/dd>\n<dt id=\"does%20clicking%20a%20column%20header%20disable%20drag-and-drop%3F\"><h3>Does clicking a column header disable drag-and-drop?<\/h3><\/dt>\n<dd><p>Yes. When you click a column header to sort by title, date, etc., the plugin detects the <code>orderby<\/code> URL parameter and disables drag-and-drop. Removing the sort (clicking the post type menu link again) re-enables it.<\/p><\/dd>\n<dt id=\"does%20it%20affect%20search%20results%3F\"><h3>Does it affect search results?<\/h3><\/dt>\n<dd><p>No. The plugin only applies its ordering to queries for enabled post types that don't have an explicit <code>orderby<\/code> set. WordPress search queries use relevance-based sorting, which the plugin does not interfere with.<\/p><\/dd>\n<dt id=\"is%20it%20compatible%20with%20page%20builders%3F\"><h3>Is it compatible with page builders?<\/h3><\/dt>\n<dd><p>Yes. Elementor, Divi, Beaver Builder, and other page builders that use standard <code>WP_Query<\/code> will respect the custom order. If the builder lets you set <code>orderby<\/code> to <code>menu_order<\/code>, the per-term ordering also works automatically.<\/p><\/dd>\n<dt id=\"what%20happens%20when%20i%20add%20a%20new%20post%20to%20a%20category%20that%20has%20a%20custom%20order%3F\"><h3>What happens when I add a new post to a category that has a custom order?<\/h3><\/dt>\n<dd><p>New posts that aren't part of the saved per-term order automatically appear first (sorted by date, newest on top). You can then go to the admin, filter by that term, and drag the new post into position.<\/p><\/dd>\n<dt id=\"is%20it%20compatible%20with%20simple%20custom%20post%20order%20%28scpo%29%3F\"><h3>Is it compatible with Simple Custom Post Order (SCPO)?<\/h3><\/dt>\n<dd><p>The plugin detects SCPO and displays an admin notice recommending deactivation. If both are active, Bracket Post Order dequeues SCPO's scripts on pages where it is active to prevent conflicts. For best results, deactivate SCPO before using this plugin.<\/p><\/dd>\n<dt id=\"does%20it%20support%20multisite%3F\"><h3>Does it support multisite?<\/h3><\/dt>\n<dd><p>Yes. The plugin works on individual sites within a multisite network. Each site maintains its own settings and post order.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.2.3<\/h4>\n\n<ul>\n<li>Fixed: New posts added to a term with per-term ordering now appear first instead of last<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>New: Settings link on the Plugins page for quick access<\/li>\n<li>New: Admin bar indicator showing current ordering mode (Global or Per-Term)<\/li>\n<li>New: Order position \"#\" column on admin post list tables<\/li>\n<li>New: Reset Order button with sort options (Date DESC\/ASC, Title A-Z\/Z-A) for both global and per-term modes<\/li>\n<li>New: Undo last reorder \u2014 \"Order saved. [Undo]\" link with 8-second timeout<\/li>\n<li>New: Green highlight animation on rows after save<\/li>\n<li>New: Drag handle (vertical dots) visible on row hover<\/li>\n<li>New: Enhanced sortable placeholder and helper styles<\/li>\n<li>New: 800ms debounce on AJAX saves to prevent rapid drag spam<\/li>\n<li>New: Mobile\/touch drag-and-drop support via jQuery UI Touch Punch<\/li>\n<li>New: Touch-friendly CSS \u2014 48px min-height targets on coarse pointer devices<\/li>\n<li>New: Full keyboard accessibility \u2014 Enter\/Space to activate, Arrow keys to move, Enter to save, Escape to cancel<\/li>\n<li>New: ARIA live region for screen reader announcements (WCAG compliance)<\/li>\n<li>New: WPML compatibility \u2014 per-term ordering works across languages<\/li>\n<li>New: Polylang compatibility \u2014 per-term ordering works across languages<\/li>\n<li>Performance: Optimized admin_init refresh \u2014 only recalculates menu_order when posts actually change (transient-based staleness detection)<\/li>\n<li>Improved: Sortable helper has larger shadow and subtle scale<\/li>\n<li>Improved: Focus ring styles for keyboard navigation<\/li>\n<li>Updated: uninstall.php cleans up transients<\/li>\n<li>Developer: New <code>bracket_po_global_order_reset<\/code> action<\/li>\n<li>Developer: New <code>bracket_po_term_post_order_reset<\/code> action<\/li>\n<\/ul>\n\n<h4>1.0.2<\/h4>\n\n<ul>\n<li>Fixed table layout during drag-and-drop on some environments<\/li>\n<li>Improved first-time post ordering initialization<\/li>\n<li>Auto-detection and repair of menu_order gaps<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>Improved WordPress coding standards compliance<\/li>\n<li>Settings page UX improvements<\/li>\n<li>Minor code quality and compatibility fixes<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release<\/li>\n<li>Global post ordering via <code>menu_order<\/code> with drag-and-drop on admin list tables<\/li>\n<li>Per-taxonomy-term post ordering \u2014 independent sort order for each category\/tag\/term<\/li>\n<li>Taxonomy term ordering via drag-and-drop on <code>edit-tags.php<\/code><\/li>\n<li>Modern settings page with card layout and toggle switches<\/li>\n<li>Dynamic taxonomy visibility \u2014 toggling a post type instantly shows its taxonomies<\/li>\n<li>Transparent <code>WP_Query<\/code> integration via <code>pre_get_posts<\/code> and <code>posts_clauses<\/code><\/li>\n<li>Per-term ordering uses SQL <code>FIELD()<\/code> for native pagination support<\/li>\n<li>Automatic conflict detection and script dequeuing for Simple Custom Post Order<\/li>\n<li>Developer hooks: <code>bracket_po_apply_term_post_order<\/code>, <code>bracket_po_get_term_post_order<\/code>, <code>bracket_po_global_order_updated<\/code>, <code>bracket_po_term_post_order_updated<\/code>, <code>bracket_po_term_order_updated<\/code><\/li>\n<li>Clean uninstall \u2014 removes options and term meta on plugin deletion<\/li>\n<li>Full internationalization support with <code>.pot<\/code> template<\/li>\n<\/ul>","raw_excerpt":"Drag-and-drop ordering for posts, pages, custom post types, and taxonomy terms \u2014 with per-category post ordering.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/mn.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/281668","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mn.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/mn.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/mn.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=281668"}],"author":[{"embeddable":true,"href":"https:\/\/mn.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/bracketdev"}],"wp:attachment":[{"href":"https:\/\/mn.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=281668"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/mn.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=281668"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/mn.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=281668"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/mn.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=281668"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/mn.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=281668"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/mn.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=281668"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}