Snippets

willy bahuaud Améliorer la fonctionnalité des « contenus à la une » de WordPress / Improve WordPress “Sticky Posts” feature

Created by willy bahuaud last modified
<?php

// Does the current user can define sticky posts for this custom post type?
function need_sticky( $post ) {
    $post_type = $post->post_type;
    $post_type_object = get_post_type_object( $post_type );
    $can_publish = current_user_can( $post_type_object->cap->publish_posts );
    return $can_publish 
      // Choose your post types
      && in_array( $post->post_type, array( 'page', 'event' ) );
}

// Start deferring php output
add_action( 'post_submitbox_minor_actions', 'w_post_submitbox_minor_actions' );
function w_post_submitbox_minor_actions( $post ) {
    if ( need_sticky( $post ) ) {
        ob_start();
    }
}

// Get PHP output and print sticky posts metabox
add_action( 'post_submitbox_misc_actions', 'w_post_submitbox_misc_actions' );
function w_post_submitbox_misc_actions( $post ) {
    if ( need_sticky( $post ) ) {
        $temp = ob_get_clean();

        // WP core need two different checkbox: on for authors, and another one for editors
        $sticky_box = '<input type="checkbox" style="display:none" 
            name="hidden_post_sticky" id="hidden-post-sticky" value="sticky" '
            . checked( is_sticky( $post->ID ), true, false ) . ' />';

        if ( current_user_can( 'edit_others_posts' ) ) {
            $sticky_box .= sprintf( '<span id="sticky-span"><input id="super-sticky" 
                name="sticky" type="checkbox" value="sticky" %1$s />
                <label for="super-sticky" class="selectit">%2$s</label><br/></span>',
                checked( is_sticky( $post->ID ), true, false ),
                __( 'Stick this post to the front page' ) );
        }

        $re = '/(<input.*id="visibility-radio-password")/U';
        $output = preg_replace( $re, "{$sticky_box}$1", $temp );
        echo $output;
    }
}
<?php

// Add a custom query var to force post count
add_filter( 'query_vars', 'sticky_offset_query_var' );
function sticky_offset_query_var( $vars ) {
    $vars[] = 'ppp_include_sticky';
    return $vars;
}

// Add the query var on home page query
add_filter( 'pre_get_posts', 'w_sticky_posts' );
function w_sticky_posts($q) {
    if ( is_home() ) {
        $q->set('ppp_include_sticky',true);
    }
    return $q;
}

// Truncate posts array to adjust post count
add_filter( 'the_posts', 'sticky_count_offset', 10, 2 );
function sticky_count_offset( $posts, $q ) {
    if ( $q->get( 'ppp_include_sticky' )
      && 0 < $q->get( 'posts_per_page' )
      && false == $q->get( 'ignore_sticky_posts' ) ) {
        $posts = array_slice( $posts, 0, $q->get( 'posts_per_page' ) );
    }
    return $posts;
}

// Are we on a paged home with sticky posts ?
function is_paged_home_with_sticky( $q ) {
    return $q->is_home()
      && $q->get( 'ppp_include_sticky' )
      && $q->is_paged()
      && false == $q->get( 'ignore_sticky_posts' );
}

// Define page offset to show posts truncated on previous page
add_filter( 'pre_get_posts', 'sticky_count_on_paged', 20 );
function sticky_count_on_paged( $q ) {
    if ( is_paged_home_with_sticky( $q ) ) {
        $q->set('post__not_in', get_option( 'sticky_posts', array() ) );
        
        $offset = count( get_option( 'sticky_posts', array() ) );
        $page_offset = $q->get( 'posts_per_page', get_option( 'posts_per_page' ) ) 
          * ( $q->get( 'paged' ) -1 ) - $offset;
        $q->set( 'offset', $page_offset );
    }
    return $q;
}

// Adjust found_posts property to display the right number of pages
add_filter( 'found_posts', 'sticky_adjust_offset_pagination', 1, 2 );
function sticky_adjust_offset_pagination( $found_posts, $q ) {
    if ( is_paged_home_with_sticky( $q ) ) {
        $offset = count( get_option( 'sticky_posts', array() ) );
        return $found_posts + $offset;
    }
    return $found_posts;
}
<?php

/**
 * If ACF field `sticky_posts` is on an option page
 */
add_filter( 'pre_option_options_sticky_posts', 'w_get_sticky' );
function w_get_sticky() {
    return get_option( 'sticky_posts' );
}

add_action( 'update_option', 'w_update_sticky', 10, 3 );
function w_update_sticky( $option, $old_value, $value ) {
    if ( 'options_sticky_posts' === $option ) {
        update_option( 'sticky_posts', $value );
    }
}

/**
 * If ACF field `sticky_posts` is a page_for_posts metabox
 */
add_filter( 'get_post_metadata', 'w_get_sticky_post_meta', 10, 3 );
function w_get_sticky_post_meta( $check, $object_id, $meta_key ) {
    if ( get_option( 'page_for_posts' ) == $object_id
      && 'sticky_posts' === $meta_key ) {
        return array( get_option( 'sticky_posts' ) );
    }
    return $check;
}

add_action( 'updated_post_meta', 'w_update_sticky_post_meta', 10, 4 );
function w_update_sticky_post_meta( $meta_id, $object_id, $meta_key, $_meta_value ) {
    if ( get_option( 'page_for_posts' ) == $object_id
      && 'sticky_posts' === $meta_key ) {
        update_option( 'sticky_posts', $_meta_value );
    }
}

Comments (0)