0

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?

3

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; – Giraldi Aug 9 '14 at 7:02
  • Ah yes but you asked for last order number - not last + 1! – bonger Aug 9 '14 at 8:35
  • 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 the post_status, of course). That query should be the correct one. – Giraldi Aug 9 '14 at 10:15
  • Ok, updated answer per your comments. – bonger Aug 9 '14 at 10:41
2

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 menu_order is shared between the different types of posts, including nav menu items even. @bonger's query seems to be better targeted. Also, with your code, publishing the page seems to take ages and then leads to a blank page. – Giraldi Aug 9 '14 at 6:55
  • 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. – Giraldi Aug 9 '14 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 ) {} – Giraldi Aug 9 '14 at 8:23
  • Mind if update your answer with the fixes? – Giraldi Aug 11 '14 at 19:36
  • Answer updated. – karpstrucking Aug 13 '14 at 10:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.