web-dev-qa-db-de.com

Zeige alle Beiträge mit dem gleichen Titel

Ich versuche, in einem Sidebar-PHP-Widget alle Posts mit demselben post_title in einer bestimmten Kategorie anzuzeigen. Ich finde diesen Code im Internet, kann ihn aber nicht verwenden. Vielen Dank für Ihre Hilfe.

function get_multiple_posts_by_title($title) {
    global $wpdb;
    $posts_ids = array();

    $posts = $wpdb->get_results( $wpdb->prepare( “SELECT ID FROM $wpdb->posts WHERE post_title = %s AND     post_type=’post_type’”, $title), OBJECT );
    foreach ($posts as $post) {
         $posts_ids[] = $post->ID;
    }

    return $posts_ids;
}

Bearbeiten: Hier ist der aktuelle Code, den ich verwende.

<?php
/*
Plugin Name: WPSE Get Duplicate Post Titles
Plugin URI:  http://wordpress.stackexchange.com/q/220279/31545
Description: Displays posts with the same title in the sidear
Version:     1.0.0
Author:      Pieter Goosen
Author URI:  http://wordpress.stackexchange.com/users/31545/pieter-goosen
License:     GPL2
License URI: https://www.gnu.org/licenses/gpl-2.0.html
*/

add_filter( 'posts_where', function ( $where, $q ) use ( &$wpdb )
{
    // Get the value from our new wpse_title_match query var
    $title_match = $q->get( 'wpse_title_match' );

    // Make sure we have a value, if not, bail
    if ( !$title_match )
        return $where;

    /**
     * Lets alter the SQL WHERE clause
     *
     * Note, this will be an exact 1 to 1 match, adjust as necessary
     */
    $where .= $wpdb->prepare(
        " AND {$wpdb->posts}.post_title = %s ",
        $title_match
    );

    return $where;
}, 10, 2 );

class WPSE_Get_Duplicate_Post_titles extends WP_Widget 
{

    public function __construct() 
    {
        parent::__construct(
            'widget_get_duplicate_post_titles', 
            _x( 'Post Title duplicates', 'Post Title duplicates' ), 
            [ 'description' => __( 'Displays posts which share the same post title.' ) ] 
        );
        $this->alt_option_name = 'widget_get_duplicate_post_titles';

        add_action( 'save_post',    [$this, 'flush_widget_cache'] );
        add_action( 'deleted_post', [$this, 'flush_widget_cache'] );
        add_action( 'switch_theme', [$this, 'flush_widget_cache'] );
    }

    public function widget( $args, $instance ) 
    {
        $cache = [];
        if ( ! $this->is_preview() ) {
            $cache = wp_cache_get( 'widget_bpfi', 'widget' );
        }

        if ( ! is_array( $cache ) ) {
            $cache = [];
        }

        if ( ! isset( $args['widget_id'] ) ) {
            $args['widget_id'] = $this->id;
        }

        if ( isset( $cache[ $args['widget_id'] ] ) ) {
            echo $cache[ $args['widget_id'] ];
            return;
        }

        ob_start();

        $title          = ( ! empty( $instance['title'] ) ) ? $instance['title'] : __( 'Post Title Duplicates' );
        /** This filter is documented in wp-includes/default-widgets.php */
        $title          = apply_filters( 'widget_title', $title, $instance, $this->id_base );

        // ADD YOUR CUSTOM PHP CODE HERE FOR EXECUTION TO DISPLAY ON FRONT END
        // First make sure this a single post page
        if ( is_single() ) { // We are on a single page
            // Get the current post object
            $post_object = $GLOBALS['wp_the_query']->get_queried_object();

            // Run our query to get the posts with duplicate titles
            $args = [
                'posts_per_page'   => -1, // Get all posts
                'post_type'        => 'post',
                'wpse_title_match' => $post_object->post_title,
                'post__not_in'     => [$post_object->ID], // Exclude current post
                'tax_query'        => [
                    [
                        'taxonomy' => 'category',
                        'terms'    => 'chroniques'
                    ]
                ],
                // Any other arguments
            ];
            $loop = new WP_Query( $args );

            // Run the loop
            if ( $loop->have_posts() ) {
                while ( $loop->have_posts ) {
                    $loop->the_post();

                    // Display your posts
                    the_title() . "\n";

                }
                wp_reset_postdata();
            }
        }

        echo $args['after_widget']; 

        if ( ! $this->is_preview() ) {
            $cache[ $args['widget_id'] ] = ob_get_flush();
            wp_cache_set( 'widget_bpfi', $cache, 'widget' );
        } else {
            ob_end_flush();
        }
    }

    public function update( $new_instance, $old_instance ) 
    {
        $instance                   = $old_instance;
        $instance['title']          = strip_tags( $new_instance['title'] );
        $this->flush_widget_cache();

        $alloptions = wp_cache_get( 'alloptions', 'options' );
        if ( isset($alloptions['widget_get_duplicate_post_titles']) )
            delete_option('widget_get_duplicate_post_titles');

        return $instance;
    }

    public function flush_widget_cache() 
    {
        wp_cache_delete('widget_bpfi', 'widget');
    }

    public function form( $instance ) 
    {

        $title      = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
        ?>

        <p>
            <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo $title; ?>" />
        </p>

    <?php
    }

}

add_action( 'widgets_init', function () 
{
    register_widget( 'WPSE_Get_Duplicate_Post_titles' );
});

add_filter( 'sidebars_widgets', function ( $sidebars_widgets )
{
    // Return our filter when we are on admin screen
    if ( is_admin() )
        return $sidebars_widgets;

    // Make sure we are not on the blog page, if we are, bail
    if ( is_single() )
        return $sidebars_widgets;

    /**
     * Widget we need to target. This should be the name/id we used to register it
     *
     * EXAMPLE
     *   parent::__construct(
            'widget_get_duplicate_post_titles', 
            _x( 'Blog Page Featured Image', 'Blog page featured image' ), 
            [ 'description' => __( 'Displays the featured image for the pge set as blog page.' ) ] 
        );
     *
     */
    $custom_widget  = 'widget_get_duplicate_post_titles';

    // See if our custom widget exists is any sidebar, if so, get the array index
    foreach ( $sidebars_widgets as $sidebars_key=>$sidebars_widget ) {
        // Skip the wp_inactive_widgets set, we do not need them
        if ( $sidebars_key == 'wp_inactive_widgets' )
        continue;

        // Only continue our operation if $sidebars_widget are not an empty array
        if ( $sidebars_widget ) {
            foreach ( $sidebars_widget as $k=>$v ) {

                /**
                 * Look for our custom widget, if found, unset it from the $sidebars_widgets array
                 * @see stripos()
                 */
                if ( stripos( $v, $custom_widget ) !== false ) 
                    unset( $sidebars_widgets[$sidebars_key][$k] );
            } // endforeach $sidebars_widget
        } // endif $sidebars_widget
    } // endforeach $sidebars_widgets

    return $sidebars_widgets;
});
3
Guenfood

Nutzen wir die eingebauten Funktionen, die WordPress bietet. Es wird fast immer davon abgeraten, benutzerdefiniertes SQL zu verwenden, wenn WordPress native Funktionen zur Ausführung der jeweiligen Aufgabe bietet.

Um unsere Beiträge abzufragen, verwenden wir WP_Query. Das einzige Problem ist, dass WP_Query die Funktion nicht unterstützt, bei der nach Posts mit bestimmten Posttiteln gesucht wird. Glücklicherweise können wir die Build-SQL-Abfrage filtern, bevor sie die Datenbank abfragt. Dazu verwenden wir den Filter posts_where, um unseren eigenen benutzerdefinierten Parameter wpse_title_match einzuführen ( und nein, das hat nichts mit Wrestling zu tun ).

Wir müssen Folgendes in ein Plugin ( Recommended ) oder in Ihre Themes-Funktionsdatei einfügen

add_filter( 'posts_where', function ( $where, $q ) use ( &$wpdb )
{
    // Get the value from our new wpse_title_match query var
    $title_match = $q->get( 'wpse_title_match' );

    // Make sure we have a value, if not, bail
    if ( !$title_match )
        return $where;

    /**
     * Lets alter the SQL WHERE clause
     *
     * Note, this will be an exact 1 to 1 match, adjust as necessary
     */
    $where .= $wpdb->prepare(
        " AND {$wpdb->posts}.post_title = %s ",
        $title_match 
    );

    return $where;
}, 10, 2 );

An dieser Stelle ist es besser, sich ein richtiges Widget zu erstellen, als alles in ein PHP-Widget zu schreiben

Hier ist ein modifiziertes Widget-Plugin, das ich kürzlich erstellt habe hier

class WPSE_Get_Duplicate_Post_titles extends WP_Widget 
{

    public function __construct() 
    {
        parent::__construct(
            'widget_get_duplicate_post_titles', 
            _x( 'Post Title duplicates', 'Post Title duplicates' ), 
            [ 'description' => __( 'Displays posts which share the same post title.' ) ] 
        );
        $this->alt_option_name = 'widget_get_duplicate_post_titles';

        add_action( 'save_post',    [$this, 'flush_widget_cache'] );
        add_action( 'deleted_post', [$this, 'flush_widget_cache'] );
        add_action( 'switch_theme', [$this, 'flush_widget_cache'] );
    }

    public function widget( $args, $instance ) 
    {
        $cache = [];
        if ( ! $this->is_preview() ) {
            $cache = wp_cache_get( 'widget_bpfi', 'widget' );
        }

        if ( ! is_array( $cache ) ) {
            $cache = [];
        }

        if ( ! isset( $args['widget_id'] ) ) {
            $args['widget_id'] = $this->id;
        }

        if ( isset( $cache[ $args['widget_id'] ] ) ) {
            echo $cache[ $args['widget_id'] ];
            return;
        }

        ob_start();

        $title          = ( ! empty( $instance['title'] ) ) ? $instance['title'] : __( 'Post Title Duplicates' );
        /** This filter is documented in wp-includes/default-widgets.php */
        $title          = apply_filters( 'widget_title', $title, $instance, $this->id_base );

        // ADD YOUR CUSTOM PHP CODE HERE FOR EXECUTION TO DISPLAY ON FRONT END
        // First make sure this a single post page
        if ( is_single() ) { // We are on a single page
            // Get the current post object
            $post_object = $GLOBALS['wp_the_query']->get_queried_object();

            // Run our query to get the posts with duplicate titles
            $args = [
                'posts_per_page'   => -1, // Get all posts
                'post_type'        => 'post',
                'wpse_title_match' => $post_object->post_title,
                'post__not_in'     => [$post_object->ID], // Exclude current post
                'tax_query'        => [
                    [
                        'taxonomy' => 'category',
                        'field'    => 'slug',
                        'terms'    => 'chroniques'
                    ]
                ],
                // Any other arguments
            ];
            $loop = new WP_Query( $args );

            // Run the loop
            if ( $loop->have_posts() ) {
                while ( $loop->have_posts() ) {
                    $loop->the_post();

                    // Display your posts
                    the_title() . "\n";

                }
                wp_reset_postdata();
            }
        }

        echo $args['after_widget']; 

        if ( ! $this->is_preview() ) {
            $cache[ $args['widget_id'] ] = ob_get_flush();
            wp_cache_set( 'widget_bpfi', $cache, 'widget' );
        } else {
            ob_end_flush();
        }
    }

    public function update( $new_instance, $old_instance ) 
    {
        $instance                   = $old_instance;
        $instance['title']          = strip_tags( $new_instance['title'] );
        $this->flush_widget_cache();

        $alloptions = wp_cache_get( 'alloptions', 'options' );
        if ( isset($alloptions['widget_get_duplicate_post_titles']) )
            delete_option('widget_get_duplicate_post_titles');

        return $instance;
    }

    public function flush_widget_cache() 
    {
        wp_cache_delete('widget_bpfi', 'widget');
    }

    public function form( $instance ) 
    {

        $title      = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
        ?>

        <p>
            <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo $title; ?>" />
        </p>

    <?php
    }

}

add_action( 'widgets_init', function () 
{
    register_widget( 'WPSE_Get_Duplicate_Post_titles' );
});

Was ich auch gerne mache, ist, ein Widget immer vollständig zu entfernen, wenn es völlig unzusammenhängend ist, um zu vermeiden, dass die Seitenleiste ein Leerzeichen anzeigt, wenn keine anderen Widgets angezeigt werden

Wir können den gleichen Ansatz versuchen, den ich beschrieben habe hier . Sie können dies einfach am unteren Rand des Plugins hinzufügen

add_filter( 'sidebars_widgets', function ( $sidebars_widgets )
{
    // Return our filter when we are on admin screen
    if ( is_admin() )
        return $sidebars_widgets;

    // Make sure we are not on the blog page, if we are, bail
    if ( is_single() )
        return $sidebars_widgets;

    /**
     * Widget we need to target. This should be the name/id we used to register it
     *
     * EXAMPLE
     *   parent::__construct(
            'widget_get_duplicate_post_titles', 
            _x( 'Blog Page Featured Image', 'Blog page featured image' ), 
            [ 'description' => __( 'Displays the featured image for the page set as blog page.' ) ] 
        );
     *
     */
    $custom_widget  = 'widget_get_duplicate_post_titles';

    // See if our custom widget exists is any sidebar, if so, get the array index
    foreach ( $sidebars_widgets as $sidebars_key=>$sidebars_widget ) {
        // Skip the wp_inactive_widgets set, we do not need them
        if ( $sidebars_key == 'wp_inactive_widgets' )
        continue;

        // Only continue our operation if $sidebars_widget are not an empty array
        if ( $sidebars_widget ) {
            foreach ( $sidebars_widget as $k=>$v ) {

                /**
                 * Look for our custom widget, if found, unset it from the $sidebars_widgets array
                 * @see stripos()
                 */
                if ( stripos( $v, $custom_widget ) !== false ) 
                    unset( $sidebars_widgets[$sidebars_key][$k] );
            } // endforeach $sidebars_widget
        } // endif $sidebars_widget
    } // endforeach $sidebars_widgets

    return $sidebars_widgets;
});

EINIGE ANMERKUNGEN

  • Alle obigen Codes ist ungetestet und erfordert PHP 5.4+

  • Sie sollten die WP_Query-Argumente im Widget an Ihre Bedürfnisse anpassen. Überall, wo ich Werte in Großbuchstaben hinzugefügt habe, sollten Sie entsprechende Werte eingeben

  • Beide Filterfunktionen können im selben Plugin hinzugefügt werden, sodass das gesamte Plugin so aussieht

ENDGÜLTIGER CODE

<?php
/*
Plugin Name: WPSE Get Duplicate Post Titles
Plugin URI:  https://wordpress.stackexchange.com/q/220279/31545
Description: Displays posts with the same title in the sidear
Version:     1.0.0
Author:      Pieter Goosen
Author URI:  https://wordpress.stackexchange.com/users/31545/pieter-goosen
License:     GPL2
License URI: https://www.gnu.org/licenses/gpl-2.0.html
*/

add_filter( 'posts_where', function ( $where, $q ) use ( &$wpdb )
{
    // Get the value from our new wpse_title_match query var
    $title_match = $q->get( 'wpse_title_match' );

    // Make sure we have a value, if not, bail
    if ( !$title_match )
        return $where;

    /**
     * Lets alter the SQL WHERE clause
     *
     * Note, this will be an exact 1 to 1 match, adjust as necessary
     */
    $where .= $wpdb->prepare(
        " AND {$wpdb->posts}.post_title = %s ",
        $title_match
    );

    return $where;
}, 10, 2 );

class WPSE_Get_Duplicate_Post_titles extends WP_Widget 
{

    public function __construct() 
    {
        parent::__construct(
            'widget_get_duplicate_post_titles', 
            _x( 'Post Title duplicates', 'Post Title duplicates' ), 
            [ 'description' => __( 'Displays posts which share the same post title.' ) ] 
        );
        $this->alt_option_name = 'widget_get_duplicate_post_titles';

        add_action( 'save_post',    [$this, 'flush_widget_cache'] );
        add_action( 'deleted_post', [$this, 'flush_widget_cache'] );
        add_action( 'switch_theme', [$this, 'flush_widget_cache'] );
    }

    public function widget( $args, $instance ) 
    {
        $cache = [];
        if ( ! $this->is_preview() ) {
            $cache = wp_cache_get( 'widget_bpfi', 'widget' );
        }

        if ( ! is_array( $cache ) ) {
            $cache = [];
        }

        if ( ! isset( $args['widget_id'] ) ) {
            $args['widget_id'] = $this->id;
        }

        if ( isset( $cache[ $args['widget_id'] ] ) ) {
            echo $cache[ $args['widget_id'] ];
            return;
        }

        ob_start();

        $title          = ( ! empty( $instance['title'] ) ) ? $instance['title'] : __( 'Post Title Duplicates' );
        /** This filter is documented in wp-includes/default-widgets.php */
        $title          = apply_filters( 'widget_title', $title, $instance, $this->id_base );

        // ADD YOUR CUSTOM PHP CODE HERE FOR EXECUTION TO DISPLAY ON FRONT END
        // First make sure this a single post page
        if ( is_single() ) { // We are on a single page
            // Get the current post object
            $post_object = $GLOBALS['wp_the_query']->get_queried_object();

            // Run our query to get the posts with duplicate titles
            $args = [
                'posts_per_page'   => -1, // Get all posts
                'post_type'        => 'post',
                'wpse_title_match' => $post_object->post_title,
                'post__not_in'     => [$post_object->ID], // Exclude current post
                'tax_query'        => [
                    [
                        'taxonomy' => 'category',
                        'field'    => 'slug',
                        'terms'    => 'chroniques'
                    ]
                ],
                // Any other arguments
            ];
            $loop = new WP_Query( $args );

            // Run the loop
            if ( $loop->have_posts() ) {
                while ( $loop->have_posts() ) {
                    $loop->the_post();

                    // Display your posts
                    the_title() . "\n";

                }
                wp_reset_postdata();
            }
        }

        echo $args['after_widget']; 

        if ( ! $this->is_preview() ) {
            $cache[ $args['widget_id'] ] = ob_get_flush();
            wp_cache_set( 'widget_bpfi', $cache, 'widget' );
        } else {
            ob_end_flush();
        }
    }

    public function update( $new_instance, $old_instance ) 
    {
        $instance                   = $old_instance;
        $instance['title']          = strip_tags( $new_instance['title'] );
        $this->flush_widget_cache();

        $alloptions = wp_cache_get( 'alloptions', 'options' );
        if ( isset($alloptions['widget_get_duplicate_post_titles']) )
            delete_option('widget_get_duplicate_post_titles');

        return $instance;
    }

    public function flush_widget_cache() 
    {
        wp_cache_delete('widget_bpfi', 'widget');
    }

    public function form( $instance ) 
    {

        $title      = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
        ?>

        <p>
            <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo $title; ?>" />
        </p>

    <?php
    }

}

add_action( 'widgets_init', function () 
{
    register_widget( 'WPSE_Get_Duplicate_Post_titles' );
});

add_filter( 'sidebars_widgets', function ( $sidebars_widgets )
{
    // Return our filter when we are on admin screen
    if ( is_admin() )
        return $sidebars_widgets;

    // Make sure we are not on the blog page, if we are, bail
    if ( is_single() )
        return $sidebars_widgets;

    /**
     * Widget we need to target. This should be the name/id we used to register it
     *
     * EXAMPLE
     *   parent::__construct(
            'widget_get_duplicate_post_titles', 
            _x( 'Blog Page Featured Image', 'Blog page featured image' ), 
            [ 'description' => __( 'Displays the featured image for the pge set as blog page.' ) ] 
        );
     *
     */
    $custom_widget  = 'widget_get_duplicate_post_titles';

    // See if our custom widget exists is any sidebar, if so, get the array index
    foreach ( $sidebars_widgets as $sidebars_key=>$sidebars_widget ) {
        // Skip the wp_inactive_widgets set, we do not need them
        if ( $sidebars_key == 'wp_inactive_widgets' )
        continue;

        // Only continue our operation if $sidebars_widget are not an empty array
        if ( $sidebars_widget ) {
            foreach ( $sidebars_widget as $k=>$v ) {

                /**
                 * Look for our custom widget, if found, unset it from the $sidebars_widgets array
                 * @see stripos()
                 */
                if ( stripos( $v, $custom_widget ) !== false ) 
                    unset( $sidebars_widgets[$sidebars_key][$k] );
            } // endforeach $sidebars_widget
        } // endif $sidebars_widget
    } // endforeach $sidebars_widgets

    return $sidebars_widgets;
});

BEARBEITEN

Sie können den Code innerhalb der Schleife erweitern, indem Sie sich den Quellcode der content.php-Vorlagenteile in einem der gebündelten Themen ansehen.

3
Pieter Goosen