スポンサーリンク

表示期間等を指定できるウィジェット”Scheduled Widge”を作って実装してみた 

Widget1 ワードプレス関連
この記事は約26分で読めます。
記事内に広告が含まれています。
スポンサーリンク

期限付きの広告表示には、これまでCocoonのキャンペーンショートコードを使っていました。しかし、1点気になることがあり、最近は【Widget Visibility Time Scheduler】を利用していたのですが、最近になってもう少し細かく期限設定をしたいと思い、いろいろと調べてみたのですが良いものがなかなか見つかりませんでした。そこで、新たにウィジェットを追加して対応することにしました。
この記事では、新しく実装したウィジェットの設定方法と使い方、そしてCocoonのキャンペーンショートコードで気になっていた点について、忘備録として残すことにしました。

修正しました

気がつかなかったのですが、サイドバー以外の本文等にこのウィジェットを設置した場合、レイアウト崩れが発生し、サイドバーが本文の下に表示されてしまう不具合があったようです。そのため一部の記述を修正しアップデートしました。また修正した内容はここで確認できます。

スポンサーリンク

Cocoonのキャンペーンショートコードについて

Cocoonのキャンペーンコードは、期間の始まりと終わりを指定して、教示したいコンテンツの内容を記述するがけで簡単に設定できとても使いやすいです。

Saidebar2

ただ、気になるのは期限が切れて表示する対象の物がないときに、一部のスキンで空白のブロックが表示されてしまうことです。

Saidebar1

この空白ブロックを消せないかといろいろと試したのですが、見つからず【Widget Visibility Time Scheduler】を使うことにしました。

簡単なWidget Visibility Time Schedulerの使い方

ここでちょっと簡単に【Widget Visibility Time Scheduler】の使い方を。
プラグイン追加より【Widget Visibility Time Scheduler】を検索してインストール、有効化するだけで準備は完了です。
基本設定とは特になく、すぐに使うことが出来ます。

使い方は、各ウィジェットの下の方に新しく”Open scheduler”のオプションが表示されるます。

Scheduler1

”Open scheduler”をクリックすると設定項目が表示されます。

”予約投稿”で”表示” 又は”非表示”を選択した時点で、期間指定ができるようになります。
指定は、期間、時間、そして曜日の指定ができます。

Scheduler2

予約投稿で”ー選択ー”のまま表示/非表示を選択しない場合は、期間指定はされず、通常のウィジェットとして機能します。

Scheduler3

指定期間が終わり、または非表示期間の場合にはウィジェットのブロックも表示されなくなります。

After_Saidebar

これでCocoonのキャンペーンショートコードで気になった、空白ブロックの表示問題が解消されることになります。

スポンサーリンク

指定期間中の除外期間を設定したい

【Widget Visibility Time Scheduler】を使っていて、設定期間中に除外期間の設定をしたいと思いいろいろと試していたのですがうまくいかず、新たに対応できるウィジェットを追加設定することにしました。
ただ今回は、【Widget Visibility Time Scheduler】のように全てのウィジェットに追加機能とするのではなく単体の新しいウィジェットとして追加をすることにしました。

スポンサーリンク

Scheduled Widgeの特徴

新しく追加するウィジェットの機能はとてもシンプルで期間を指定して表示/非表示ができるというものです。
・HTML,ショートコードに対応
・表示期間と非表示期間を選べる
・曜日で表示/非表示が設定できる
・設定期間中に除外期間を設定することが出来る
が主な機能となります。

ウィジェットの追加設定はFunction.phpに貼り付けるだけ

下記内容をFunction.phpに貼り付けるだけで追加設定は終わりです。

/***********************************************
Scheduled_Widget 期間指定できるウィジェット
***********************************************/

class Scheduled_Widget extends WP_Widget {
    public function __construct() {
        parent::__construct('Scheduled_widget', __('Scheduled Widget', 'text_domain'));
    }

    public function widget($args, $instance) {
        $current_time = current_time('Y-m-d H:i');
        $current_day = date('w');

        $title = apply_filters('widget_title', $instance['title'] ?? '');
        $content = $instance['content'] ?? '';

        $start_datetime = !empty($instance['start_date']) ? $instance['start_date'] . ' ' . $instance['start_time'] : '1970-01-01 00:00';
        $end_datetime = !empty($instance['end_date']) ? $instance['end_date'] . ' ' . $instance['end_time'] : '1970-01-01 00:00';

        // 除外期間
        $exclude_start_datetime = !empty($instance['exclude_start_date']) ? $instance['exclude_start_date'] . ' ' . $instance['exclude_start_time'] : '1970-01-01 00:00';
        $exclude_end_datetime = !empty($instance['exclude_end_date']) ? $instance['exclude_end_date'] . ' ' . $instance['exclude_end_time'] : '2099-01-01 00:00';

        $visibility = $instance['visibility'] ?? 'show';
        $selected_days = $instance['days'] ?? [0, 1, 2, 3, 4, 5, 6];

        $is_within_time_range = ($current_time >= $start_datetime && $current_time <= $end_datetime);
        $is_selected_day = in_array($current_day, $selected_days);
        $is_within_exclude_range = ($current_time >= $exclude_start_datetime && $current_time <= $exclude_end_datetime);

            if (($visibility == 'show' && $is_within_time_range && $is_selected_day && !$is_within_exclude_range) ||
            ($visibility == 'hide' && (!$is_within_time_range || !$is_selected_day || $is_within_exclude_range))) {
            echo $args['before_widget'];
            if (!empty($title)) {
                echo $args['before_title'] . $title . $args['after_title'];
            }
              // ショートコード出力時に <p> タグを付けない
    echo do_shortcode($content);
    echo $args['after_widget']; // ← ここで1回だけ出力
}
    }

    public function form($instance) {
        $title = $instance['title'] ?? '';
        $content = $instance['content'] ?? '';
        $start_date = $instance['start_date'] ?? '';
        $end_date = $instance['end_date'] ?? '';
        $start_time = $instance['start_time'] ?? '00:00';
        $end_time = $instance['end_time'] ?? '23:59';
        $visibility = $instance['visibility'] ?? 'show';
        $selected_days = $instance['days'] ?? [0, 1, 2, 3, 4, 5, 6];

        $exclude_start_date = $instance['exclude_start_date'] ?? '';
        $exclude_end_date = $instance['exclude_end_date'] ?? '';
        $exclude_start_time = $instance['exclude_start_time'] ?? '00:00';
        $exclude_end_time = $instance['exclude_end_time'] ?? '23:59';

 $is_exclude_enabled = !empty($exclude_start_date) || !empty($exclude_end_date); // 除外期間が設定されているか

        $start_of_week = get_option('start_of_week', 1);
        $days_of_week = range(0, 6);
        $days_of_week = array_merge(array_slice($days_of_week, $start_of_week), array_slice($days_of_week, 0, $start_of_week));

        $weekdays = [
            0 => '日曜日',
            1 => '月曜日',
            2 => '火曜日',
            3 => '水曜日',
            4 => '木曜日',
            5 => '金曜日',
            6 => '土曜日',
        ];
// Get current server time
    $current_time = current_time('Y-m-d H:i:s');
    
    ?>
   
        <!-- タイトルとコンテンツのフォーム -->
        <p>
            <label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('タイトル:', 'text_domain'); ?></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 esc_attr($title); ?>">
        </p>

        <p>
            <label for="<?php echo $this->get_field_id('content'); ?>"><?php _e('コンテンツ:', 'text_domain'); ?></label>
            <textarea class="widefat" id="<?php echo $this->get_field_id('content'); ?>" name="<?php echo $this->get_field_name('content'); ?>"><?php echo esc_textarea($content); ?></textarea>
        </p>

        <!-- 可視設定 -->
        <p>
            <label for="<?php echo $this->get_field_id('visibility'); ?>"><?php _e('表示設定:', 'text_domain'); ?></label>
            <select class="widefat" id="<?php echo $this->get_field_id('visibility'); ?>" name="<?php echo $this->get_field_name('visibility'); ?>">
                <option value="show" <?php selected($visibility, 'show'); ?>><?php _e('表示', 'text_domain'); ?></option>
                <option value="hide" <?php selected($visibility, 'hide'); ?>><?php _e('非表示', 'text_domain'); ?></option>
            </select>
        </p>

        <!-- 開始日と終了日 -->
 <p><strong>現在のサーバー時間: <?php echo esc_html($current_time); ?></strong></p>       
 <p>
            <label for="<?php echo $this->get_field_id('start_date'); ?>"><?php _e('開始日:', 'text_domain'); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id('start_date'); ?>" name="<?php echo $this->get_field_name('start_date'); ?>" type="date" value="<?php echo esc_attr($start_date); ?>">
        </p>

        <p>
            <label for="<?php echo $this->get_field_id('start_time'); ?>"><?php _e('開始時間:', 'text_domain'); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id('start_time'); ?>" name="<?php echo $this->get_field_name('start_time'); ?>" type="time" value="<?php echo esc_attr($start_time); ?>">
        </p>

        <p>
            <label for="<?php echo $this->get_field_id('end_date'); ?>"><?php _e('終了日:', 'text_domain'); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id('end_date'); ?>" name="<?php echo $this->get_field_name('end_date'); ?>" type="date" value="<?php echo esc_attr($end_date); ?>">
        </p>

        <p>
            <label for="<?php echo $this->get_field_id('end_time'); ?>"><?php _e('終了時間:', 'text_domain'); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id('end_time'); ?>" name="<?php echo $this->get_field_name('end_time'); ?>" type="time" value="<?php echo esc_attr($end_time); ?>">
        </p>

        <!-- 曜日選択 -->
        <p>
            <label><?php _e('曜日設定:', 'text_domain'); ?></label><br>
            <?php foreach ($days_of_week as $day) : ?>
                <label>
                    <input type="checkbox" name="<?php echo $this->get_field_name('days'); ?>[]" value="<?php echo $day; ?>" <?php checked(in_array($day, $selected_days)); ?>>
                    <?php echo $weekdays[$day]; ?>
                </label><br>
            <?php endforeach; ?>
        </p>

  <!-- 除外期間の表示切り替え用チェックボックス -->
        <p>
            <input type="checkbox" id="<?php echo $this->get_field_id('enable_exclude'); ?>" <?php checked($is_exclude_enabled); ?>>
            <label for="<?php echo $this->get_field_id('enable_exclude'); ?>"><?php _e('除外期間設定', 'text_domain'); ?></label>
        </p>

        <!-- 除外期間フォーム(初期状態はチェックありの時だけ表示) -->
        <div id="<?php echo $this->get_field_id('exclude_settings'); ?>" style="display: <?php echo $is_exclude_enabled ? 'block' : 'none'; ?>;">
            <h3><?php _e('除外期間:', 'text_domain'); ?></h3>

            <p>
                <label for="<?php echo $this->get_field_id('exclude_start_date'); ?>"><?php _e('開始日:', 'text_domain'); ?></label>
                <input class="widefat" id="<?php echo $this->get_field_id('exclude_start_date'); ?>" name="<?php echo $this->get_field_name('exclude_start_date'); ?>" type="date" value="<?php echo esc_attr($exclude_start_date); ?>">
            </p>

            <p>
                <label for="<?php echo $this->get_field_id('exclude_start_time'); ?>"><?php _e('開始時間:', 'text_domain'); ?></label>
                <input class="widefat" id="<?php echo $this->get_field_id('exclude_start_time'); ?>" name="<?php echo $this->get_field_name('exclude_start_time'); ?>" type="time" value="<?php echo esc_attr($exclude_start_time); ?>">
            </p>

            <p>
                <label for="<?php echo $this->get_field_id('exclude_end_date'); ?>"><?php _e('終了日:', 'text_domain'); ?></label>
                <input class="widefat" id="<?php echo $this->get_field_id('exclude_end_date'); ?>" name="<?php echo $this->get_field_name('exclude_end_date'); ?>" type="date" value="<?php echo esc_attr($exclude_end_date); ?>">
            </p>

            <p>
                <label for="<?php echo $this->get_field_id('exclude_end_time'); ?>"><?php _e('終了時間:', 'text_domain'); ?></label>
                <input class="widefat" id="<?php echo $this->get_field_id('exclude_end_time'); ?>" name="<?php echo $this->get_field_name('exclude_end_time'); ?>" type="time" value="<?php echo esc_attr($exclude_end_time); ?>">
            </p>
        </div>

        <script>
            document.addEventListener("DOMContentLoaded", function() {
                var checkbox = document.getElementById("<?php echo $this->get_field_id('enable_exclude'); ?>");
                var excludeSettings = document.getElementById("<?php echo $this->get_field_id('exclude_settings'); ?>");

                function toggleExcludeSettings() {
                    excludeSettings.style.display = checkbox.checked ? "block" : "none";
                }

                checkbox.addEventListener("change", toggleExcludeSettings);
            });
        </script>

        <?php
    }

    public function update($new_instance, $old_instance) {
        $instance = [];
        $instance['title'] = (!empty($new_instance['title'])) ? strip_tags($new_instance['title']) : '';
        $instance['content'] = (!empty($new_instance['content'])) ? $new_instance['content'] : '';
        $instance['visibility'] = (!empty($new_instance['visibility'])) ? strip_tags($new_instance['visibility']) : 'show';
        $instance['start_date'] = (!empty($new_instance['start_date'])) ? strip_tags($new_instance['start_date']) : '';
        $instance['end_date'] = (!empty($new_instance['end_date'])) ? strip_tags($new_instance['end_date']) : '';
        $instance['start_time'] = (!empty($new_instance['start_time'])) ? strip_tags($new_instance['start_time']) : '00:00';
        $instance['end_time'] = (!empty($new_instance['end_time'])) ? strip_tags($new_instance['end_time']) : '23:59';
        $instance['exclude_start_date'] = (!empty($new_instance['exclude_start_date'])) ? strip_tags($new_instance['exclude_start_date']) : '';
        $instance['exclude_end_date'] = (!empty($new_instance['exclude_end_date'])) ? strip_tags($new_instance['exclude_end_date']) : '';
        $instance['exclude_start_time'] = (!empty($new_instance['exclude_start_time'])) ? strip_tags($new_instance['exclude_start_time']) : '00:00';
        $instance['exclude_end_time'] = (!empty($new_instance['exclude_end_time'])) ? strip_tags($new_instance['exclude_end_time']) : '23:59';
        $instance['days'] = (!empty($new_instance['days'])) ? $new_instance['days'] : [0, 1, 2, 3, 4, 5, 6];
        
        return $instance;
    }
}
function register_Scheduled_widget() {
    register_widget('Scheduled_Widget');
}
add_action('widgets_init', 'register_Scheduled_widget');

期間の指定がない場合を考慮し、開始期間、終了期間、時間等はディフォルトであらかじめ設定していますので問題があるようでしたら変更ください。
曜日の並びについては、ワードプレス設定の曜日始まりに合わせたものとなっています。
また、日時はサーバー時間を基準としています。

修正箇所

すでに上に記載されてPHPの内容は修正済みとなっていますが、修正箇所だけを直すのであれば下記となります。
37行目あたりにあるショートコード対応の部分

// ショートコード対応
echo '<p>' . do_shortcode($content) . '</p>';
echo $args['after_widget']; echo $args['after_widget'];
}

を下記のように修正しています。

  // ショートコード出力時に <p> タグを付けない
    echo do_shortcode($content);
    echo $args['after_widget']; // ← ここで1回だけ出力
}

不要な<p>タッグが入っていたためにレイアウト崩れが発生していたようです。

スポンサーリンク

使い方

説明するほどではありませんがとりあえず...。
Function.phpにコードを張り付けるとウィジェット管理画面に【Scheduled Widget】が表示されます。

Widget1

【Scheduled Widget】をサイドバーなどに設置し設定をしていきます。

Widget2
widget3

① タイトル
② 表示したいコンテンツ、HTML、ショートコード等、ウィンドウの大きさ変更可能
③ 表示 / 非表示の選択
④ 開始日時指定
⑤ 終了日時指定
⑥ 対象曜日指定
⑦ 除外期間設定 あり/なし選択
⑧ 除外期間 開始日時指定
⑨ 除外期間 終了日時指定
除外期間の設定については、⑦の除外期間設定のチェックを入れると表示されます。
チェックを入れても表示されない場合には画面をリフレッシュすると表示されます。

スポンサーリンク

注意事項

キャッシュ関連のプラグインを使用している場合は、キャッシュが更新されないと期間指定がうまく作動しませんので注意が必要です。
WP Fastest Cache プラグインを使用している場合は下記記事をご参考ください。

さいごに

Scheduled Widgeについてですが、全ての環境で機能するかどうかは確認していませんのでご了承ください。
また、他のプラグイン等と競合する場合もあるかもしれませんので、Function.phpに追加する際は、バックアップを行うなど自己責任で実施ください。

コメント

タイトルとURLをコピーしました