【メモ】WordPress, テーマ内のJavaScriptをwp_enqueue_scriptに追加

テーマ内に置いたJavaScriptファイルをwp_enqueue_scriptで呼び出せるように設定する。

functions.php

function js_enque_method() {
   wp_register_script('example_script',get_bloginfo('template_url').'/js/example.js','jQuery','1.0');
   wp_enqueue_script('example_script');
}
add_action('wp_enqueue_scripts', 'js_enque_method');

テーマ内に[js]フォルダを作り、そのフォルダ内に[example.js]があります。
example.jsのVersionは1.0です。
example.jsはjQueryを必要とします。

WordPress, ループをカスタマイズする3つの方法

WordPressでループをカスタマイズするメモ。

query_posts()
http://wpdocs.sourceforge.jp/テンプレートタグ/query_posts

global $query_string;
// 全投稿出力
$posts = query_posts($query_string.'&posts_per_page=-1');
 
if (have_posts()) : while (have_posts()) : the_post();
   // ループ処理
   endwhile;
else;
   // not found
endif;
 
// ループをリセット
wp_reset_query();

オリジナルのループを元にカスタマイズしたい時に使用する。
wp_reset_queryを最後に実行する。

WP_Query()
http://wpdocs.sourceforge.jp/関数リファレンス/WP_Query

$args = array(
   'post_type'=>'page',
   'post__in' => array('595', '33', 44)
);
$query = new WP_Query($args);
 
while($query->have_posts()) : $query->the_post();
   // ループ処理
endwhile;
 
// queryをリセット
wp_reset_postdata();

オリジナルのループを作成、複数のループを作成。
wp_reset_postdataを最後に実行する。

get_posts
http://wpdocs.sourceforge.jp/テンプレートタグ/get_posts

$myposts = get_posts('posts_per_page=5&offset=1&category=1');
foreach($myposts as $post) :
   setup_postdata($post);
   // ループ処理
endforeach;

リセットはいらない。
引数は配列。

WordPress 3, sidebar.phpが無い時のget_sidebar

default テーマが添付されなくなった WordPress 3.0。

get_sidebar を実行した時に…
WordPress 3.0 以前では使用しているテーマに sidebar.php が無かったら default テーマの sidebar.php が使用されていました。

default テーマが無くなると、どうなるんだろうと思ったのですが抜かり無く代替え策が考えられていました。

sidebar.php が無いときは、
wp-includes/theme-compat/sidebar.php が使われます。

theme-compat には他に

comments-popup.php
comments.php
footer.php
header.php

が用意されています。

ただファイルのコメントに次のように書かれていたので、一時的な処置のようです。
ちゃんとテーマに footer.php, header.php, sidebar.php などは用意しておいた方が良さそうです。

This file is here for Backwards compatibility with old themes and will be removed in a future version

WordPress, Useragentなグローバル変数

WordPressはUseragentに関するグローバル変数を持っています。

$is_lynx
$is_gecko
$is_IE
$is_winIE
$is_macIE
$is_opera
$is_NS4
$is_safari
$is_chrome
$is_iphone

ブラウザーに合わせた設定を加えたい時とかに便利です。
もとネタ、
10 useful new WordPress hacks
Detect the visitor browser within WordPress

さらにもとネタ
Browser Detection and the body_class() Function

add_filter('body_class','browser_body_class');
function browser_body_class($classes) {
	global $is_lynx, $is_gecko, $is_IE, $is_opera, $is_NS4, $is_safari, $is_chrome, $is_iphone;
 
	if($is_lynx) $classes[] = 'lynx';
	elseif($is_gecko) $classes[] = 'gecko';
	elseif($is_opera) $classes[] = 'opera';
	elseif($is_NS4) $classes[] = 'ns4';
	elseif($is_safari) $classes[] = 'safari';
	elseif($is_chrome) $classes[] = 'chrome';
	elseif($is_IE) $classes[] = 'ie';
	else $classes[] = 'unknown';
 
	if($is_iphone) $classes[] = 'iphone';
	return $classes;
}

body_classの出力するクラスへUseragentを入れとこうぜ、な関数ですよね。

/wp-includes/ -> vars.php (source)

WordPress, 親テーマfunctions.phpのaction, filterを子テーマでremove

WordPress3.0から使える親テーマ機能。
便利なんだけど、親テーマのfunctions.phpで設定されているactionやfilterを子テーマでremoveする方法が分からず悶々としてたけど、ようやく方法が分かりました。

本家Forum : [resolved] can i create child functions.php file for twentyten?
http://wordpress.org/support/topic/can-i-create-child-functionsphp-file-for-twentyten?replies=26

Adeptris さんによれば
after_setup_themeを使えば良いらしい。

/** Tell WordPress to run child_theme_setup()
when the 'after_setup_theme' hook is run.
*/
add_action( 'after_setup_theme', 'child_theme_setup' );
 
/** This function will hold our new calls and over-rides */
if ( !function_exists( 'child_theme_setup' ) ):
function child_theme_setup() {
 
}
endif;

関数 child_theme_setup にremoveを書けば対応できました。
感謝感謝です。

WordPress, 子テーマのための親テーマ作成の心構え – functions.php その2

親テーマ functions.php に add_filter されている関数を子テーマで変更することは困難を極めます。

読み込む順序が
1.子テーマ functions.php
2.親テーマ functions.php
になるからです。

これだと、いくら子テーマ functions.php で remove_filter しても意味がありません。
理論的には何らかの hook を使い最後の最後に remove_filter することは可能かもしれませんが、ワンクリック・インストールのWordPressらしくない解決方法に思えます。

親テーマの functions.php の関数は 全て functions_exists 判定 を入れることを必須条件にしてもらいたいものです。
そうすれば、子テーマでの変更はあっけないほど簡単にできます。
同名の関数を書けば良いだけですから。

Twenty Ten も一部の関数にしか判定が入っておらず不満が残ります。
というか、3.0対応テーマ作成の見本となるべきテーマなので早急に改善して欲しいです。

子テーマの子、孫テーマもありかな。

そうなると、配布テーマの functions.php の関数も 全て functions_exists 判定 が必須ですね。

update 2010-09-22
子テーマでremoveする方法があるので functions_exists が必須という訳では無さそうです。
でも、用意してくれてるとかなり嬉しい。

WordPress, 親テーマfunctions.phpのaction, filterを子テーマでremove

WordPress, wp_nav_menuのbefore, after と link_before, link_after

wp_nav_menuのbefore, after と link_before, link_after 用法が誤解を生みそうな件。

$before
(文字列) (オプション) リンクテキストの前のテキスト
初期値: なし

$after
(文字列) (オプション) リンクテキストの後のテキスト
初期値: なし

$link_before
(文字列) (オプション) リンクの前のテキスト
初期値: なし

$link_after
(文字列) (オプション) リンクの後のテキスト
初期値: なし

before と link_before の説明がどうもすっきりしない。

Usage:

<?php wp_nav_menu( array(
    'link_before' => '<span class="link_before">', 'link_after' => '</span>', 
    'before' => '<span class="before">', 'link_after' => '</span>', 
    'theme_location' => 'primary', 'depth' => '1' )
 );

Output:

<div class="menu">
    <ul>
        <li>
            <span class="before">
                <a href="/"><span class="link_before">Home</span></a>
            </span>
        </li>
    </ul>
</div>

出力結果をみても逆な気がしてしょうがない。

WordPress, wp_nav_menu+カスタムメニューのCSS設定

wp_nav_menu+カスタムメニューがナビゲーション・メニューを作るのに便利なことが分かってきた。
前回のPost : WordPress 3.x, wp_nav_menu コードを追ってみた

.menu の位置が状況によって変わるのでCSSの設定には注意が必要です。

Twentyten では次のように使われています。
header.php

wp_nav_menu( array( 'container_class' => 'menu-header', 'theme_location' => 'primary' ) );

この時のHTML出力は以下のようになります。

カスタムメニューを使用しない場合

Output(1行で出力されているのをインデントを付けています)

<div class="menu">
    <ul>
        <li >
            <a href="http://me.beginsprite.com/" title="ホーム">ホーム</a>
        </li>
    </ul>
</div>

menu オプションを指定していないので、ulwrap する div には class='menu' が設定されます。

Twentyten はデフォルトのページメニューを使用する場合 functions.php で 「ホーム」へのリンクを出力するように設定されています。

function twentyten_page_menu_args( $args ) {
	$args['show_home'] = true;
	return $args;
}
add_filter( 'wp_page_menu_args', 'twentyten_page_menu_args' );

カスタムメニューを設定した場合

<div class="menu-header">
    <ul id="menu-カスタムメニュー名" class="menu">
        <li >
            <a href="http://me.beginsprite.com/" title="ホーム">ホーム</a>
        </li>
    </ul>
</div>

class='menu' の位置が「カスタムメニュー」を使うと container タグ内 ul タグに設定されます。

配布テーマを作成する時は CSS 設定に充分な注意と配慮が必要になるでしょう。

WordPress 3.x, wp_nav_menu コードを追ってみた

WordPress 3.0 から追加された wp_nav_menu のコードを追ったオレメモ。
多分「カスタムメニュー」に関係あるはず。

WordPress.com 日本語ブログ : 新カスタムメニュー機能 (など)
WordPress.com Support : Menus

Function Reference/wp nav menu
trac : nav-menu-template.php

$defaults = array(
'menu'            => ,
'container'       => 'div',
'container_class' => ,
'container_id'    => ,
'menu_class'      => 'menu',
'menu_id'         => ,
'echo'            => true,
'fallback_cb'     => 'wp_page_menu',
'before'          => ,
'after'           => ,
'link_before'     => ,
'link_after'      => ,
'depth'           = 0,
'walker'          => ,
'theme_location'  => );

wp_nav_menufallback_cb の設定をしない時は wp_page_menu を使って出力するので Parameter は wp_page_menu の Parameter を追加して設定できます。

fallback_cb => wp_page_menu のデフォルト時は wp_nav_menu の Parameter で次のものは設定しても無視されるようです。
container_class, container_id, before, after, link_before, link_after, menu_id.

wp_nav_menu は「カスタムメニュー」を使用しない時は wp_page_menu を出力します。
このとき出力される ul タグを container オプションのデフォルト div でwrapします。
この div には menu_class オプションのデフォルト class='menu' が設定されます。
menu_class オプションは wp_page_menu を使っているときでも設定可能です。
複数のクラスを設定したい時は半角スペースを使い設定します。
Usage :
'menu_class' => 'menu main-menu navigation'

theme_location が重要なようですが、さてこれは何を指定すれば良いのでしょう?
コードを追っていくと

// nav-menu.php
function get_nav_menu_locations() {
	return get_theme_mod( 'nav_menu_locations' );
}
 
// theme.php
function get_theme_mod($name, $default = false) {
	$theme = get_current_theme();
 
	$mods = get_option( "mods_$theme" );
 
	if ( isset($mods[$name]) )
		return apply_filters( "theme_mod_$name", $mods[$name] );
 
	return apply_filters( "theme_mod_$name", sprintf($default, get_template_directory_uri(), get_stylesheet_directory_uri()) );
}

ということはこんな感じかなぁ。

apply_filters(theme_mod_nav_menu_locations, $mods['nav_menu_locations']);

で、何をやってるのかは???
おしえて、わかる人。

update

2010-08-25

コードの意味は良くわかりませんが、、、
カスタムメニューで登録したメニューをデフォルト設定にした時、”primary” にすることで wp_nav_menu で出力できるようです。

“primary” のほかにどんな設定値があるのかは以前不明です。

wp_nav_menumenu オプションを設定すると「カスタムメニュー」で登録したメニューを呼び出せます。
カスタムメニューを使うとタイトルへのリンクをパーマリンクを変更せずに名称を変更できます。

カスタムメニューはページ、カテゴリー、タグなどを混在させたメニューを簡単に作成できます。
テンプレート・タグを駆使してグローバル・ナビゲーションを作成したことのある方にはありがたい機能です。

Usage:

 'menu-header',
    'menu' => 'gnavi',
    'container_id' => 'menu-main-menu',
    'menu_class' => 'inazumatv-menu inazumatv',
    'link_before' => '<span>', 'link_after' => '</span>',
    'menu_id' => "menu-main-menu-nav",
    'theme_location' =>; 'primary', 'depth' => '1' )
 );

Output:

<div id="menu-main-menu" class="menu-header">
<ul id="menu-main-menu-nav" class="inazumatv-menu inazumatv">
	<li id="menu-item-ID" class="menu-item menu-item-type-custom current-menu-item current_page_item menu-item-home menu-item-ID">
            <a href="/"><span>Home</span></a></li>
	<li id="menu-item-ID2" class="menu-item menu-item-type-post_type menu-item-ID2">
            <a href="URL"><span>Title</span></a></li>
</ul>
</div>

外観 -> メニュー
で “gnavi” という名称のカスタムメニューを登録しています。

これはかなり便利そうです。
カスタムメニューは複数登録できそうなので、これからメニューを作る時は「カスタムメニュー」+ wp_nav_menu の組み合わせがステキです。

update 2010-08-25
タグに関してはカスタムリンクを使えばメニューに加えることも可能ですが、他と比べて「簡単に」ではないので削除しました。

WordPress 3.0のTwenty Tenのループ出力, loop.phpとget_template_part

Twenty Tenのループ出力は loop.php に集約されて書かれていて、loop.php を呼び出す部分は 3.0 から登場した関数 get_template_part が使われています。

関数リファレンス/get template part
Function Reference/get template part

使い方

<?php get_template_part( $slug, $name ) ?>

[編集] パラメータ
$slug
(文字列) (必須) 一般テンプレートのスラッグ名
初期値: なし
$name
(文字列) (オプション) 特定テンプレートの名前
初期値: なし

用例

[編集] 子テーマで loop.php を使用する
テーマフォルダが wp-content/themes で、親テーマが twentyten で、子テーマが twentytenchild の場合、この例はファイルを順に PHP require() します。

  1. wp-content/themes/twentytenchild/loop-index.php
  2. wp-content/themes/twentytenchild/loop.php
  3. wp-content/themes/twentyten/loop-index.php
  4. wp-content/themes/twentyten/loop.php
<?php get_template_part( 'loop', 'index' ); ?>

用例を見ると、関数 get_template_part は今まで include, require としていた部分を置き換えてくれるようです。

index.php には以下のように書かれています。

<?php
/* Run the loop to output the posts.
 * If you want to overload this in a child theme then include a file
 * called loop-index.php and that will be used instead.
 */
 get_template_part( 'loop', 'index' );
?>

子テーマでカスタマイズしたいときは、loop-index.php を子テーマに作れば良いってことになります。
これってかなり便利そうな気がする。

これからはテーマで include, require が書いてあるとイケテないってことになりますね。

get_template_part は関数 locate_template を使い最後は関数 load_template でロードすべきファイルを require_once します。

general-template.php

// @since 3.0.0
function get_template_part( $slug, $name = null ) {
	do_action( "get_template_part_{$slug}", $slug, $name );
 
	$templates = array();
	if ( isset($name) )
		$templates[] = "{$slug}-{$name}.php";
 
	$templates[] = "{$slug}.php";
 
	locate_template($templates, true, false);
}

theme.php

// @since 2.7.0
function locate_template($template_names, $load = false, $require_once = true ) {
	if ( !is_array($template_names) )
		return '';
 
	$located = '';
	foreach ( $template_names as $template_name ) {
		if ( !$template_name )
			continue;
		if ( file_exists(STYLESHEETPATH . '/' . $template_name)) {
			$located = STYLESHEETPATH . '/' . $template_name;
			break;
		} else if ( file_exists(TEMPLATEPATH . '/' . $template_name) ) {
			$located = TEMPLATEPATH . '/' . $template_name;
			break;
		}
	}
 
	if ( $load && '' != $located )
		load_template( $located, $require_once );
 
	return $located;
}
 
// @since 1.5.0
function load_template( $_template_file, $require_once = true ) {
	global $posts, $post, $wp_did_header, $wp_did_template_redirect, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID;
 
	if ( is_array( $wp_query->query_vars ) )
		extract( $wp_query->query_vars, EXTR_SKIP );
 
	if ( $require_once )
		require_once( $_template_file );
	else
		require( $_template_file );
}

よくわかんないのは get_template_partdo_action のとこ。
do_action( "get_template_part_{$slug}", $slug, $name ); だと引数3つだけど・・・

plugin.php

function do_action($tag, $arg = '')

だから3つ目は無視されるよね。
どういうことなんでしょう?
あと、なんのための do_action なのかなぁ。