Introduction
What this plugin does
WDD Drag & Drop Post Order gives you a dedicated admin screen to drag posts into whatever order you want. Once you save, your site's front end will show posts in that exact order — no theme editing, no custom queries, no shortcodes.
It works by setting WordPress's built-in menu_order field on each post, then hooking into pre_get_posts to apply that order on the front end for any post type you've enabled.
Key features
- Drag-and-drop reordering using jQuery UI Sortable
- Works with Posts, Pages, and any registered Custom Post Type
- Optional date update — automatically adjusts post dates to match the visual order
- Three date-spacing options: per hour, per day, or per week
- Live search with debounce and pagination for large libraries
- One-click reset to restore default WordPress ordering
- No configuration needed on the front end — ordering applies automatically
The plugin only modifies the front-end query order for post types you explicitly enable in Settings. All other post types are left completely untouched.
Before You Start
Requirements
| Requirement | Minimum | Notes |
|---|---|---|
| WordPress | 5.6 | Tested up to 6.5 |
| PHP | 7.4 | PHP 8.0+ recommended |
| User role | manage_options |
Administrator access required |
| jQuery UI | Bundled with WP | Plugin enqueues jquery-ui-sortable automatically — nothing to install |
Setup
Installation
Upload via WordPress admin (recommended)
-
1
Go to Plugins → Add NewIn your WordPress dashboard navigate to Plugins → Add New Plugin.
-
2
Click "Upload Plugin"Hit the Upload Plugin button at the top, then choose the
wdd-drag-drop-post-order.zipfile. -
3
Install & ActivateClick Install Now, then Activate Plugin once it uploads.
-
4
Configure SettingsGo to Post Order → Settings to choose which post types to enable.
Manual installation (FTP)
-
1
Extract the zipUnzip
wdd-drag-drop-post-order.zipon your local machine. -
2
Upload via FTPUpload the
wdd-drag-drop-post-order/folder to/wp-content/plugins/on your server. -
3
Activate in WordPressGo to Plugins → Installed Plugins and click Activate.
After activation a new Post Order item appears in your WordPress sidebar with two sub-pages: Reorder and Settings.
Usage
The Reorder screen
This is your main working area — go to Post Order → Reorder to open it.
Post type tabs
If you've enabled more than one post type in Settings, you'll see a tab row at the top. Click a tab to switch between post types. Each has its own completely separate order.
Switching tabs does not auto-save. If you have unsaved changes the browser will warn you. Always hit Save Order first.
Dragging posts
Each post row has a drag handle on the left (the dotted grid icon). Grab it and drag the row up or down. A blue placeholder shows where the post will land. You can re-drag as many times as you like before saving.
Search
Use the search box in the top-right to filter posts by title. Results update automatically after a short delay and pagination resets to page 1 on each search.
Saving
Once you're happy with the order, click Save Order. The button stays disabled until you make at least one drag. After saving the order is immediately applied on the front end.
Reset
The Reset button clears the custom menu_order for all posts of the current type, setting them back to 0. WordPress then falls back to its default sort (usually date descending). A confirmation dialog appears before anything changes.
Feature
The date update feature
When you toggle Update dates on the Reorder screen and save, the plugin rewrites the post_date of every post in the list to reflect the new order. This is useful when your theme or RSS feed displays dates and you want chronology to match visual order.
How the dates are calculated
The plugin uses the current time as a base and works backwards down the list:
- First post in the list → gets right now as its date
- Second post → gets now minus 1 interval
- Third post → gets now minus 2 intervals
- …and so on
The interval (hour, day, or week) is set under Settings → Date spacing. With "1 Day" spacing and 5 posts you'd get today, yesterday, the day before, and so on.
The toggle is per-save, not permanently sticky. Its default state is controlled by the Settings option. Leave it off for pure visual reordering — only switch it on when you actually want dates changed.
Date changes are permanent and cannot be undone from within the plugin. If you need to revert, restore post dates manually or from a database backup.
Reference
Settings reference
All settings live at Post Order → Settings and are stored in the wdd_ddpo_settings WordPress option as a serialised array.
| Setting | Type | Default | Description |
|---|---|---|---|
post_types |
array | ['post'] |
Which post types appear in the Reorder screen and get front-end ordering applied. |
update_dates |
bool | false |
Default state of the "Update dates" toggle on the Reorder screen. |
date_spacing |
string | 'hour' |
Time gap between posts when date updating is on. Accepts 'hour', 'day', or 'week'. |
Reading settings programmatically
// Get all settings $settings = get_option( 'wdd_ddpo_settings', [] ); // Or use the Settings class directly $obj = WDD_DDPO_Settings::get_instance(); $post_types = $obj->get( 'post_types' ); $update_dates = $obj->get( 'update_dates' ); $spacing = $obj->get( 'date_spacing' );
Developer
File structure
One class per file, all loaded from the main plugin entry point. No autoloader — simple and dependency-free.
Class responsibilities
| Class | Responsibility |
|---|---|
WDD_DDPO_Settings |
Singleton. Registers the WordPress option, sanitises input, and provides a get() helper for reading settings anywhere in the codebase. |
WDD_DDPO_Admin |
Registers the admin menu and sub-pages, enqueues CSS/JS only on the plugin's own screens, and localises JS variables via wp_localize_script. |
WDD_DDPO_Ajax |
Handles three wp_ajax_* actions: wdd_ddpo_save_order, wdd_ddpo_get_posts, and wdd_ddpo_reset_order. All require a valid nonce and manage_options capability. |
WDD_DDPO_Query |
Hooks into pre_get_posts on the front end only, applying menu_order sorting for enabled post types on main queries. |
Developer
Hooks & Filters
Use these hooks to customise the plugin's behaviour without editing its files. Add all custom code to your theme's functions.php or a site-specific plugin.
add_filter( 'wdd_ddpo_enabled_post_types', function( $post_types ) { $post_types[] = 'portfolio'; return $post_types; } );
add_filter( 'wdd_ddpo_posts_per_page', function( $per_page ) { return 100; } );
add_action( 'wdd_ddpo_after_save_order', function( $post_ids, $post_type ) { // Example: clear a custom cache after reordering my_plugin_clear_cache( $post_type ); }, 10, 2 );
add_filter( 'wdd_ddpo_query_args', function( $args, $post_type ) { if ( $post_type === 'product' ) { $args['post_status'] = 'publish'; } return $args; }, 10, 2 );
Never edit plugin files directly — your changes will be overwritten on update. Always use hooks in an external file.
Reference
Frequently asked questions
pre_get_posts to sort those posts by menu_order on all main queries for that post type. Standard themes using WP_Query or get_posts() pick it up automatically.WP_Query with a hardcoded orderby those queries won't be affected — only the site's main query is modified.menu_order value changes.menu_order values written to your posts stay in the database after deactivation — WordPress just won't apply them to queries without the plugin's hook. Reactivating restores full functionality immediately. Settings also persist unless you fully delete the plugin.product) will appear in Settings. The plugin sets menu_order correctly, but whether your shop pages respect it depends on WooCommerce's own sort setting. Go to WooCommerce → Settings → Products → Default product sorting and set it to Custom ordering.History
Changelog
pre_get_posts