2. 9. 1 サイト閲覧画面のカスタマイズ(1)ウィジェット

イベントカレンダー, イベントアーカイブ

ウィジェット登録・削除

 デフォルトウィジェットをすべて削除し、自作の“最近の投稿”と“イベントカレンダー”を登録しています。
 「カスタムメニュー」の代わりに自作のサイトマップ連携型ウィジェットを使っています。これについては、別途紹介します。

コード

// --------------------------------
// デフォルトウィジェット削除
// 最近の投稿 登録
// イベントカレンダー 登録
// --------------------------------
function hk_functions_widgets_init() {
    // デフォルトウィジェット削除
    unregister_widget('WP_Widget_Archives');        // アーカイブ
    unregister_widget('WP_Widget_RSS');             // RSS
    unregister_widget('WP_Nav_Menu_Widget');        // カスタムメニュー
    unregister_widget('WP_Widget_Categories');      // カテゴリ
    unregister_widget('WP_Widget_Calendar');        // カレンダー
    unregister_widget('WP_Widget_Search');          // 検索
    unregister_widget('WP_Widget_Pages');           // 固定ページ
    unregister_widget('WP_Widget_Recent_Comments'); // 最近のコメント
    unregister_widget('WP_Widget_Recent_Posts');    // 最近の投稿
    unregister_widget('WP_Widget_Tag_Cloud');       // タグクラウド
    unregister_widget('WP_Widget_Text');            // テキスト
    unregister_widget('WP_Widget_Meta');            // メタ情報
    // 最近の投稿 登録
    register_widget( 'Hk_Widget_Recent_Posts' );
    // イベントカレンダー 登録
    register_widget( 'Hk_Widget_Event_Calendar' );
    return;
}
add_action( 'widgets_init', 'hk_functions_widgets_init' );

ウィジェット 最近の投稿

 投稿と固定ページを対象にしています。
 パスワード保護を除外しています。

コード

// ================================
// ウィジェット 最近の投稿
// ================================
class Hk_Widget_Recent_Posts extends WP_Widget {
    // ================================
    // 登録
    // ================================
    function __construct() {
        $widget_ops = array( 'description' => '最近の投稿を表示' );
        parent::__construct('hk_widget_recent_posts', '最近の投稿 HK', $widget_ops);
    }

    // --------------------------------
    // 設定画面
    // --------------------------------
    function form( $instance ) {
        if ( isset($instance['title']) )
            $title = htmlspecialchars( $instance['title'] );
        else
            $title = '';
        echo "<p>\n"; 
        echo '  <label for="'.$this->get_field_id('title').'">タイトル:'."</label>\n";
        echo '  <input class="widefat" id="'.$this->get_field_id('title').'" name="'.$this->get_field_name('title').'" type="text" value="'.$title.'" />'."\n";
        echo "</p> \n";
    }

    // --------------------------------
    // 設定更新
    // --------------------------------
    function update( $new_instance, $old_instance ) {
        return $new_instance;
    }

    // --------------------------------
    // 閲覧画面表示
    // --------------------------------
    function widget( $args, $instance ) {
        extract( $args ); 
        $title = '';
        if ( isset($instance['title']) )
            $title = $instance['title'];
        if ( $title == '' )
            $title = '最近の投稿';
        echo $before_widget."\n";
        echo $before_title . $title . $after_title."\n";
        echo $this->recent_posts_disp();
        echo $after_widget."\n";
    }

    // --------------------------------
    // 閲覧画面表示メイン
    //   最近の投稿表示
    // --------------------------------
    private function recent_posts_disp() {
        // 投稿データ取得
        $args = array(
            'post_type'      => array( 'post', 'page' ),
            'post_status'    => 'publish',
            'has_password'   => false,
            'orderby'        => 'date',
            'order'          => 'DESC',
            'posts_per_page' => 5,
        );
        $my_query = new WP_Query( $args );
        $html = '';
        if ( $my_query->have_posts() ) {
            $html  = '<div class="hk_recent_posts">'."\n";
            $html .= '  <ul>'."\n";
            while ( $my_query->have_posts() ) {
                $my_query->the_post();
                $my_post = get_post();
                if ( ! isset( $my_post->post_title ) )    continue;
                $title = $my_post->post_title;
                $link  = get_permalink();
                $html .= '    <li><a href="'.$link.'">'.htmlspecialchars( $title ).'</a>'."\n";
            }
            wp_reset_postdata();
            $html .= '  </ul>'."\n";
            $html .= '</div>'."\n";
        }
        return $html;
    }
} // END OF class Hk_Widget_Recent_Posts

ウィジェット イベントカレンダー

 開催日をもとに今月と来月のカレンダーを表示します。
 月別・日別イベントアーカイブへのリンクは、形式的に投稿日に基づく投稿アーカイブへのリンクにパラメータ hk_ym あるいは hk_ymd を付加しています。アーカイブの表示は、システムの初期化が完了した時点で分岐するのでパラメータさえ付ければリンク先はどこでも良いのですが、擬似的に投稿アーカイブへのリンクと同一形式にしています。

コード

// ================================
// ウィジェット イベントカレンダー
// ================================
class Hk_Widget_Event_Calendar extends WP_Widget {
    // ================================
    // 登録
    // ================================
    function __construct() {
        $widget_ops = array( 'description' => '今月と来月のイベントを表示' );
        parent::__construct( 'hk_widget_event_calendar', 'イベントカレンダー', $widget_ops );
    }

    // --------------------------------
    // 設定画面
    // --------------------------------
    function form( $instance ) {
        if ( isset( $instance['title'] ) )
            $title = htmlspecialchars( $instance['title'] );
        else
            $title = '';
        echo "<p>\n"; 
        echo '  <label for="'.$this->get_field_id('title').'">タイトル:'."</label>\n";
        echo '  <input class="widefat" id="'.$this->get_field_id('title').'" name="'.$this->get_field_name('title').'" type="text" value="'.$title.'" />'."\n";
        echo "</p> \n";
    }

    // --------------------------------
    // 設定更新
    // --------------------------------
    function update( $new_instance, $old_instance ) {
        return $new_instance;
    }

    // --------------------------------
    // 閲覧画面表示
    // --------------------------------
    function widget( $args, $instance ) {
        extract( $args ); 
        $title = '';
        if ( isset( $instance['title'] ) )
            $title = $instance['title'];
        if ( $title == '' )
            $title = 'イベントカレンダー';
        echo $before_widget."\n";
        echo $before_title . $title . $after_title."\n";
        echo $this->hk_event_calendar_disp();
        echo $after_widget."\n";
    }

    // --------------------------------
    // 閲覧画面表示メイン
    // イベントカレンダー表示
    // --------------------------------
    private function hk_event_calendar_disp() {
        // 本日の年月
        date_default_timezone_set('Asia/Tokyo');
        $this_year  = (int) date( 'Y' );
        $this_month = (int) date( 'm' );
        // 来月
        $next_month = $this_month + 1;
        if ( $next_month > 12 ) {
            $next_month = 1;
            $next_year = $this_year + 1;
        }
        else
            $next_year = $this_year;
        // 表示対象月
        if ( isset( $_GET['hk_ym'] ) ) {
            $hk_ym = $_GET['hk_ym'];
            list( $year, $month ) = explode( '-', $hk_ym );
            $year  = (int) $year;
            $month = (int) $month;
        }
        else if ( isset( $_GET['hk_ymd'] ) ) {
            $hk_ymd = $_GET['hk_ymd'];
            list( $year, $month, $day ) = explode( '-', $hk_ymd );
            $year  = (int) $year;
            $month = (int) $month;
        }
        else {
            $year  = $this_year;
            $month = $this_month;
        }
        // 表示対象月のデータ
        $time_reg = gmmktime( 0, 0, 0, $month, 1, $year );
        // 月の日数
        $day_max = date( 't', $time_reg );
        // 月始めの曜日
        $wday    = date( 'w', $time_reg );
        // 投稿データ取得
        $ym = $year.'-'.sprintf( "%02d", $month );
        $args = array(
            'posts_per_page' => -1,
            'order'      => 'ASC',
            'orderby'    => 'meta_value',
            'meta_query' => array(
                array(
                    'key'     => '01_開催日',
                    'value'   => array( $ym.'-00', $ym.'-32' ),
                    'compare' => 'BETWEEN',
                )
            )
        );
        $my_query = new WP_Query( $args );
        // 日別イベントに整理
        $day_title = array();
        for ( $i=1; $i<=$day_max; $i++ )
            $day_title[ $i ] = '';
        if ( $my_query->have_posts() ) {
            while ( $my_query->have_posts() ) {
                $my_query->the_post();
                $post = get_post();
                if ( ! isset( $post->post_title ) )        continue;
                $title   = $post->post_title;
                $post_id = $post->ID;
                $ymd = get_post_meta( $post_id, '01_開催日', true );
                list( $year_r, $month_r, $day_r ) = explode( '-', $ymd );
                $day_r = (int) $day_r;
                $day_title[ $day_r ] .= "\n".$title;
            }
            wp_reset_postdata();
            for ( $i=1; $i<=$day_max; $i++ )
                $day_title[ $i ] = trim( $day_title[ $i ] );
        }
        // イベントカレンダー表示
        $html  = '<div class="hk_calendar">'."\n";
        $html .= '  <div class="hk_cal11">'.$year.'年'.$month.'月</div>'."\n";
        $html .= '  <div class="hk_cal21 hk_clear">'."\n";
        $html .= '    <ul class="hk_cal_ul">'."\n";
        $html .= '      <li>日</li><li>月</li><li>火</li><li>水</li><li>木</li><li>金</li><li>土</li>'."\n";
        $html .= '    </ul>'."\n";
        $html .= '  </div>'."\n";
        $html .= '  <div class="hk_cal31 hk_clear">'."\n";
        $html .= '    <ul class="hk_cal_ul">'."\n      ";
        if ( $wday != 0 ) {
            for ( $i=0; $i<$wday; $i++ )
                $html .= '<li>&nbsp;</li>';
        }
        $j = $wday;
        for ( $i=1; $i<=$day_max; $i++ ) {
            if ( $day_title[ $i ] ) {
                $i_i  = sprintf( "%02d", $i );
                $ymd  = $ym.'-'.$i_i;
                $link = get_day_link( $year, $month, $i );
                $link = add_query_arg( 'hk_ymd', $ymd, $link );
                $html .= '<li><a href="'.$link.'" title="'.htmlspecialchars( $day_title[ $i ] ).'">'.$i.'</a></li>';
            }
            else
                $html .= '<li>'.$i.'</li>';
            if ( $i != $day_max ) {
                $j++;
                if ( $j == 7 ) {
                    $j = 0;
                    $html .= "\n    </ul>\n";
                    $html .= '    <ul class="hk_cal_ul">'."\n      ";
                }
            }
        }
        $html .= "\n    </ul>\n";
        $html .= '  </div>'."\n";
        // 今月・来月へのリンク
        $html .= '  <div class="hk_clear">'."\n";
        // 今月
        $html .= '    <div class="alignleft">'."\n";
        $ym   = $this_year.'-'.sprintf("%02d",$this_month);
        $link = get_month_link( $this_year, $this_month );
        $link = add_query_arg( 'hk_ym', $ym, $link );
        $html .= '      <a href="'.$link.'" title="'.$this_month.'月を表示">'.$this_month.'月</a>'."\n";
        $html .= '    </div>'."\n";
        // 来月
        $html .= '    <div class="alignright">'."\n";
        $ym   = $next_year.'-'.sprintf( "%02d", $next_month );
        $link = get_month_link( $next_year, $next_month );
        $link = add_query_arg( 'hk_ym', $ym, $link );
        $html .= '      <a href="'.$link.'" title="'.$next_month.'月を表示">'.$next_month.'月</a>'."\n";
        $html .= '    </div>'."\n";
        $html .= '  </div>'."\n";
        $html .= '</div>'."\n";
        return $html;
    }
} // END OF class Hk_Widget_Event_Calendar

スタイルシート

.hk_calendar {
    font-size: 12px;
    font-size: 0.857142857rem;
    line-height: 1.75;
    font-family: "MS ゴシック", Helvetica, Arial, sans-serif;
    max-width:140px;
    max-width: 10rem;
    clear:both;
    margin:0;
    padding:0;
}
.hk_cal11 {
    width:100%;
    clear:both;
    text-align:center;
    line-height: 1.75;
    margin:0;
    padding:0;
}
.hk_cal21 {
    width:100%;
    clear:both;
    line-height: 1.75;
    margin:0;
    padding:0;
    border-top:1px #ffffff solid;
}
.hk_cal_ul {
    width:100%;
    clear:both;
    list-style-type:none;
    line-height: 1.75;
    margin:0;
    padding:0;
}
.hk_cal_ul li {
    width:20px;
    width: 1.428571428rem;
    text-align:center;
    float:left;
    line-height: 1.75;
    margin:0;
    padding:0;
}
.hk_cal31 {
    width:100%;
    clear:both;
    line-height: 1.75;
    margin:0 0 6px 0;
    margin:0 0 0.428571428rem 0;
    padding:0;
    border-top:1px #ffffff solid;
    border-bottom:1px #ffffff solid;
}

月別・日別イベントアーカイブ

 イベントアーカイブの表示は、システム初期化完了後に“分岐”してメインクエリとページ番号を設定し、テーマファイルを呼び出します。
 他のページと間違えられないよう、ヘッダータイトルタグの設定も必要です。
 テーマのページナビゲーション用に、ページ番号を global $paged に設定する必要があります。
 表示用のテーマファイルを作成する必要があります。archive.php が参考になります。ファイル名は何でもかまいません。
 フック'wp_loaded'で“分岐”しますので、優先順位を最後にする必要があります。20 にしています。

コード

// --------------------------------
// 月別・日別イベントアーカイブ
//   投稿取得・テーマ呼び出し
// --------------------------------
function hk_functions_wp_loaded() {
    if (( ! isset( $_GET['hk_ym'] ) ) && ( ! isset( $_GET['hk_ymd'] ) ))    return;
    // ページ番号
    global $wp_rewrite;
    global $paged;
    if ( ! $wp_rewrite->using_permalinks() ) {
        if ( isset( $_REQUEST['paged'] ) )
                $paged = (int) $_REQUEST['paged'];
        else    $paged = 1;
    }
    else {
        $pagination_base = '/'.$wp_rewrite->pagination_base.'/';
        // ページのパスとファイル名とパラメータ
        $uri = $_SERVER['REQUEST_URI'];
        if ( strpos( $uri, $pagination_base ) !== false ) {
            preg_match( "|(?:$wp_rewrite->pagination_base/)(\d+)(?:/)|i", $uri, $matches );
            $paged = (int) $matches[1];
        }
        else    $paged = 1;
    }
    // 投稿取得パラメータ
    $args = array(
        'post_type'   => 'post',
        'post_status' => 'publish',
        'orderby'     => 'meta_value',
        'order'       => 'ASC',
        'paged'       => $paged,
        'posts_per_page' => get_option( 'posts_per_page' ),
    );
    // 月別アーカイブ
    if ( isset( $_GET['hk_ym'] ) ) {
        $ym = $_GET['hk_ym'];
        $args['meta_query'] = array(
            array(
                'key'     => '01_開催日',
                'value'   => array( $ym.'-00', $ym.'-32' ),
                'compare' => 'BETWEEN',
            )
        );
    }
    // 日別アーカイブ
    else {
        $ymd = $_GET['hk_ymd'];
        $args['meta_query'] = array(
            array(
                'key'   => '01_開催日',
                'value' => $ymd,
            )
        );
    }
    query_posts( $args );
    // テーマ呼び出し
    include( TEMPLATEPATH.'/archive-event.php' );
    exit;
}
add_action( 'wp_loaded', 'hk_functions_wp_loaded', 20 );

 このプログラムをお使いになる場合は、お使いになる方の自己責任でお願いします。

更新日:2016/03/23
掲載日:2015/11/13