
いよいよ今週の土曜日から年末年始のおやすみに入ります(^^)/。その準備としてこのblogにもお知らせを表示しようと思いました。
以前作った「トップページだけに表示するウィジェットエリアを作るーtwentyfourteen編」のトップのエリアをいよいよ使おう!と思うのですが、まだおやすみに入ってはいないので表示するのはおやすみに入ってからにしたいと思います。その日に公開するのも面倒だし、ということで期限付きのテキストウィジェットを作ってみました。
ウィジェットエリアとウィジェットの違い
今日までちょっとごっちゃになっていたのですが「ウィジェットエリア」と「ウィジェット」は違うものでしたね。。以前書いた記事もその辺を間違えていたところもあったので修正しました。
以前書いたウィジェットエリアの記事
[ryus_blogcard url=https://usortblog.com//toppage-widget/]
[ryus_blogcard url=https://usortblog.com//toppage-widget-simplicity/]

図で描くとこんなかんじで、ウィジェットエリア=ウィジェットを置く場所、ウィジェット=表示するコンテンツ って感じでした。
なので、前回は「ウィジェットエリア」を作りましたが、今回はそこに載せる「ウィジェット」で期限付きのテキストウィジェットを作りたいと思います。
作った期限付きテキストウィジェットはこちらです!
まずは完成したものをお見せしたいと思います。

ダッシュボード 外観>ウィジェット でみるとこの 期限付きテキスト が表示されます。よく使われる テキスト と同じような、タイトルと本文が入力できるタイプのものです。
これを表示したい ウィジェットエリアに ドラッグ&ドロップ します。どのウィジェットエリアでもかまいませんが今回は以前作った「トップメインウィジェット」に表示します。

そうするとこんな感じで入力項目が表示されます。

こんな感じで入力して、保存すると

このように表示されます。期限がちゃんと判定できているかどうかを見るために

日付を明日から(今日は2015/12/24)にしてみます。そしてトップページを見ると

何も表示されなくなります!(画像が壊れてるのはローカルのテスト環境だからで、このウィジェットのせいではありません(^_^;)
開始日と終了日を入れるとその期限だけ表示します。開始日と終了日を入れなければ常に表示されます。開始日だけを入れればその日が過ぎたら表示します。終了日だけをいれたら終了日まで表示します。
というようなウィジェットです。
期限付きテキストウィジェットを作る方法
これを作ろうと思ってウィジェットの作り方はどうするのかな?と検索して、株式会社LIGさんの
これだけ!?WordPressのWidget(ウィジェット)の作り方
この記事を見つけました。とても分かりやすくほぼこのままの形でカスタマイズさせていただきました。
自分のサイトでこの期限付きテキストウィジェットを作るには、使っている子テーマのfunctions.phpに以下のコードをコピーして貼り付けてください。テーマはtwentyfourteenでなくても何でもかまいません。
// 期限付きのテキストウィジェット
class Limit_Text_Widget extends WP_Widget{
/**
* Widgetを登録する
*/
function __construct() {
parent::__construct(
'ryus_text_time_limit', // Base ID
'期限付きテキスト', // Name
array( 'description' => '期限付きのテキストウィジェット', ) // Args
);
}
/**
* 表側の Widget を出力する
*
* @param array $args 'register_sidebar'で設定した「before_title, after_title, before_widget, after_widget」が入る
* @param array $instance Widgetの設定項目
*/
public function widget( $args, $instance ) {
if ($instance['limit_from_ymd']) {
if (date('Y-m-d') < $instance['limit_from_ymd']) {
return;
}
}
if ($instance['limit_to_ymd']) {
if (date('Y-m-d') > $instance['limit_to_ymd']) {
return;
}
}
echo $args['before_widget'];
echo $args['before_title'];
echo $instance['title'];
echo $args['after_title'];
echo nl2br($instance['body']);
echo $args['after_widget'];
}
/** Widget管理画面を出力する
*
* @param array $instance 設定項目
* @return string|void
*/
public function form( $instance ){
$title = $instance['title'];
$title_name = $this->get_field_name('title');
$title_id = $this->get_field_id('title');
$body = $instance['body'];
$body_name = $this->get_field_name('body');
$body_id = $this->get_field_id('body');
$limit_from_ymd = $instance['limit_from_ymd'];
$limit_from_ymd_name = $this->get_field_name('limit_from_ymd');
$limit_from_ymd_id = $this->get_field_id('limit_from_ymd');
$limit_to_ymd = $instance['limit_to_ymd'];
$limit_to_ymd_name = $this->get_field_name('limit_to_ymd');
$limit_to_ymd_id = $this->get_field_id('limit_to_ymd');
?>
<p>
<label for="<?php echo $title_id; ?>">タイトル:</label>
<input class="widefat" id="<?php echo $title_id; ?>" name="<?php echo $title_name; ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
</p>
<p>
<label for="<?php echo $body_id; ?>">本文:</label>
<textarea class="widefat" id="<?php echo $body_id; ?>" name="<?php echo $body_name; ?>"><?php echo esc_attr( $body ); ?></textarea>
</p>
<p>
<label for="<?php echo $limit_from_ymd_id; ?>">有効期限開始日(yyyy-mm-ddの形式で入力):</label>
<input class="widefat" id="<?php echo $limit_from_ymd_id; ?>" name="<?php echo $limit_from_ymd_name; ?>" type="text" value="<?php echo esc_attr( $limit_from_ymd ); ?>"
</p>
<p>
<label for="<?php echo $limit_to_ymd_id; ?>">有効期限終了日(yyyy-mm-ddの形式で入力):</label>
<input class="widefat" id="<?php echo $limit_to_ymd_id; ?>" name="<?php echo $limit_to_ymd_name; ?>" type="text" value="<?php echo esc_attr( $limit_to_ymd ); ?>">
</p>
<?php
}
/** 新しい設定データが適切なデータかどうかをチェックする。
* 必ず$instanceを返す。さもなければ設定データは保存(更新)されない。
*
* @param array $new_instance form()から入力された新しい設定データ
* @param array $old_instance 前回の設定データ
* @return array 保存(更新)する設定データ。falseを返すと更新しない。
*/
function update($new_instance, $old_instance) {
if($new_instance['limit_from_ymd']){
$ymd = explode('-', $new_instance['limit_from_ymd']);
if (count($ymd) < 3){
return false;
}
if (checkdate($ymd[1], $ymd[2], $ymd[0]) == false) {
return false;
}
$new_instance['limit_from_ymd'] = $ymd[0].'-'.substr('0'.$ymd[1], -2).'-'.substr('0'.$ymd[2], -2);
}
if($new_instance['limit_to_ymd']){
$ymd = explode('-', $new_instance['limit_to_ymd']);
if (count($ymd) < 3){
return false;
}
if (checkdate($ymd[1], $ymd[2], $ymd[0]) == false) {
return false;
}
$new_instance['limit_to_ymd'] = $ymd[0].'-'.substr('0'.$ymd[1], -2).'-'.substr('0'.$ymd[2], -2);
}
return $new_instance;
}
}
add_action( 'widgets_init', function () {
register_widget( 'Limit_Text_Widget' ); //WidgetをWordPressに登録する
} );
すっごい長いですが(^_^;、

コピーマークを押して、

こうなったら ctrl+c か 右クリックしてコピーして 貼り付けてください。
カスタマイズしたコードの一部を解説
それだけだとちょっと面白くないので、カスタマイズしたところにの一部について書きます。
public function widget( $args, $instance ) {
if ($instance['limit_from_ymd']) {
if (date('Y-m-d') < $instance['limit_from_ymd']) {
return;
}
}
if ($instance['limit_to_ymd']) {
if (date('Y-m-d') > $instance['limit_to_ymd']) {
return;
}
}
まずは期限付き部分のコーディングです。値が入っているとき、開始日(limit_from_ymd)より本日が小さければ return して表示しません。同様に値が入っているとき、終了日(limit_to_ymd)より本日が大きければ return して表示しません。
function update($new_instance, $old_instance) {
if($new_instance['limit_from_ymd']){
$ymd = explode('-', $new_instance['limit_from_ymd']);
if (count($ymd) < 3){
return false;
}
if (checkdate($ymd[1], $ymd[2], $ymd[0]) == false) {
return false;
}
このfunctionでは入力された値の妥当性をチェックして、ダメだったら(この場合は形式が思ったものでないとか、日付で無いとか)falseを返します。今入力した値は保存されません。
OKだったときは
$new_instance['limit_from_ymd'] = $ymd[0].'-'.substr('0'.$ymd[1], -2).'-'.substr('0'.$ymd[2], -2)
こんな感じに編集し直します。というのは月や日が1桁だったときでも日付の大小が判断できるように頭に0を付けています。
他に表示する場面で
echo nl2br($instance['body']);
としました。これはtextareaに入力された文章を見た目同じように表示するため nl2br で改行コードをbrタグに置き換えています。
あと、LIGさんのコードにはウィジェットエリアも追加するコードが入っていましたが今回はウィジェットだけ作りたかったのではずしました。
おまけ:ひっっかったところ 日付とフィールドのid
いつもながら順調にはできず引っかかったところが2カ所ありました。
日付の問題
このblogを書くために朝試していたんですが、どうも日付の判定がおかしいということに気づきました。限界値テストのために終了日を昨日にしているのになぜか表示されてしまいます。
あ、、今は9時前…そっか ということで思い出しました。
[ryus_blogcard url=https://usortblog.com//phpdateminus9/]
試していたテーマがいつも使っているものではなかったためにこの
date_default_timezone_set('Asia/Tokyo');
が子テーマのfunctions.phpに入っていませんでした。これを入れて日付の問題は解消しました。
フィールドのidの問題
テストをしてて大体うまく動いていたのですが「あれ?最初の1回だけ開始日が保存されない」ということに気づきました。だめなのは最初の1回だけでもう一度保存すれば開始日も保存されます。
コードをなんども見直しましたが特におかしなコーディングはしていません。DBを見ても最初の1回は開始日が保存されていません。これは…としばらく悩みましたが、デベロッパーツールでElementsを表示してみたところ、

こんな風になっていました。
ウィジェットはいくつでも追加が可能なため、それぞれのウィジェットにはidとなる数字が入力フィールドに入っています。この場合、idは8でした。
保存されない limit_from を見てみると 8 となるべき所に __i__ という謎の文字が入っています。
これについてはフィールド名を変えてみたりしてもダメでしたし、検索してみましたが同様の問題が起こっているということだけがわかってまだ解決していません。ということで、このウィジェットを使うときははスミマセンが開始日は一回目の保存では保存できないため、もう一度入力して保存してくださいm(_ _)m
この問題が解決できないと不便なのでなんとかしたいとは思っています…
まとめ:年末年始とかの休暇でなくてもいろいろお使いいただけたら、と思います
子テーマを使っているサイトでしたらどのテーマでもこの 期限付きテキストウィジェット が使えると思いますので是非お試しください。
この期限付きテキストウィジェットは年末年始だけで無く、何かのイベントとか、創立記念日とかにも使えるんじゃないかなぁと思います。
このblogにも年末年始の間だけ表示するようにしていますので、見に来てください。
あとコードはとても簡単なので改造していろいろなフィールドをくっつけて、もっと機能の多いウィジェットを作ってみるのもいいかもしれません(^^)/
[amazon_searchlink search=”PHPプログラム”]



コメント