WordPress小工具多选问题

时间:2019-09-25 作者:CarnageV

我正在构建Wordpress小部件,遇到了一个无法找到解决方案的问题。这个小部件很简单:它按类别显示我的CPT中最后10篇文章。

对我来说,最棘手的一点是让它能够处理选定的多个类别(处理单个类别)>

每次我选择两个类别时,“选择”字段将恢复为默认选择或最后选择的单个类别。

以下是我的小部件代码:

public function widget( $args, $instance ) 
    {
        $cache = [];
        if ( ! $this->is_preview() ) {
            $cache = wp_cache_get( \'widget_cat_posts\', \'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\'] : __( \'Category Posts\' );

        $title          = apply_filters( \'widget_title\', $title, $instance, $this->id_base );
        $number         = ( ! empty( $instance[\'number\'] ) ) ? absint( $instance[\'number\'] ) : 5;
        if ( ! $number ) {
            $number = 5;
        }
        $cat_id         = $instance[\'cat_id\'];



        if( true === $random ) {

            $query_args = [
                \'posts_per_page\'    => 10,
                \'cat\'               => $cat_id,
                \'post_type\'         => \'mycmpt\',
                \'orderby\'           => \'rand\'
            ];

        }else{  

            $query_args = [
                \'posts_per_page\'    => 10,
                \'cat\'               => $cat_id,
                \'post_type\'         => \'mycmpt\',
            ];

        }
        $q = new WP_Query( apply_filters( \'category_posts_args\', $query_args ) );

        if( $q->have_posts() ) {

            echo $args[\'before_widget\'];
            if ( $title ) {
                echo $args[\'before_title\'] . $title . $args[\'after_title\'];
            }               

            while( $q->have_posts() ) {
                $q->the_post(); ?>

                <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>> 

                    <header class="entry-header">
                        <?php the_title( \'<h1 class="entry-title"><a href="\' . esc_url( get_permalink() ) . \'" rel="bookmark">\', \'</a></h1>\' ); ?>
                    </header><!-- .entry-header -->




                            <?php the_post_thumbnail(); ?>





                            <?php the_excerpt(); ?>



                    <?php } ?>

                </article><!-- #post-## -->

                <?php 



            wp_reset_postdata();
        }
            echo $args[\'after_widget\']; 

        if ( ! $this->is_preview() ) {
            $cache[ $args[\'widget_id\'] ] = ob_get_flush();
            wp_cache_set( \'widget_cat_posts\', $cache, \'widget\' );
        } else {
            ob_end_flush();
        }
    } 
这是我的更新代码:

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

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

        return $instance;
    } 
这是我的表单代码:

public function form( $instance ) 
{

    $title      = isset( $instance[\'title\'] ) ? esc_attr( $instance[\'title\'] ) : \'\';
    $number     = isset( $instance[\'number\'] ) ? absint( $instance[\'number\'] ) : 5;
    $cat_id     = isset( $instance[\'cat_id\'] ) ? absint( $instance[\'cat_id\'] ) : 1;

    ?>

    <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>



    <p>
        <label for="<?php echo $this->get_field_id(\'cat_id\'); ?>"><?php _e( \'Category Name:\' )?></label>

        <select multiple="multiple" id="<?php echo $this->get_field_id(\'cat_id\'); ?>" name="<?php echo $this->get_field_name(\'cat_id\'); ?>">
            <?php 
            $this->categories = get_categories();
            foreach ( $this->categories as $cat ) {
                $selected = ( $cat->term_id == esc_attr( $cat_id ) ) ? \' selected = "selected" \' : \'\';
                $option = \'<option \'.$selected .\'value="\' . $cat->term_id;
                $option = $option .\'">\';
                $option = $option .$cat->name;
                $option = $option .\'</option>\';
                echo $option;
            }
            ?>
        </select>
    </p>



<?php
}
我尝试在数组中设置$selected=in\\u,但没有成功。

我已经让它与single select一起工作,但我现在不知道为什么它不能与multiselect一起工作。

1 个回复
最合适的回答,由SO网友:CarnageV 整理而成

如果有人在看这个问题,我设法找到了一个解决方案。1、切换到复选框而不是多选,并使用“选中”而不是“选中”;2、使用了tax\\u查询和其他一些查询修改。

该代码并不完美,但目前仍有效。

用于显示CPT中按单个或多个类别排序的最后10个条目的工作小部件代码:

class CPT_Widget extends WP_Widget 
{

    public function __construct() 
    {
        parent::__construct(
            \'widget_category_posts\', 
            _x( \'CPT Widget\', \'CPT Widget\' ), 
            [ \'description\' => __( \'Display the latest entries in your custom post type sorted by single or multiple categories.\' ) ] 
        );
        $this->alt_option_name = \'widget_category_posts\';

        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_cat_posts\', \'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\'] : __( \'Category Posts\' );
        $title          = apply_filters( \'widget_title\', $title, $instance, $this->id_base );
        $number         = ( ! empty( $instance[\'number\'] ) ) ? absint( $instance[\'number\'] ) : 5;
        if ( ! $number ) {
            $number = 5;
        }
        $cat_id         = $instance[\'categories\'];
        if( true === $random ) {
            $query_args = [
                \'posts_per_page\'    => 10,
                \'post_type\'         => \'yourcustomposttype\',
                \'orderby\'           => \'rand\',
                \'tax_query\' => array(
                            array(
                            \'taxonomy\' => \'category\',
                            \'field\' => \'term_id\',
                            \'terms\' => $cat_id,
                             ),
                          ),
            ];
        }else{  
            $query_args = [
                \'posts_per_page\'    => 10,
                \'post_type\'         => \'yourcustomposttype\',
                \'orderby\'           => \'rand\',
                \'tax_query\' => array(
                            array(
                            \'taxonomy\' => \'category\',
                            \'field\' => \'term_id\',
                            \'terms\' => $cat_id,
                             ),
                          ),
            ];

        }
        $q = new WP_Query( $query_args );

        if( $q->have_posts() ) {
            echo $args[\'before_widget\'];
            if ( $title ) {
                echo $args[\'before_title\'] . $title . $args[\'after_title\'];
            }               
            while( $q->have_posts() ) {
                $q->the_post(); ?>

                <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>> 

                    <header class="entry-header">
                        <?php the_title( \'<h1 class="entry-title"><a href="\' . esc_url( get_permalink() ) . \'" rel="bookmark">\', \'</a></h1>\' ); ?>
                    </header><!-- .entry-header -->
                        <div class="post-thumbnail">
                            <?php the_post_thumbnail(); ?>
                        </div><!--/.post-thumbnail-->
                        <div class="entry-summary">
                            <?php the_excerpt(); ?>
                        </div><!-- .entry-summary -->
                    <?php } ?>
                </article><!-- #post-## -->
                <?php 
            wp_reset_postdata();
        }
            echo $args[\'after_widget\']; 

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


public function update($a, $b) {
  return array(
    \'title\'      => isset($a[\'title\']) ? strip_tags($a[\'title\']) : $b[\'title\'],
    \'categories\' => isset($a[\'categories\']) ? array_filter(array_map(function($id) { return intval($id); }, (array) $a[\'categories\'])) : (array) $b[\'title\']
  );
}

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

    public function form($instance) {
  $title = isset($instance[\'title\']) ? $instance[\'title\'] : \'\';
  $categories = isset($instance[\'categories\']) ? $instance[\'categories\'] : array();
  ?>

  <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\') ?>"
           value="<?php echo $title ?>" />
  </p>

  <p>Categories</p>
  <ul>
  <?php foreach (\\get_categories() as $category): ?>
    <li>
      <label>
        <input type="checkbox"
             class="checkbox"
             name="<?php echo $this->get_field_name(\'categories\') ?>[]"
             value="<?php echo $category->cat_ID ?>"
             <?php checked(in_array($category->cat_ID, $categories)) ?> />
        <?php echo $category->name ?>
      </label>
    </li>
  <?php endforeach ?>
  </ul>
  <?php
}
}


add_action( \'widgets_init\', function () 
{
    register_widget( \'CPT_Widget\' );
}); 

相关推荐

My widgets do not save

每次我保存我的小部件并离开页面时,我的小部件都会消失。侧边栏已完全清空,不会保存任何更改。控制台或PHP日志中没有任何错误。如果我将小部件直接复制并保存在数据库中widgets_text, 它们将被显示,但我仍然无法在侧边栏中添加或删除任何内容。这只发生在我的右侧边栏上,左侧边栏工作正常,但它们都以相同的方式注册。这是我注册侧边栏的方式:function my_widgets_init() { register_sidebar( array ( \'name\'