web-dev-qa-db-ja.com

Wordpressウィジェットの新しいインスタンスがコンテンツの複製を作成する

私が書いたカスタムメイドのウィジェットがあり、同じウィジェットの2つのインスタンスを同じウィジェット領域に表示したいと思います。管理パネル内のウィジェット領域に新しいウィジェットインスタンスをドラッグアンドドロップしてカスタムフィールド内に新しいデータを配置して保存すると、ホームページに戻っても同じ内容の新しいウィジェットと古いウィジェットの両方が表示されます。私はそれがupdate関数の問題かもしれないと思いますが、私はそれが同じように見えるようにwordpressのドキュメントに従ってそれを書いた。これがコードです:

functions.php

/**
 * Register new custom wiget
*/

class Sole_Source_Main_Widget extends WP_Widget {
    public function __construct() {
        $widget_options = array(
            'classname' => 'sole_source_main_widget',
            'description' => 'Main content widget'
        );
        parent::__construct('sole_source_main_widget', 'Sole Source Widget', $widget_options);
    }

    //back-end display

    public function update( $new_instance, $old_instance ) {
     $instance = $old_instance;
     $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
     $instance['description'] = ( ! empty( $new_instance['description'] ) ) ? strip_tags( $new_instance['description'] ) : '';
     $instance['image'] = ( ! empty( $new_instance['image'] ) ) ? strip_tags( $new_instance['image'] ) : '';

     return $instance;
}

public function form( $instance ) {
$title = ! empty( $instance['title'] ) ? $instance['title'] : ''; ?>
<?php $description = ! empty( $instance['description'] ) ? $instance['description'] : ''; ?>
<?php $image = ! empty( $instance['image'] ) ? $instance['image'] : ''; ?>
<p>
    <label for="<?php echo $this->get_field_id( 'title' ); ?>">Title:</label>
    <input type="text" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo esc_attr( $title ); ?>" />

    <label for="<?php echo $this->get_field_id( 'description' ); ?>">Description:</label>
    <input type="text" id="<?php echo $this->get_field_id( 'description' ); ?>" name="<?php echo $this->get_field_name( 'description' ); ?>" value="<?php echo esc_attr( $description ); ?>" />

    <label for="<?php echo $this->get_field_id( 'image' ); ?>">Image URL:</label>
    <input type="text" id="<?php echo $this->get_field_id( 'image' ); ?>" name="<?php echo $this->get_field_name( 'image' ); ?>" value="<?php echo esc_attr( $image ); ?>" />
</p><?php
}

    //front-end display
    public function widget( $args, $instance ) {

  $title = apply_filters( 'widget_title', $instance[ 'title' ] );
    $description = apply_filters('widget_title', $instance['description']);
    $image = apply_filters('widget_title', $instance['image']);
    ?>

    <?php echo $args['before_widget'] . $args['before_title']; ?> <img src="<?php echo $image; ?>"></img> <?php $args['after_title']; ?>
  <?php echo $args['before_widget'] . $args['before_title'] . $title . $args['after_title']; ?>
    <?php echo $args['before_widget'] . $args['before_title'] . $description . $args['after_title']; ?>

  <?php echo $args['after_widget'];
    }
}

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

sidebar.php

<aside id="secondary" class="widget-area col-sm-12 col-md-12 col-lg-12" role="complementary">
    <div class="col-lg-6 col-md-12">
    <?php dynamic_sidebar( 'main-widget' ); ?>
</div>
    <div class="col-lg-6 col-md-12">
    <?php dynamic_sidebar( 'main-widget' ); ?>
    </div>
</aside><!-- #secondary -->

enter image description here

2
Limpuls

ウィジェットクラスに問題はありません。あなたが持っている問題はあなたがあなたのsidebar.phpの中に2回、ウィジェットを含むウィジェットエリアを表示しているということです:

<aside id="secondary" class="widget-area col-sm-12 col-md-12 col-lg-12" role="complementary">
    <div class="col-lg-6 col-md-12">
    <?php dynamic_sidebar( 'main-widget' ); // this will display all the widgets in your main-widget sidebar ?>
</div>
    <div class="col-lg-6 col-md-12">
    <?php dynamic_sidebar( 'main-widget' ); // this will display again all the widgets in your main-widget sidebar ?>
    </div>
</aside><!-- #secondary -->

各サイドバーディスプレイの2番目のウィジェットはおそらくCSSによって隠れていますが、2回、左側に1回、右側に1回あります。

そのため、dynamic_sidebar( 'main-widget' );を2回呼び出さないでください。

私が理解していることから、ウィジェットを特定のdivにラップして2つの列に配置できるようにしたいと思います。このためには、before-widgetフィルタを介して各ウィジェットのafter-widgetおよびdynamic_sidebar_paramsパラメータをフィルタ処理する必要があります。あるいは、もっと良いことに、CSSを使ってトリックを実行することもできます。

ターゲットウィジェット領域の各ウィジェットにラッパーを追加するスターターPHPコードは次のとおりです。

/**
 * @param array $params
 */
function sole_add_widget_columns_wrapper( $params ) {
    // Add the opening wrapper tag
    $params[0]['before_widget'] = PHP_EOL . '<div class="col-lg-6 col-md-12">' . PHP_EOL . $params[0]['before_widget'];

    // Add the closing wrapper tag
    $params[0]['after_widget'] = $params[0]['after_widget'] . PHP_EOL . '</div><!-- close wrapper -->' . PHP_EOL;
}

/**
 * @param string $index
 */
function sole_handle_main_widget_area_columns( $index ) {
    // We only want to deal with the main widget area
    if ( 'main-widget' !== $index ) {
        return;
    }

    // Filter each widget params and add the wrappers
    add_filter( 'dynamic_sidebar_params', 'sole_add_widget_columns_wrapper', 10, 1 );

    // Hook an action to remove the filter above after we are done with this widget area.
    // This way we don't affect other widget area that may come, on the same page, after this one.
    add_action( 'dynamic_sidebar_after', 'sole_remove_main_widget_area_columns_filter', 10 );
}
add_action( 'dynamic_sidebar_before', 'sole_handle_main_widget_area_columns', 10 );

function sole_remove_main_widget_area_columns_filter() {
    remove_filter( 'dynamic_sidebar_params', 'sole_add_widget_columns_wrapper', 10 );
}

このコードは各ウィジェットをラップし、偶数ウィジェットと奇数ウィジェットを2つの列ラッパーに入れません。

1
Vlad Olaru