TopWordPressテーマ > 2010年12月
2010年12月10日

WordPress 3でウィジェットを作るカスタマイズ

December 10,2010 2:55 AM
Tag:[, ]
Permalink

WordPress 3のサイドバーにウィジェットを表示するカスタマイズ」の続きで、WordPress 3でウィジェットを作るカスタマイズを紹介します。

1.基本

ウィジェット作成に必要なソースコードは次のようなイメージです。

class WP_Widget_xxx extends WP_Widget {
    function WP_Widget_xxx() { }
    function form( $instance ) { }
    function update( $new_instance, $old_instance ) { }
    function widget( $args, $instance ) { }
}
function WP_Widget_xxxInit() {
    register_widget('WP_Widget_xxx');
}
add_action('widgets_init', 'WP_Widget_xxxInit');

ソースコードをテーマのfunction.php、あるいはプラグインファイルに記述すれば、ウィジェットが追加される仕組みになっています。

前述のソースコードは3つの部分に大別されます。

  1. WP_Widgetを継承したクラスWP_Widget_xxxの定義
  2. ウィジェット登録する関数(WP_Widget_xxxInit)の定義
  3. add_action()を使って、ウィジェット管理画面を初期化するフックポイントwidgets_initにウィジェット初期化関数(WP_Widget_xxxInit())の登録

処理は3→2→1の順で実行されます。2と3はxxxの部分を任意の名称にするだけでどんなウィジェットにも使いまわせます。3を次のように書けば2を省略できます。

add_action('widgets_init', create_function('', 'return register_widget("WP_Widget_xxx");'));

実際にウィジェットの中身を作るのは1のクラスWP_Widget_xxxで、クラス内で定義する関数は次の4つです。

  • コンストラクタ(WP_Widget_xxx)
  • form():管理画面のウィジェットにフォームを表示する関数
  • update():管理画面のウィジェットの「保存」をクリックしたときに実行される関数
  • widget():ウィジェットを表示する関数

ここではデフォルトのカレンダーウィジェットを例に、それぞれの関数の動作について解説します。

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

ウィジェットで表示されたカレンダー
ウィジェットで表示されたカレンダー

カレンダーウィジェットのソースコード

class WP_Widget_Calendar extends WP_Widget {
 
    function WP_Widget_Calendar() {
        $widget_ops = array('classname'   => 'widget_calendar',
                            'description' => __( 'A calendar of your site’s posts') );
        $this->WP_Widget('calendar', __('Calendar'), $widget_ops);
    }
 
    function widget( $args, $instance ) {
        extract($args);
        $title = apply_filters('widget_title', 
                               empty($instance['title']) ?
                               ' ' : $instance['title'],
                               $instance,
                               $this->id_base);
        echo $before_widget;
        if ( $title )
            echo $before_title . $title . $after_title;
        echo '<div id="calendar_wrap">';
        get_calendar();
        echo '</div>';
        echo $after_widget;
    }
 
    function update( $new_instance, $old_instance ) {
        $instance = $old_instance;
        $instance['title'] = strip_tags($new_instance['title']);
        return $instance;
    }
 
    function form( $instance ) {
        $instance = wp_parse_args( (array) $instance, array( 'title' => '' ) );
        $title = strip_tags($instance['title']);
?>
        <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 esc_attr($title); ?>" />
        </p>
<?php
    }
}
 
function WP_Widget_CalendarInit() {
    register_widget('WP_Widget_Calendar');
}
 
add_action('widgets_init', 'WP_Widget_CalendarInit');

1.コンストラクタ

コンストラクタはウィジェット名の定義、ウィジェットの登録などを行います。カレンダーウィジェットのコンストラクタは次のようになっています。

function WP_Widget_Calendar() {
    $widget_ops = array('classname'   => 'widget_calendar',
                        'description' => __( 'A calendar of your site&#8217;s posts') );
    $this->WP_Widget('calendar', __('Calendar'), $widget_ops);
}

WP_Widget()の引数の意味は次の通りです。

WP_Widget(ウィジェットID, ウィジェット名, ウィジェットオプション, コントロールオプション);

ウィジェットIDは任意の小文字の文字列、ウィジェット名は管理画面のウィジェットタイトルになります。

ウィジェットオプションにはハッシュclassnameとdescriptionを配列で定義でき、descriptionはウィジェットタイトル下の説明文になります。

コントロールオプションには、ウィジェットのサイズを定義するハッシュwidthとheightを配列で定義できます(有効なのはwidthのみの模様)。

$control_ops = array('width' => '300px', 'height' => '300px');

2.form()

form()はウィジェット管理画面のフォームを定義します。フォームを定義することでウィジェットの表示をカスタマイズすることができます。

以下はカレンダーウィジェットのタイトル名を変更するためのフォームです。

function form( $instance ) {
    $instance = wp_parse_args( (array) $instance, array( 'title' => '' ) );
    $title = strip_tags($instance['title']);
?>
    <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 esc_attr($title); ?>" />
    </p>
<?php
}

関数の引数$instanceにはフォームデータが設定されており、1行目のwp_parse_argsで$instanceをハッシュ形式に変換します。

$instance = wp_parse_args( (array) $instance, array( 'title' => '' ) );

2行目で、ハッシュキーtitleの値から不要なタグを除去します。

$title = strip_tags($instance['title']);

残りの処理で、取得したフォームデータ($title)をフォームに反映させます。

<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 esc_attr($title); ?>" />
</p>

関数get_field_id()とget_field_name()は上記の処理を流用すれば良いと思います。

参考までに、get_field_id()はwp-includes/widgets.phpにあり、次の処理を行っています。

function get_field_id($field_name) {
    return 'widget-' . $this->id_base . '-' . $this->number . '-' . $field_name;
}

get_field_name()もwp-includes/widgets.phpにあり、次の処理を行っています。

function get_field_name($field_name) {
    return 'widget-' . $this->id_base . '[' . $this->number . '][' . $field_name . ']';
}

3.update()

update()は、管理画面のウィジェットの「保存」をクリックしたときに実行し、フォームデータを保存します。

function update( $new_instance, $old_instance ) {
    $instance = $old_instance;
    $instance['title'] = strip_tags($new_instance['title']);
    return $instance;
}

関数の引数$new_instanceは変更後のデータ、$old_instanceは変更前のデータが設定されています。ここでは2行目でハッシュキーtitleの値のみ取り出して返却していますが、単純に次のようにしてもよいでしょう。

function update( $new_instance, $old_instance ) {
    return $new_instance;
}

4.widget()

widget()はウィジェットを表示する役割があります。前述のようなフォームデータがある場合、この関数でフォームデータの値を取得し、ウィジェットの表示に反映させます。

function widget( $args, $instance ) {
    extract($args);
    $title = apply_filters('widget_title', empty($instance['title']) ?
                   '&nbsp;' : $instance['title'], $instance, $this->id_base);
    echo $before_widget;
    if ( $title )
        echo $before_title . $title . $after_title;
    echo '<div id="calendar_wrap">';
    get_calendar();
    echo '</div>';
    echo $after_widget;
}

関数の引数$instanceは、form()の引数と同様、フォームデータです。

1行目のextractで、引数$argsの内容を配列にセットします(ここでは使っていない模様)。

extract($args);

2行目でフィルターフックwidget_titleを実行して、フォームのtitleのデータを変数$titleに設定します。

$title = apply_filters('widget_title', empty($instance['title']) ?
                   '&nbsp;' : $instance['title'], $instance, $this->id_base);

残りの処理でカレンダーを表示します。関数get_calendarは外部の関数でカレンダーデータを取得します(ここでは割愛)。

echo $before_widget;
if ( $title )
    echo $before_title . $title . $after_title;
echo '<div id="calendar_wrap">';
get_calendar();
echo '</div>';
echo $after_widget;

$before_widget、$before_title、$after_title、$after_widgetは「WordPress 3のサイドバーにウィジェットを表示するカスタマイズ」の4項にあるregister_sidebarのハッシュキーに相当します。

5.デフォルトウィジェットについて

4項までの説明で、ウィジェットを作るための基本的な仕組みが理解できたと思います。

デフォルトのウィジェットはwp-includes/default-widgets.phpに登録されています。このファイルに書かれている各ウィジェットの処理をトレースしていけば、ウィジェット作成に関する知識をより深めることができるでしょう。

Comments [0] | Trackbacks [0]
2010年12月 8日

WordPress 3のサイドバーにウィジェットを表示するカスタマイズ

December 8,2010 1:55 AM
Tag:[, ]
Permalink

WordPress 3のサイドバーにウィジェットを表示するカスタマイズです。ネタ的にはかなり出遅れてる感じですが、なかなか仕組みが理解できなかったので、WordPressテーマを変更したときの備忘録として残しておきます。

ここでは、ウィジェットが適用されていない2つのサイドバー(sidebar.php/sidebar2.php)にウィジェットを表示する例を説明します。カスタマイズしたいテーマにサイドバーが1つしかない場合、あるいは3つ以上ある場合でも手順はたいして変わりません。

1.sidebar.phpの変更

まず、サイドバー用のテーマファイルsidebar.phpがあるとします。

<ul>
    <li><h2>Search this site</h2><?php include (TEMPLATEPATH . '/searchform.php'); ?></li>
    <li><h2>Archives</h2>
        <ul><?php wp_get_archives('show_post_count=true'); ?></ul>
    </li>
    <li><h2>Categories</h2>
        <ul>
        <?php wp_list_cats('sort_column=name&optioncount=1&hide_empty=1&hierarchical=1'); ?>
        </ul>
    </li>
</ul>

これにウィジェットを表示できるようにするには、一番外側のul要素の開始タグの直後からul要素の終了タグの直前までを以下の2行で括ります。

<?php if ( ! dynamic_sidebar( 'primary-widget-area' ) ) : ?>
…略…
<?php endif; ?>

追加した行にある関数dynamic_sidebarの機能は次の通りです(ここ重要)。

  • 「primary-widget-area」というウィジェットエリアにウィジェットが設定されていれば、括っている内容の代わりに、そのウィジェットを表示する。
  • 「primary-widget-area」というウィジェットエリアにウィジェットが設定されていなければ、括っている内容をそのまま表示する。

以下に、ウィジェットエリアの状態と、対応するサイドバーの表示内容を示します。厳密には画面はsidebar2.phpのものですが、イメージということで。

ウィジェットエリアにウィジェットが設定されている状態

ウィジェットが設定されているときのサイドバー

ウィジェットエリアにウィジェットが設定されていない状態

ウィジェットが設定されていないときのサイドバー(sidebar.phpの内容を表示)

関数dynamic_sidebarの引数「primary-widget-area」という名称は、ウィジェットを表示する位置を特定するもので、任意の名称で構いません。

変更後のsidebar.phpは次のようになります。追加部分を青色で示しています。

<ul>
<?php if ( ! dynamic_sidebar( 'primary-widget-area' ) ) : ?>
    <li><h2>Search this site</h2><?php include (TEMPLATEPATH . '/searchform.php'); ?></li>
    <li><h2>Archives</h2>
        <ul><?php wp_get_archives('show_post_count=true'); ?></ul>
    </li>
    <li><h2>Categories</h2>
        <ul>
        <?php wp_list_cats('sort_column=name&optioncount=1&hide_empty=1&hierarchical=1'); ?>
        </ul>
    </li>
<?php endif; ?>
</ul>

2.sidebar2.phpの変更

サイドバーが複数ある場合も、同様の設定を行います。1項と異なるのは、関数dynamic_sidebarの引数「primary-widget-area」を「secondary-widget-area」にしている点です。

以下は、もうひとつのサイドバー(sidebar2.php)に設定した例です。

<ul>
<?php if ( ! dynamic_sidebar( 'secondary-widget-area' ) ) : ?>
    <li id="calendar"><?php get_calendar(); ?></li>
    <li><h2>Recent Entries</h2>
        <ul><?php get_archives('postbypost', '10','custom' ,'<li>' ,'</li>'); ?></ul>
    </li>
    <li><h2>Recent Comments</h2>
        <ul><?php get_recently_commented(); ?></ul>
    </li>
    <li><h2>Recent Trackbacks</h2>
        <ul><?php get_recently_trackbacked(); ?></ul>
    </li>
<?php endif; ?>
</ul>

つまりサイドバーごとに「primary-widget-area」「secondary-widget-area」の部分の名称を変えれば、いくつでも設定できます。

sidebar.php(sidebar2.php)の設定はこれだ終わりです。

ちなみに、sidebar.phpに記述している中に表示させたいものがあれば、その部分をif文で括らないようにすればOKです。例えば、上のsidebar2.phpでカレンダーだけを常に表示させたい場合は次のようにします。

<ul>
    <li id="calendar"><?php get_calendar(); ?></li>
<?php if ( ! dynamic_sidebar( 'secondary-widget-area' ) ) : ?>
    <li><h2>Recent Entries</h2>
        <ul><?php get_archives('postbypost', '10','custom' ,'<li>' ,'</li>'); ?></ul>
    </li>
    <li><h2>Recent Comments</h2>
        <ul><?php get_recently_commented(); ?></ul>
    </li>
    <li><h2>Recent Trackbacks</h2>
        <ul><?php get_recently_trackbacked(); ?></ul>
    </li>
<?php endif; ?>
</ul>

3.ウィジェットエリアの定義(手抜きをしたい場合)

WordPress 3の場合、1項・2項の設定をおこなって「twentyten」テーマの中にあるfunction.phpを自分のテーマディレクトリにコピーすれば、ウィジェット機能はそのまま使えます。

その場合、dynamic_sidebarの引数「primary-widget-area」「secondary-widget-area」の名称は変更しないでください。また、「twentyten」テーマのfunction.phpには、次の4つのウィジェットエリアが用意されています。

  • First Footer Widget Area
  • Second Footer Widget Area
  • Third Footer Widget Area
  • Fourth Footer Widget Area

「twentyten」テーマのfunction.phpをそのまま使うと、カスタムメニューやカスタム背景なども同時に使えるかもしれません。

4.ウィジェットエリアの定義(自前で作りたい場合)

自前でウィジェットエリアの定義を作るには、自分のテーマディレクトリ配下に空のfunction.phpを作り、次の内容を設定してください。ここでは当ブログで定義しているもの(ほとんどfunction.phpの流用ですが)からウィジェットに関連する部分のみをそのまま掲載しておきます。

<?php
function koikikukan_widgets_init() {
    register_sidebar( array(
        'name' => __( 'Primary Widget Area', 'koikikukan3' ),
        'id' => 'primary-widget-area',
        'description' => __( 'The primary widget area', 'koikikukan3' ),
        'before_widget' => '<li id="%1$s" class="widget-container %2$s">',
        'after_widget' => '</li>',
        'before_title' => '<h2 class="widget-title">',
        'after_title' => '</h2>',
    ) );
    register_sidebar( array(
        'name' => __( 'Secondary Widget Area', 'koikikukan3' ),
        'id' => 'secondary-widget-area',
        'description' => __( 'The secondary widget area', 'koikikukan3' ),
        'before_widget' => '<li id="%1$s" class="widget-container %2$s">',
        'after_widget' => '</li>',
        'before_title' => '<h2 class="widget-title">',
        'after_title' => '</h2>',
    ) );
}
add_action( 'widgets_init', 'koikikukan_widgets_init' );

一番下にあるadd_actionで、ウィジェット管理画面を初期化するフック(widgets_init)を定義し、関数koikikukan_widgets_initを起動します。

add_action( 'widgets_init', 'koikikukan_widgets_init' );

関数koikikukan_widgets_initの中では、関数register_sidebarを2回起動しています。2回起動するのは、サイドバーに追加したdynamic_sidebarに対応させるためです。register_sidebarの引数にあるidの値が1項・2項で定義した「primary-widget-area」「secondary-widget-area」と一致させます。

function koikikukan_widgets_init() {
    register_sidebar( array(
        …中略…
        'id' => 'primary-widget-area',
        …中略…
    ) );
    register_sidebar( array(
        …中略…
        'id' => 'secondary-widget-area',
        …中略…
    ) );
}

関数register_sidebarは、管理画面のウィジェットエリアを作り、そこにドラッグ&ドロップされるウィジェットのテンプレートを定義する機能があります。

register_sidebarの引数に、作りたいウィジェットのスケルトン((X)HTMLマークアップ部分)を定義します。

'name' =&gt; __( 'Secondary Widget Area', 'koikikukan3' ),
'id' =&gt; 'secondary-widget-area',
'description' =&gt; __( 'The secondary widget area', 'koikikukan3' ),
'before_widget' =&gt; '&lt;li id="%1$s" class="widget-container %2$s"&gt;',
'after_widget' =&gt; '&lt;/li&gt;',
'before_title' =&gt; '&lt;h2 class="widget-title"&gt;',
'after_title' =&gt; '&lt;/h2&gt;',

それぞれの意味は次の通りです(公式サイトより)。

  • name - サイドバー(ウィジェットエリア)名
  • id - サイドバー id
  • description - サイドバー(ウィジェットエリア)の説明 (2.9以降)
  • before_widget - ウィジェットの前のテキスト
  • after_widget - ウィジェットの後のテキスト
  • before_title - タイトルの前のテキスト
  • after_title - タイトルの後のテキスト

サンプルではサイドバー名の、

'name' =&gt; __( 'Secondary Widget Area', 'koikikukan3' ),

はローカライズを行っていますが、次のように直接日本語を書いても構いません。その場合はfunction.phpの文字エンコーディングはUTF-8で保存してください。

'name' =&gt; 'ほげほげ',

「カテゴリ」ウィジェットは次のようなマークアップで出力されます。

<li id="categories-2" class="widget-container widget_categories">
  <h2 class="widget-title">カテゴリー</h2>
  <ul>
    <li class="cat-item cat-item-5"><a href="http://.../?cat=5" title="お知らせ に含まれる投稿をすべて表示">お知らせ</a></li>
    <li class="cat-item cat-item-7"><a href="http://.../?cat=7" title="イベント に含まれる投稿をすべて表示">イベント</a></li>
    <li class="cat-item cat-item-4"><a href="http://.../?cat=4" title="エンタメ に含まれる投稿をすべて表示">エンタメ</a></li>
    <li class="cat-item cat-item-36"><a href="http://.../?cat=36" title="ニュース に含まれる投稿をすべて表示">ニュース</a></li>
  </ul>
</li>

以上です。これでデフォルトで用意されているウィジェットが利用できるようになります。ウィジェットを自前で作る方法は「WordPress 3でウィジェットを作るカスタマイズ」で紹介します。

Comments [0] | Trackbacks [0]
2010年12月 7日

WordPressテーマ(WordPress 3.x対応)

December 7,2010 2:55 AM
Tag:[, , ]
Permalink

当ブログで配布中のWordPressテーマをバージョンアップしてWordPress 3.0対応にしました。

WordPressテーマ

1.追加機能

WordPress 3.0対応として、以下の機能を追加しました。

  • ウィジェットに対応します
  • カスタムメニューに対応します
  • カスタム背景画像に対応します

メニュー

ウィジェットはサイドバーのリスト類をドラッグ&ドロップで自由に配置できる機能です。「外観」→「ウィジェット」の画面から直感的に操作できます。

ウィジェット

カスタムメニューは、「外観」→「メニュー」の画面から、カテゴリリストの並び順などを任意の順番に変更できたり、他のメニューをリストに加えることができる機能です。作成したカスタムメニューは、先程のウィジェットに「カスタムメニュー」として表示されます。

カスタムメニュー

カスタム背景画像は、「外観」→「背景」の画面から、任意の背景色を選択したり、背景画像をアップロードして適用することができます。下は背景画像を設定したところです。

背景画像

これだけで背景画像が適用されるようになります。ただしリキッドレイアウトを選択した場合は背景色に「#ffffff」を設定してください。

背景画像が適用

また、テンプレートの構造を見直し、本文エリアがサイドバーの(X)HTMLマークアップより前方になるようにしました。

2.テーマのダウンロード

下記のページよりテーマをダウンロードしてください。

WordPress テーマ(テンプレート)・3カラム版
Comments [12] | Trackbacks [1]
Now loading...
ギターに入った猫
掲載広告募集
Styles
Font Size
Default
For defective color vision
Gray Scale
RGB Color
Search this site

このブログをメールで購読する by:FeedBurner

AMN
Categories
Monthly Archives
2020年
2019年
2018年
2017年
2016年
2015年
2014年
2013年
2012年
2011年
2010年
2009年
2008年
2007年
2006年
2005年
2004年
2003年
BlogPeople
Syndicate this site
FeedBurner(RSS1.0/RSS2.0/Atom)
Counter
これまでのアクセス
Powered by
Movable Type 6.0.3