WordPress Logo WordPress functions.php

更新日:2019年04月22日

作成日:2019年02月02日

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 に記述する設定項目や関数などについて。

フック

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

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

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

  • add_theme_support(): テーマに特定の機能を有効化
  • add_editor_style(): ビジュアルエディタのスタイルシート設定
  • add_image_size(): 画像サイズの登録
  • set_post_thumbnail_size(): アイキャッチ画像サイズの設定
  • register_nav_menus(): ナビゲーションメニューを登録

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' );

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

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'
  • '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'

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

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

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

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

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

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' );

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