Is there a way to automatically set page order to the last order number upon creating new pages instead of having it set to 0?
2 Answers
You could use ajax and the admin_footer-post-new.php
hook. The sql would vary depending on whether you want the highest or most recently published order number. The following returns the highest published order number + 1:
function wpse155926_set_menu_order() {
$ret = array();
if ( check_ajax_referer( 'wpse155926_set_menu_order_post', 'nonce', false /*die*/ ) ) {
global $wpdb;
//last published
//$sql = $wpdb->prepare( 'SELECT menu_order FROM ' . $wpdb->posts . ' WHERE post_type = %s AND post_status = %s ORDER BY post_date DESC LIMIT 1', 'page', 'publish' );
//highest published
$sql = $wpdb->prepare( 'SELECT menu_order FROM ' . $wpdb->posts . ' WHERE post_type = %s AND post_status = %s ORDER BY menu_order DESC LIMIT 1', 'page', 'publish' );
if ( ( $result = $wpdb->get_var( $sql ) ) !== false ) {
$ret['menu_order'] = $result + 1;
}
}
header('Content-type: application/json');
die( json_encode( $ret ) );
}
add_action( 'wp_ajax_wpse155926_set_menu_order', 'wpse155926_set_menu_order' );
function wpse155926_admin_footer_post_new_php() {
?>
<script type="text/javascript">
jQuery(document).ready(function() {
(function ($) {
$.post( ajaxurl, {
action: 'wpse155926_set_menu_order',
nonce: <?php echo json_encode( wp_create_nonce( 'wpse155926_set_menu_order_post' ) ); ?>
}, function(response) {
if (response && response.menu_order) {
$('#pageparentdiv input[name="menu_order"]').val(response.menu_order);
}
}, 'json'
);
})(jQuery);
});
</script>
<?php
}
add_action( 'admin_footer-post-new.php', 'wpse155926_admin_footer_post_new_php' );
-
This works really well. One addition, though, I think the
$result
should be offset by one so it would be a new unique number and in the last page order. Eg.$ret['menu_order'] = ++$result;
– GiraldiAug 9, 2014 at 7:02 -
-
Oh, and by the way, I think you should use the commented query instead, which uses
ORDER BY menu_order
, since I am looking for the highest value (with the addition of thepost_status
, of course). That query should be the correct one.– GiraldiAug 9, 2014 at 10:15 -
You could hook into the publish_page
transitional status action and use a simple SQL query (via $wpdb
) to determine the highest current value of menu_order
in the {prefix}_posts
table and set the menu_order
of the new page accordingly. Example code:
add_action( 'publish_page', 'wpse155926_set_to_last_page', 10, 2 );
function wpse155926_set_to_last_page( $ID, $post ) {
if ( $post->menu_order === 0 ) {
global $wpdb;
$query = "SELECT MAX(menu_order) FROM $wpdb->posts WHERE post_type LIKE 'page' AND post_status LIKE 'publish';";
$max_menu_order = $wpdb->get_var( $query );
$post->menu_order = ++$max_menu_order;
remove_action('publish_page', 'wpse155926_set_to_last_page');
wp_update_post( $post );
add_action('publish_page', 'wpse155926_set_to_last_page');
}
}
-
-
I think I found the solution to the blank page issue: infinite loop. In your case, anyway, the
publish_page
action should be removed and then re-added. With this fix, along with @bonger's query, the overall code is working in the right direction... Still testing, though.– GiraldiAug 9, 2014 at 7:33 -
Okay, your code with the above fixes seems to work. However, the process runs on every update of the page, thus moving any updated page to the last order. So I added a condition within the function to set the page order ONLY if it is not already set:
if ( $post->menu_order === 0 ) {}
– GiraldiAug 9, 2014 at 8:23 -
-