WordPress Logo WordPress functions.php

更新日:2024年09月27日

作成日:2019年02月02日

functions.php はテーマに機能を追加するテンプレートファイルの1つで、テーマで使う関数(ファイルの読み込みや機能)などを記述します。以下は functions.php の記述上の注意点やテーマの作成時に記述するよく使う設定などに関する覚書です。

functions.php ファイル

テーマを作成する際に使用するファイルの1つ functions.php は、機能に関する設定を記述するテーマファイルで、テーマと一緒に wp-content/themes のテーマ用ディレクトリに配置します。

場所:インストールディレクトリ / wp-content / themes / テーマフォルダ / functions.php

以下は、WordPress の公式テーマ「Twenty Nineteen」の例です。

functions.php はエディタでファイルを直接開いて編集することができます。

また、管理画面(「外観」→「テーマの編集」→「テーマのための関数」)からもアクセス及び編集することができます。

functions.php の特徴

functions.php は、以下のような特徴があります。

  • テーマと一緒に wp-content/themes のテーマ用ディレクトリーへ配置します。
  • 現在有効なテーマのディレクトリーにあるときのみ実行され、そのテーマに対してのみ機能します。
  • ダッシュボード(編集画面のページなど)やテンプレート(公開ページ)の表示に先立って読み込まれて実行されます。
  • PHP の関数や WordPress 組み込みの関数を呼び出したり、テーマで使う独自の関数を定義することができます。
  • functions.php で定義した変数はグローバル変数になり、テンプレートで利用できます。
  • テーマのテンプレートより先に読み込まれるので、テーマの初期化の処理が行えます。
  • WordPress の機能を変更するアクションやフィルターの定義を行うことができます。

参考サイト:

記述上の注意点

functions.php に記述する際に注意する点について。

直接何かを出力しない

functions.php はテンプレート(公開ページのファイル)より先に読み込まれるので、以下のような直接何かを出力するような記述はしません。

//functions.php
echo "Hello!";

上記のように記述してしまうと、HTML の <!DOCTYPE html> より前に "Hello!" が出力されてしまい、HTML の出力は以下のようになってしまいます。

Hello!<!DOCTYPE html>
<html lang="ja">
<head>

ページに値を出力する場合は、関数を作成してその関数をページ(テンプレート)で実行します。

//functions.php
function my_echo() {
  echo "Hello!";
}   
//テンプレート(index.php など)で実行
<p><?php my_echo(); ?></p>
一度 PHP を終了させて出力

以下は少し特殊な記述例です。一度 PHP を終了させて出力していますが、実際に出力されるのはアクションフックによる関数の実行時なので、この場合は問題ありません。

内容的には、add_action() を使って add_google_analytics() と言う関数を wp_head アクションにフックしています。

4行目で一度 PHP を終了させて、5行目~13行目をこの関数の実行時に出力させています。

add_action('wp_head','add_google_analytics');
function add_google_analytics() {
  if( !is_user_logged_in() ) {
  ?>
  <script>
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
    ga('create', 'UA-xxxxxxxxxxx', 'xxxxxx.com');
    ga('require', 'displayfeatures');
    ga('send', 'pageview');
  </script>
  <?php
  }
}

関連ページ:「一度 PHP を終了させて出力

function_exists()

functions.php には独自の関数を定義することができ、定義した関数はテンプレートファイルで呼び出すことができます。

但し、関数を子テーマでオーバーライド(上書き)できるようにするには、以下のように function_exists() を使って関数を定義します。

if ( ! function_exists( 'my_function' ) ) {
  //my_function が定義されていない場合は my_function を定義
  function my_function() {
    // 処理
  }
}

上記のように記述しておくと、親テーマで定義されている関数を子テーマ側でオーバーライド(上書き)しようと同じ関数を書いても「既にその関数は定義済み」と言うエラーにならないで済みます。

function_exists() は指定した関数が既に定義されているかを調べることができる PHP の関数です。

PHP の組み込み関数やユーザーが定義した関数の中から、引数で指定した名前の関数を探して、もし既にその関数が存在すれば true を返し、存在しなければ false を返します(但し、この関数は、include_once や echo のような言語構造については false を返します)。

function_exists() の使い道

例えばプラグインをインストールして、そのプラグインの関数をテーマに記述する場合に、function_exists() を使えば、もしそのプラグインをアンインストールした場合に「その関数は定義されていません」と言うエラーを回避することができます。

if ( function_exists( 'plugin_function' ) ) {
  //plugin_function が定義されている場合は実行
  plugin_function();
}

以下のように記述すれば、その関数が存在しなければテンプレートに div 要素も出力しないようにすることもできます。

<?php if( function_exists('my_plugin_func') ): ?>
  <div class="plugin">
    <?php my_plugin_func(); ?>
  </div>
<?php endif; ?>

変数の定義

テンプレートファイルで使用する値などを、functions.php に変数で定義しておくことができます。

functions.php に直接定義する変数はグローバル変数になります。このため、変数を定義する際は、接頭辞を付けるなどして WordPress やプラグインの変数と重複しないように注意する必要があります。

定義した変数は、グローバル変数としてテンプレートファイル内で使用することができます。

functions.php
$my_bg_color = "#999";
テンプレートファイル(index.php など)
<div style="background: <?php echo $my_bg_color; ?>">...</div>

但し、header.php や footer.php などのテンプレートパーツは、インクルードタグ内部の load_template() 関数内で読み込まれているため、index.php などのテンプレートとはスコープが異なります。

そのためテンプレートパーツで使用するには、global 宣言を行う必要があります。

テンプレートパーツ(header.php など)
<div style="background: <?php global $my_bg_color; echo $my_bg_color; ?>">...</div>

但し、グローバル変数は多用するとソースコードが読みにくくなりバグの原因ともなるので、できるだけ利用しない方が良いとされています(関連項目:変数の有効範囲(スコープ))。

別ファイルの読み込み

functions.php に独自の関数や機能を色々と記述していくと、何がどこに書いてあるのかが判らず管理が大変になってくることがあります。

そのような場合は、関数やファイルの読み込みなど機能ごとにファイルを分離してそれぞれを functions.php に読み込むようにすると管理しやすくなります。

以下はテーマフォルダ内に「inc」というフォルダを作成して、その中に機能別のファイル(以下の例では scripts.php)を配置して functions.php で読み込む場合の例です。

ファイルの読み込みには、PHP の require_once を使用して、読み込むファイルのパスを指定します。

require_once get_template_directory() . '/inc/scripts.php';

//または、require を使用
require get_template_directory() . '/inc/scripts.php';

以下は公式テーマ「twentynineteen」の functions.php の例です。

/** SVG Icons class. */
require get_template_directory() . '/classes/class-twentynineteen-svg-icons.php';

/** Custom Comment Walker template. */
require get_template_directory() . '/classes/class-twentynineteen-walker-comment.php';

/** Enhance the theme by hooking into WordPress. */
require get_template_directory() . '/inc/template-functions.php';

/** SVG Icons related functions. */
require get_template_directory() . '/inc/icon-functions.php';

/** Custom template tags for the theme. */
require get_template_directory() . '/inc/template-tags.php';

/** Customizer additions. */
require get_template_directory() . '/inc/customizer.php';

または、get_template_part() を使って以下のようにして読み込むこともできますが、この場合、読み込まれた側のファイルで呼び出し元の functions.php で定義された変数を参照することができないので注意が必要です(テンプレートパーツで変数を参照)。

また、get_template_part() を使う場合は、ファイルの拡張子は記述しません。

get_template_part('/inc/scripts');

テーマの作成時に記述する設定

テーマを作成する際に良く使う functions.php に記述する設定項目や関数などについて。

ツールバーの非表示

ツールバーの表示・非表示の設定はユーザーごとにログインして「サイトを見るときにツールバーを表示する」で設定できますが、全てのユーザーで非表示にするには functions.php に以下を記述します。

show_admin_bar フィルターフックを使用して __return_false は false を返す関数です。

add_filter('show_admin_bar', '__return_false');

または show_admin_bar() を使って以下を functions.php に記述しても非表示にできます。

のパラメータには 真偽値(true または false)を指定して表示・非表示を設定することができます。

show_admin_bar( false );

以下はユーザーが「manage_options」の権限を持っていない場合はツールバーを非表示にする例です。

if ( ! current_user_can( 'manage_options' ) ) {
    show_admin_bar( false );
}

関連ページ:edit_post_link()(編集用リンクの出力)

フック

必要に応じてフック(アクションフックやフィルターフック)を記述します。

同じフックを利用する場合は、まとめて記述しておくと管理がしやすくなります。

例えば、after_setup_theme アクションフックを使用する関数には以下のようなものがあります。

after_setup_theme は有効なテーマの functions.php ファイルが読み込まれた直後に実行され、通常、テーマ設定やオプションを初期化するために使われるアクションフックです。

Codex: after_setup_theme

これらは、以下のようにまとめて記述すると管理しやすくなると思います。(但し、同じアクションでも priority が異なれば別にする必要があります。)

function my_theme_setup() {
  add_theme_support( 'title-tag' );
  add_theme_support( 'html5', array( 'search-form', 'gallery', 'caption' ) );
  add_theme_support( 'post-thumbnails' );
  add_image_size('vertical', 275, 413);
  add_image_size('horizontal', 550, 366);
  add_editor_style('editor-style.css');
  register_nav_menus( array(
    'global' => 'Global Menu',
    'footer'  => 'Footer Menu',
  ) );
}
add_action( 'after_setup_theme', 'my_theme_setup' );

add_theme_support などの関数はアクションフックを使用しなくても動作しますが、アクションフックを使って適切なタイミングで実行しないと動作しない関数もあります。

以下は公式テーマ Twenty Nineteen の例です。

if ( ! function_exists( 'twentynineteen_setup' ) ) :
  function twentynineteen_setup() {
    load_theme_textdomain( 'twentynineteen', get_template_directory() . '/languages' );
    add_theme_support( 'title-tag' );
    add_theme_support( 'post-thumbnails' );
    set_post_thumbnail_size( 1568, 9999 );
    register_nav_menus(
      array(
        'menu-1' => __( 'Primary', 'twentynineteen' ),
        'footer' => __( 'Footer Menu', 'twentynineteen' ),
        'social' => __( 'Social Links Menu', 'twentynineteen' ),
      )
    );
    add_theme_support(
      'html5',
      array(
        'search-form',
        'comment-form',
        'comment-list',
        'gallery',
        'caption',
      )
    );
    add_theme_support(
      'custom-logo',
      array(
        'height'      => 190,
        'width'       => 190,
        'flex-width'  => false,
        'flex-height' => false,
      )
    );
    add_theme_support( 'customize-selective-refresh-widgets' );
    add_theme_support( 'wp-block-styles' );
    add_theme_support( 'align-wide' );
    add_theme_support( 'editor-styles' );
    add_editor_style( 'style-editor.css' );
    add_theme_support(
      'editor-font-sizes',
      array(
        array(
          'name'      => __( 'Small', 'twentynineteen' ),
          'shortName' => __( 'S', 'twentynineteen' ),
          'size'      => 19.5,
          'slug'      => 'small',
        ),
        array(
          'name'      => __( 'Normal', 'twentynineteen' ),
          'shortName' => __( 'M', 'twentynineteen' ),
          'size'      => 22,
          'slug'      => 'normal',
        ),
        array(
          'name'      => __( 'Large', 'twentynineteen' ),
          'shortName' => __( 'L', 'twentynineteen' ),
          'size'      => 36.5,
          'slug'      => 'large',
        ),
        array(
          'name'      => __( 'Huge', 'twentynineteen' ),
          'shortName' => __( 'XL', 'twentynineteen' ),
          'size'      => 49.5,
          'slug'      => 'huge',
        ),
      )
    );

    $default_hue     = twentynineteen_get_default_hue();
    $saturation      = apply_filters( 'twentynineteen_custom_colors_saturation', 100 );
    $lightness       = apply_filters( 'twentynineteen_custom_colors_lightness', 33 );
    $lightness_hover = apply_filters( 'twentynineteen_custom_colors_lightness_hover', 23 );
    add_theme_support(
      'editor-color-palette',
      array(
        array(
          'name'  => __( 'Primary', 'twentynineteen' ),
          'slug'  => 'primary',
          'color' => twentynineteen_hsl_hex( 'default' === get_theme_mod( 'primary_color' ) ? $default_hue : get_theme_mod( 'primary_color_hue', $default_hue ), $saturation, $lightness ),
        ),
        array(
          'name'  => __( 'Secondary', 'twentynineteen' ),
          'slug'  => 'secondary',
          'color' => twentynineteen_hsl_hex( 'default' === get_theme_mod( 'primary_color' ) ? $default_hue : get_theme_mod( 'primary_color_hue', $default_hue ), $saturation, 23 ),
        ),
        array(
          'name'  => __( 'Dark Gray', 'twentynineteen' ),
          'slug'  => 'dark-gray',
          'color' => '#111',
        ),
        array(
          'name'  => __( 'Light Gray', 'twentynineteen' ),
          'slug'  => 'light-gray',
          'color' => '#767676',
        ),
        array(
          'name'  => __( 'White', 'twentynineteen' ),
          'slug'  => 'white',
          'color' => '#FFF',
        ),
      )
    );
    add_theme_support( 'responsive-embeds' );
  }
endif;
add_action( 'after_setup_theme', 'twentynineteen_setup' );

function twentynineteen_widgets_init() {
  register_sidebar(
    array(
      'name'          => __( 'Footer', 'twentynineteen' ),
      'id'            => 'sidebar-1',
      'description'   => __( 'Add widgets here to appear in your footer.', 'twentynineteen' ),
      'before_widget' => '<section id="%1$s" class="widget %2$s">',
      'after_widget'  => '</section>',
      'before_title'  => '<h2 class="widget-title">',
      'after_title'   => '</h2>',
    )
  );
}
add_action( 'widgets_init', 'twentynineteen_widgets_init' );

以下はフィルターフックの関連項目へのリンクです。

template_redirect

template_redirect アクションフックは /wp-includes/template-loader.php に記述されていて、どのテンプレートを読み込むかを決定する直前(ページを表示する直前)に実行されます。

template_redirect アクションフックが実行されるタイミングでは、既にリクエストされた URL から投稿のデータを取得しています。

そのため template_redirect アクション関数内では以下のようなことが可能です(フック名に redirect が付いていますが、必ずしもリダイレクトをする必要はありません)。

  • 条件分岐タグを使ってページの種類によって処理を振り分ける
  • get_queried_object() を使ってそのページの投稿オブジェクトを参照する
  • まだレスポンス(ヘッダー)を返していないので、 wp_redirect()wp_safe_redirect() などを使って任意の URL にリダイレクトする

例えば、以下のような template_redirect アクションを記述すれば、それぞれのテンプレートファイルに表示前の処理のコードを記述する必要がなくなります。

function my_template_redirect() {
  if ( is_front_page() ) {
    // フロントページが表示される前に行う処理
  } elseif ( is_home() ) {
    // ブログメインページが表示される前に行う処理
  } elseif ( is_category() ) {
    // カテゴリーアーカイブページが表示される前に行う処理
  } elseif ( is_single() ) {
    // 投稿ページが表示される前に行う処理
  } elseif ( is_page() ) {
    // 固定ページが表示される前に行う処理
  } else {
    // それ以外のページが表示される前に行う処理
  }
}
add_action( 'template_redirect', 'my_template_redirect' );

参考サイト:ページを表示する直前の前処理にtemplate_redirectアクションを

以下は、「secret」と言うページを訪れた際にログインしていない場合は「signup」と言うページにリダイレクトする例です。

リダイレクトした場合は die() または exit() を使ってこれ以上 template_redirect を実行させないようにします。

function my_secret_page_template_redirect() {
  if( is_page( 'secret' ) && ! is_user_logged_in() )
  {
    wp_redirect( home_url( '/signup/' ) );
    die; //これ以上 template_redirect を実行させない
  }
}
add_action( 'template_redirect', 'my_secret_page_template_redirect' );

add_theme_support

add_theme_support() は WordPress で用意されている特定の機能をテーマで使用できるように有効化する関数で、functions.php に記述します。

以下はこの関数の概要です。

add_theme_support( $feature, $args );

パラメータ
  • $feature (string):(必須) 追加する機能の名前
  • $args (mixed):それぞれの機能に指定するオプションで、機能ごとに異なります。

第一引数の $feature で指定できる機能には以下のようなものがあります。

  • 'post-formats'
  • 'post-thumbnails'
  • 'html5'
  • 'custom-logo'
  • 'custom-header-uploads'
  • 'custom-header'
  • 'custom-background'
  • 'menus'
  • 'title-tag'
  • 'starter-content'
  • 'responsive-embeds'
  • 'widgets'
  • 'wp-block-styles'(以下 Gutenberg エディタ関連)
  • 'align-wide'
  • 'editor-color-palette'
  • 'editor-font-sizes'
  • その他(バージョンアップされると追加されていきます)
戻り値
失敗した場合は false。それ以外はなし。

add_theme_support() は アクションフックを使わなくても動作しますが、アクションフックを使って記述する場合は、after_setup_theme フックを使います。

function my_theme_setup() {
   add_theme_support( $feature, $args );
}
add_action( 'after_setup_theme', 'my_theme_setup');

複数指定する場合は、まとめてアクションフックを使って記述するとわかりやすくなります。

function my_theme_setup() {
  add_theme_support( 'post-thumbnails' );
  add_theme_support( 'title-tag' );
  add_theme_support( 'html5', array(
    'comment-form',
    'comment-list',
    'gallery',
    'caption',
  ) );
}
add_action( 'after_setup_theme', 'my_theme_setup' );

title タグの出力

WordPress4.1 から title タグは head 要素内に記述しなくても、functions.php に以下のように add_theme_support() を使って記述すれば、WordPress がページ種類に応じて title タグを自動的に挿入してくれるようになりました。

※テンプレートの head 要素内に title タグは記述しません(記述すると二重に出力されてしまいます)。

add_theme_support( 'title-tag' );

アクションフックを使わなくても動作しますが、アクションフックを使って記述する場合は、after_setup_theme フックを使います。

function my_theme_setup() {
   add_theme_support( 'title-tag' );
}
add_action( 'after_setup_theme', 'my_theme_setup');

詳細は「WordPress title タグの出力」を参照ください。

HTML5 のマークアップを適用

add_theme_support() を使って、WordPress が出力する検索やコメントのフォーム、コメントのリスト、ギャラリーやキャプションに HTML5 のマークアップを適用させることができます。

Codex 日本語版:テーママークアップ
Codex:Theme Markup

add_theme_support() の第1パラメータに 'html5' を指定して、第2パラメータ(必須)に HTML5 のマークアップを適用させる項目(以下)を配列で指定します。

  • 'search-form'
  • 'comment-form'
  • 'comment-list'
  • 'gallery'
  • 'caption'
  • 'script'(5.3 で追加)
  • 'style'(5.3 で追加)

例えば、テーマに searchform.php ファイルがない場合は WordPress デフォルトの検索フォームが読み込まれますが、その際に HTML5 でマークアップされた検索フォームを表示させるには以下のように記述します。

add_theme_support( 'html5', array( 'search-form' ) );

version 5.3 から 'script''style' が追加されました。(Miscellaneous Developer Focused Changes in 5.3

これらを指定することで、HTML5 では不要な script や style 要素の type 属性を出力しないようにすることができます。

script や style 要素に type 属性が指定されていると、W3C の構文チェック(Markup Validation Service)https://validator.w3.org/ では「The type attribute is unnecessary for JavaScript resources」のような警告(Warning)が表示されます。

そのため、5.3 以前では template_redirect フックなどを使って type 属性を削除する必要がありましたが、その必要がなくなりました。

以下のように記述することで、script や style 要素の type 属性を出力しないようにすることができます。

add_theme_support( 'html5', array( 'script', 'style' ) );

以下のように type 属性が出力されません。

<script src='https://example.com/js/plugins.js?ver=1577426774'></script>

以下は全てを指定する場合の例です。

add_theme_support( 'html5', array( /* HTML5 のタグを使って出力させるものを指定 */
  'search-form',
  'comment-form',
  'comment-list',
  'gallery',
  'caption',
  'script',
  'style',
) );

キャプションはこの指定をしなくても figure 要素を使って出力されるようです(?)。

ブロックベースのウィジェットを無効化

WordPress 5.8 から導入されたブロックベースのウィジェットを無効化するには remove_theme_support() を使って以下のように記述することができます。

以下では after_setup_theme フックを使っています。その他の add_theme_support() などとまとめて記述できます。

function my_theme_setup() {
  remove_theme_support( 'widgets-block-editor' );
}
add_action( 'after_setup_theme', 'my_theme_setup' );

head 内のタグを削除

WordPress では、wp_head() により head 内に様々なタグが出力されます。サイトの要件により異なると思いますが、確実に不要と判断できるものは remove_action()add_filter() を使って削除することができます。

// 絵文字を使うためのスクリプトとスタイルを出力しない
remove_action('wp_head', 'print_emoji_detection_script', 7);
remove_action('wp_print_styles', 'print_emoji_styles');

// 絵文字の DNS プリフェッチ用リンクを出力しない(この場合はフィルターフックを利用)
add_filter( 'emoji_svg_url', '__return_false' );

// REST API URL を出力しない
remove_action('wp_head','rest_output_link_wp_head');

// EditURI を出力しない
remove_action( 'wp_head', 'rsd_link' );

// wlwmanifest を出力しない
remove_action( 'wp_head', 'wlwmanifest_link' );

// WordPress のバージョン情報の出力をしない(機能に影響なし)
remove_action( 'wp_head', 'wp_generator' );

// 短縮形 URL を出力をしない
remove_action('wp_head', 'wp_shortlink_wp_head');

// oEmbed 機能に必要なリンクを出力をしない
remove_action('wp_head','rest_output_link_wp_head');
remove_action('wp_head','wp_oembed_add_discovery_links');
remove_action('wp_head','wp_oembed_add_host_js');

// feed 出力をしない.
remove_action( 'wp_head', 'feed_links', 2 );
remove_action( 'wp_head', 'feed_links_extra', 3 );

スタイルシートや JavaScript ファイルの読み込み

以下はテーマ内の style.css を読み込む例です。

get_stylesheet_uri() は、現在有効化されているテーマで使われているスタイルシートの URI(ファイル名を含む)を返す関数です。

function my_template_css() {
  wp_enqueue_style( 'my-template-style', get_stylesheet_uri() );
}
add_action( 'wp_enqueue_scripts', 'my_template_css' );

以下は jQuery を CDN から読み込み、独自の JavaScript ファイル(base.js)を </body> 終了タグの前で読み込む例です。

また、引数 $ver(16行目)に filemtime() を使ってファイルの更新日時を付与して、ファイルが更新するたびにクエリパラメータが変更されてブラウザキャッシュが更新されるようにしています。

function add_my_scripts() {
  //WordPress 本体の jQuery を登録解除
  wp_deregister_script( 'jquery');
  //jQuery を CDN から読み込む
  wp_enqueue_script( 'jquery',
    '//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js',
    array(),  //依存関係がない場合
    '3.3.1',
    true //</body> 終了タグの前で読み込み
  );
  //base.js の読み込み
  wp_enqueue_script(
    'base-script',
    get_theme_file_uri( '/js/base.js' ),
    array( 'jquery' ), //依存ファイルは上記の jquery
    filemtime( get_theme_file_path( '/js/base.js' ) ),
    true
  );
}
add_action('wp_enqueue_scripts', 'add_my_scripts');

JavaScript とスタイルシートの読み込みは同じアクションフック(wp_enqueue_scripts)を使っているのでまとめて読み込むことができます。

function add_my_files() {
  //WordPress 本体の jQuery を登録解除
  wp_deregister_script( 'jquery');
  //jQuery を CDN から読み込む
  wp_enqueue_script( 'jquery',
    '//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js',
    array(),
    '3.3.1',
    true
  );
  wp_enqueue_script(
    'base-script',
    get_theme_file_uri( '/js/base.js' ),
    array( 'jquery' ),
    filemtime( get_theme_file_path( '/js/base.js' ) ),
    true
  );
  //スタイルシートの読み込み
  wp_enqueue_style(
    'my-style',
    get_theme_file_uri( '/css/style.css' ),
    array(),
    filemtime( get_theme_file_path( '/css/style.css' ) )
  );
}
add_action('wp_enqueue_scripts', 'add_my_files');

詳細は「WordPress CSSやJavaScriptファイルの読み込み」を参照ください。

ナビゲーションメニューの登録

ナビゲーションメニュー(カスタムメニュー)の機能を利用するためには、functions.php でナビゲーションメニューを有効化または登録します。

以下は register_nav_menus() を使ったナビゲーションメニューの登録の例です。

アクションフックを使わなくても動作しますが、通常は、after_setup_theme アクションフックのタイミングで実行します。

function register_my_menus() {
  register_nav_menus( array(
    'main-menu' => 'Main Menu',
    'footer-menu'  => 'Footer Menu',
  ) );
}
add_action( 'after_setup_theme', 'register_my_menus' );

この関数は内部で add_theme_support( 'menus' ) を実行してメニュー機能を有効化しているので、add_theme_support() を別途実行する必要はありません。

詳細は「WordPress ナビゲーションメニュー(カスタムメニュー)」を参照ください。

サイドバーの登録

ウィジェットを利用するには register_sidebar() を使ってサイドバーを登録して機能を有効化します。

以下は register_sidebar() を使ったサイドバーの登録の例です。

アクションフックに登録しなくても動作しますが、通常は widgets_init アクションフックのタイミングで実行します。

function my_theme_widgets_init() {
  register_sidebar( array(
    'name' => 'Main Sidebar',
    'id' => 'main-sidebar',
    'before_widget' => '<section id="%1$s" class="my_sidebar">',
    'after_widget' => '</section>',
    'before_title' => '<h3 class="sidebar_title">',
    'after_title'  => '</h3>',
  ) );
}
add_action( 'widgets_init', 'my_theme_widgets_init' );

register_sidebar() は内部で add_theme_support( 'widgets' ) を実行してウィジェット機能を有効化しています。

詳細は「WordPress テーマにウィジェット機能を追加」を参照ください。

投稿のタイトルや抜粋の変更

投稿のタイトルをカスタマイズするには、the_title フィルターを使います。

以下は「トップページやアーカイブなどのループ内の場合」に投稿記事が一定期間内(一週間以内)に作成された場合にタイトルの最後に「New」と表示する例です。

function my_add_new_to_title( $title) {
  if ( in_the_loop() && !is_singular() ) {
    if ( date('U') - get_the_time('U') < 60*60*24*7 ){
      $title .= ' <span class="new_entry">New</span>';
    }
  }
  return $title;
}
add_filter('the_title', 'my_add_new_to_title');

詳細は「the_title フィルター」を参照ください。

以下は抜粋の文字数を30文字に変更する例です。

function change_my_excerpt_mblength( $length ) {
  return 30;
}
add_filter( 'excerpt_mblength', 'change_my_excerpt_mblength' );

詳細は「抜粋のデフォルトの変更」を参照ください。

投稿 ID の取得

投稿 ID はループの中では get_the_ID() などで取得することができますが、フックなどではタイミングによって以下のようにスーパーグローバル変数から投稿 ID を取得することがあります。

$_GET['post'] または $_POST['post_ID']

以下は「特定のページにメタボックスを追加する」場合の add_meta_boxes アクションで使用する例です。

$post_id = '';
//投稿ID を $_GET['post']  または $_POST['post_ID'] から取得
if( isset($_GET['post'] ) || isset( $_POST['post_ID'] ) ) {
  $post_id = $_GET['post'] ? $_GET['post'] : $_POST['post_ID'] ;
}

wp-admin\includes\class-wp-screen.php では以下のような記述があります。(int) を使って整数値に型キャストしています。

//一部抜粋
if ( isset( $_GET['post'] ) )
  $post_id = (int) $_GET['post'];
elseif ( isset( $_POST['post_ID'] ) )
  $post_id = (int) $_POST['post_ID'];
else

また、wp-admin\includes\dashboard.php には以下のような input 要素の記述があります。

<input type="hidden" name="post_ID" value="<?php echo $post_ID; ?>" />

$_REQUEST['post'] または $_POST['post']

以下は「特定の投稿タイプでサムネイル画像を自動生成させない」場合の intermediate_image_sizes_advanced フィルタで使用する例です。

[追記 2019/07/11] 現在は、intermediate_image_sizes_advanced フィルタのタイミングでは $_REQUEST['post_id'] で投稿 ID を取得できません。代わりに $_REQUEST['post'] または $_POST['post'] を使います。

//$_REQUEST['post_id']が設定されていればそれを使って投稿タイプを取得
if (isset($_REQUEST['post']) && 'xxxxx' === get_post_type( (int) $_REQUEST['post']))

$_REQUEST['post_id']

wp-admin\async-upload.php には以下のような記述があります。

//一部抜粋
if ( isset( $_REQUEST['post_id'] ) ) {
  $post_id = absint( $_REQUEST['post_id'] );
  if ( ! get_post( $post_id ) || ! current_user_can( 'edit_post', $post_id ) )
    $post_id = 0;
}

media_upload_type_url_form() と言う関数のソースには以下のような記述があります。

//一部抜粋
$post_id = isset( $_REQUEST['post_id'] ) ? intval( $_REQUEST['post_id'] ) : 0;

また、wp-admin\media.php には以下のような input 要素の記述があります。

<input type="hidden" name="post_id" id="post_id" value="<?php echo isset($post_id) ? esc_attr($post_id) : ''; ?>" />

関連ページ:ループで使うテンプレートタグや関数/ID

関数作成で使う関数

wp_parse_args

(ユーザーの指定した)引数の値とデフォルトの値をマージ(結合)するための関数です。

WordPress の関数の定義などで良く使われている関数で、関数を作成する際などに使えます。

wp_parse_args( $args, $defaults )

パラメータ
  • $args(配列|文字列|オブジェクト):(必須)デフォルトの値($defaults)とマージする値の連想配列やクエリ形式の文字列(例 type=post&posts_per_page=7)、オブジェクト。$defaults 内の値を上書きします。
  • $defaults(配列):(オプション)デフォルト値の配列。$args で上書きされます。初期値:''
戻り値
ユーザーの指定した引数とデフォルト値をマージした結果の連想配列

以下は wp_parse_args() の働きを確認するためだけの my_arg_test() と言う関数の例です。

my_arg_test() は引数に指定した値をデフォルトの値($defaults)とマージして出力します。

※この関数 my_arg_test() が引数なしでもエラーにならないようにするためには、引数にデフォルト値 $args = array() を設定しておく必要があります。

function my_arg_test( $args = array() ) {
  $defaults = array(
    'foo' => "Apple",
    'bar' => "Windows",
    'boo' => "Linux",
  );
  $args = wp_parse_args( $args, $defaults );
  foreach($args as $key => $val) {
    echo $key . ' => ' . $val . '<br>';
  }
} 

以下は実行例です。

引数に値を指定しなければデフォルト値が使われ、値を指定すればそれがデフォルトの値を上書きします。

デフォルトにない引数を指定すると追加されます。

引数の指定は連想配列かクエリ文字列で指定します(オブジェクトでも指定可能)。

<?php
  /* 引数指定なし */
  my_arg_test();
  //実行結果
  foo => Apple
  bar => Windows
  boo => Linux

  /* 連想配列で指定 */
  my_arg_test(array('foo' =>'X'));
  //実行結果
  foo => X
  bar => Windows
  boo => Linux

  my_arg_test(array('foo_new' => '独自追加'));
  //実行結果
  foo => Apple
  bar => Windows
  boo => Linux
  foo_new => 独自追加 //デフォルトにない場合は追加される

  my_arg_test(array('foo' => 'X', 'bar' => 'Y'));
  //実行結果
  foo => X
  bar => Y
  boo => Linux

  my_arg_test(array('foo' => 'X', 'bar' => 'Y', 'boo' => 'Z'));
  //実行結果
  foo => X
  bar => Y
  boo => Z

  $my_args = array('foo'=> '1', 'bar' => '2', 'boo' => '3');
  my_arg_test($my_args); //変数に入れてから実行
  //実行結果
  foo => 1
  bar => 2
  boo => 3

  /* クエリ文字列で指定 */
  my_arg_test('foo=0&bar=1');
  //実行結果
  foo => 0
  bar => 1
  boo => Linux

?>

似たような関数に shortcode_atts() がありますが、shortcode_atts() の場合はデフォルトにない値は無視されて追加できないなどの違いがあります。

以下は wp_parse_args() のソースです。

必要に応じて $args を配列に変換してデフォルトの配列と array_merge() でマージしています。

function wp_parse_args( $args, $defaults = '' ) {
  if ( is_object( $args ) ) {
    $r = get_object_vars( $args );
  } elseif ( is_array( $args ) ) {
    $r =& $args;
  } else {
    wp_parse_str( $args, $r );
  }

  if ( is_array( $defaults ) ) {
    return array_merge( $defaults, $r );
  }
  return $r;
}
extract() 連想配列を変数として抽出

関数の定義などでは、マージした引数の連想配列を変数として使うことが多いと思います。

引数の連想配列を変数に登録(抽出)するには PHP 関数の extract() を使用します。

第2引数 EXTR_SKIP は、もし同じ変数名が他に存在する場合は上書きしないと言う指定です。

extract() を使うと連想配列の要素をキーを変数名とした変数として使用できるようになります。

PHP マニュアルには「配列からシンボルテーブルに変数をインポートする」とあります。シンボルテーブルは変数を管理するテーブルでスコープごとに1つのシンボルテーブルがあります。つまり現在のスコープに変数を追加してくれます。

<?php
function my_extract_test($args = array()) {
  $defaults = array(
    'foo' => "Apple",
    'bar' => "Windows",
    'boo' => "Linux",
  );
  $args = wp_parse_args( $args, $defaults );

  //連想配列を変数に登録
  extract( $args, EXTR_SKIP );

  //extract() の実行によりキーを変数名として使用できるようになる
  //echo $foo; で Apple が出力される

  foreach($args as $key => $val) {
    echo ${$key} .'<br>';  //変数名($foo や $bar など)を動的に生成して出力
    //または echo $$key .'<br>';
  }

}

my_extract_test(array('Test' => 'Test Value'));

?>

<-- 出力結果 -->
Apple
Windows
Linux
Test Value

管理者メールアドレスを承認なしで変更

管理者メールアドレスを変更する場合、変更したメールアドレス宛に変更の承認メールが送信されます。

何らかの理由で承認メールが届かなかったり、変更の承認ができない場合、以下を functions.php に記述することで、確認メールの送信を一時的に無効にして変更することができます。

[注意]

承認メールが送られる仕組みはセキュリティ上のものなので、管理者メールアドレスが変更できたら、以下の記述は削除します。

//管理者メールアドレスをメールによる承認なしで変更
//既存のフックを削除
remove_action( 'add_option_new_admin_email', 'update_option_new_admin_email' );
remove_action( 'update_option_new_admin_email', 'update_option_new_admin_email' );
//新たなフックを登録
add_action( 'add_option_new_admin_email', 'my_update_option_new_admin_email', 10, 2 );
add_action( 'update_option_new_admin_email', 'my_update_option_new_admin_email', 10, 2 );
//保存時に承認プロセスを実行するのではなく直接更新
function my_update_option_new_admin_email( $old_value, $value ) {
  update_option( 'admin_email', $value );
}

//プロフィールのメールアドレスをメールによる承認なしで変更
add_action( 'admin_init', function() {
  remove_action( 'personal_options_update', 'send_confirmation_on_profile_email' );
} );