この投稿は、Twenty-Seventyeenのfunctions.phpに書かれている関数を解読しています!
公式テーマの中身を勉強して、自作テーマ作成に役立てたいと考えています。
functions.phpは、テーマに必ず存在するもので、その名のとおりテーマの設定に必要な関数が書かれているファイルです。しかし、このファイルに、何を記載すればいいのでしょうか?
目次
- 1 functions.phpとは?
- 2 アクションフックとフィルターフックをおさえておこう
- 3 WordPressバージョンの確認
- 4 テーマのセットアップ関数|twentyseventeen_setup()
- 5 コンテンツの幅を設定する関数|twentyseventeen_content_width()
- 6 カスタムフォントの登録 twentyseventeen_fonts_url
- 7 twentyseventeen_resource_hints
- 8 ウィジェットの登録 twentyseventeen_widgets_init
- 9 抜粋[…]に付け加え twentyseventeen_excerpt_more
- 10 Javascriptの検出 twentyseventeen_javascript_detection
- 11 ピンバックURLの指定 twentyseventeen_pingback_header
- 12 カラーのカスタマイズ twentyseventeen_colors_css_wrap
- 13 スクリプトとスタイルを追加する|twentyseventeen_scripts
- 14 まとめ
functions.phpとは?
functions.phpは、テーマに必ず存在するもので、その名のとおりテーマの設定に必要な関数が書かれているファイルです。
スタイルシート、スクリプト、カスタム投稿やウィジェットなど必要なものをなんでも登録させることができ、自作の関数もこちらで登録しておけば、テーマ内のテンプレートで使うことができます。
アクションフックとフィルターフックをおさえておこう
functions.phpのファイル内で必ず出てくるのが、アクションフックとフィルターフックと呼ばれるものです。
アクションフックとフィルターフックは、このようなコードで追加されます。
add_action() add_filter()
フィルター、アクションにフック・・・名前だけでは何のことかさっぱり?なのですが、僕は次のように理解しています。
- アクションフック
- テーマ設定時、ヘッダー読み込み時、ウィジェット設定時など、WordPressの動作その時々に追加して機能させる命令
- フィルターフック
- WordPressのデータベースのアクセスや、サーバーとクライアント間のアクセス時に機能させる命令
Twentyseventeenのfunctions.phpに出てくるアクションフックとフィルターフックの例をまとめます。
- after_setup_theme(アクション)
- テーマでサポートしたい機能をここで追加する
- wp_resource_hints(フィルター)
- 特定のWebサイトを事前に読み込むなどの処理
- widgets_init(アクション)
- ウィジェットの追加
- excerpt_more(フィルター)
- moreタグの設置
- wp_head(アクション)
- ヘッダーの読み込み時の処理
- wp_enqueue_scripts(アクション)
- スクリプト、スタイルシートなどの読み込み
- wp_calculate_image_sizes(フィルター)
- 画像サイズの計算処理
- get_header_image_tag(フィルター)
- ヘッダーイメージサイズの上書き
- wp_get_attachment_image_attributes(フィルター)
- HTMLのimg要素の抽出
- frontpage_template(フィルター)
- front-page.phpを使えるようにする
このように、WordPressが行う様々な処理に引っ掛け(フックし)て、処理(命令)を追加しているようです。これがイメージできるようになっただけでも、進歩ですよね!
それでは、順番に関数を解読していきます。
WordPressバージョンの確認
これはお決まりですが、functions.php内は、全体がPHPコードです。開始タグ
<?php
から始めます。閉じタグ ?> は書かないことが推奨されているようで、書かなくても良いです。
はじめに、次のようなコードが書かれています。これは、WordPressのバージョンを確認し、4.7alpha未満の場合、back-compat.phpに書かれている関数を定義するよう指定されています。
if文なので、4.7plpha以上の場合は飛ばされます。
/** * Twenty Seventeen only works in WordPress 4.7 or later. */ if ( version_compare( $GLOBALS['wp_version'], '4.7-alpha', '<' ) ) { require get_template_directory() . '/inc/back-compat.php'; return; }
$GLOBALSは、ワードプレスのコード全体にわたって使用することができる変数(データ)です。wp_versionという変数に、バージョンが格納されています。(Codexで紹介されている変数以外をアクセスすることはやめた方が良いとのことです)
テーマのセットアップ関数|twentyseventeen_setup()
テーマのセットアップ関数がずら〜っと書かれています。小分けにして見ていきます。
function twentyseventeen_setup() { /*下記に順に説明しています*/; } add_action( 'after_setup_theme', 'twentyseventeen_setup' );
以下、テーマのセットアップ関数内で使用されている関数について解読していきます。
翻訳ファイルの読み込み| load_theme_textdomain();
はじめに、テーマの翻訳ファイルを読み込みます。拡張子が.moという翻訳ファイルを読み込んでいます。
load_theme_textdomain( 'twentyseventeen' );
深くわかっているわけでないのですが・・・デフォルトテーマの場合、wordpressがインストールされているフォルダの中の次のアドレスのところに、ロケール(言語)に合わせてインストールされた.moファイルがあります。
/wordpress/wp-content/languages/themes/
この中から、twentyseventeen-ja.moというファイルが選ばれるようになっています。
自分で翻訳ファイルとその場所を指定することもできます。
機能の追加|add_theme_support();
この関数には、after_setup_theme が必要です。様々な機能を追加しています。
add_theme_support( 'automatic-feed-links' );
追加してある機能の一覧
- automatic-feed-links
- title-tag
- post-thumbnails
- html5
- post-formats
- custom-logo
- customize-selective-refresh-widgets
- starter-content
一つひとつ見ていきましょう。
automatic-feed-links
headの中にfeedリンクタグ<link>を出力し、feedの存在を知らせてくれます。
add_theme_support( 'automatic-feed-links' );
title-tag
headの中に<title>タグを出力します。
add_theme_support( 'title-tag' );
post-thumbnails
投稿編集画面にアイキャッチ画像のセクションを表示させることを有効にします。
add_theme_support( 'post-thumbnails' );
これに続いて、画像サイズが二つ追加されています。実際に使われているところで、解説します。
add_image_size( 'twentyseventeen-featured-image', 2000, 1200, true ); add_image_size( 'twentyseventeen-thumbnail-avatar', 100, 100, true );
グローバル変数の’content_width’に、525pxが代入されました。メディアの挿入で画像を選択するときに「大サイズ」の幅が525pxになっています。
$GLOBALS['content_width'] = 525;
html5
html5のマークアップ使用を許可します。コメントフォーム、コメントリスト、ギャラリー、キャプション。
add_theme_support( 'html5', array( 'comment-form', 'comment-list', 'gallery', 'caption', ) );
post-formats
投稿フォーマットの指定ができます。
add_theme_support( 'post-formats', array( 'aside', 'image', 'video', 'quote', 'link', 'gallery', 'audio', ) );
下の画像のように選択できます。
custom-logo
ロゴを指定することができるようになる命令です。widthとheightは、ロゴ画像選択の際に「推奨画像サイズ」として出てきます。
add_theme_support( 'custom-logo', array( 'width' => 250, 'height' => 250, 'flex-width' => true, ) );
customize-selective-refresh-widgets
メニュー→外観→カスタマイズ(ウィジェット) で、編集ショートカットを有効にします。
add_theme_support( 'customize-selective-refresh-widgets' );
これを有効にすると、ライブビューの更新を確認しながら編集することができるようになり、便利です。
starter-content
これは、テーマを使い始める時に、テーマ側が用意したサンプルを表示させて、どのようなことができるのかをわかりやすく表示してくれる機能です。ちょっと長いですが、add_theme_supportで追加しているスターターコンテンツの内容を見てみましょう!
まずは、ウィジットのサイドバーです。sidebar-1、sidebar-2、sidebar-3の情報が追加されています。
add_theme_support( 'starter-content', array( 'widgets' => array( 'sidebar-1' => array( 'text_business_info', 'search', 'text_about', ), 'sidebar-2' => array( 'text_business_info', ), 'sidebar-3' => array( 'text_about', 'search', ), ), // 続く
sidebar-1は、下の図のように追加されていますね。
同様に、sidebar-2はフッター1、sidebar-3はフッター2として追加されています。
次は、postsです。about、contact、blog、homepage-sectionに対してアイキャッチ画像が当てがわれます。
// 続き 'posts' => array( 'home', 'about' => array( 'thumbnail' => '{{image-sandwich}}', ), 'contact' => array( 'thumbnail' => '{{image-espresso}}', ), 'blog' => array( 'thumbnail' => '{{image-coffee}}', ), 'homepage-section' => array( 'thumbnail' => '{{image-espresso}}', ), ), // 続く
例として、about(会社概要)のアイキャッチを示します。
次のattachmentsは、添付ファイル(メディア)の関連付けです。postsのthumbnailで当てがったimage-espresso、image-sandwich、image-coffeeに、タイトルと画像のアドレスを指定しています。
// 続き 'attachments' => array( 'image-espresso' => array( 'post_title' => _x( 'Espresso', 'Theme starter content', 'twentyseventeen' ), 'file' => 'assets/images/espresso.jpg', ), 'image-sandwich' => array( 'post_title' => _x( 'Sandwich', 'Theme starter content', 'twentyseventeen' ), 'file' => 'assets/images/sandwich.jpg', ), 'image-coffee' => array( 'post_title' => _x( 'Coffee', 'Theme starter content', 'twentyseventeen' ), 'file' => 'assets/images/coffee.jpg', ), ), // 続く
次のoptionsで、ホーム、投稿ページに表示するページを設定しているのだと思うのですが・・・まだよくわかっていません。
// 続き 'options' => array( 'show_on_front' => 'page', 'page_on_front' => '{{home}}', 'page_for_posts' => '{{blog}}', ), // 続く
theme_modsは、今は全くわかりません。ごめんなさい。
// 続き 'theme_mods' => array( 'panel_1' => '{{homepage-section}}', 'panel_2' => '{{about}}', 'panel_3' => '{{blog}}', 'panel_4' => '{{contact}}', ), // 続く
nav_menusで、トップのナビとソーシャルの設定をしています。
// 続き 'nav_menus' => array( 'top' => array( 'name' => __( 'Top Menu', 'twentyseventeen' ), 'items' => array( 'page_home', 'page_about', 'page_blog', 'page_contact', ), ), 'social' => array( 'name' => __( 'Social Links Menu', 'twentyseventeen' ), 'items' => array( 'link_yelp', 'link_facebook', 'link_twitter', 'link_instagram', 'link_email', ), ), ), ) );
add_editor_style
投稿の編集画面「ビジュアルエディター」にスタイルを追加します。まだ、よくわかっていません。
add_editor_style( array( 'assets/css/editor-style.css', twentyseventeen_fonts_url() ) );
2種類のナビメニューを登録しています。
register_nav_menus( array( 'top' => __( 'Top Menu', 'twentyseventeen' ), 'social' => __( 'Social Links Menu', 'twentyseventeen' ), ) );
コンテンツの幅を設定する関数|twentyseventeen_content_width()
見出しのとおり、テーマのデザインとスタイルシートに基づいて、コンテンツの幅を設定します。どこでこの関数が実行されているかは、まだわかっていません。既に、上のほうにある
$GLOBALS['content_width'] = 525;
で、コンテンツ幅が設定されています。
function twentyseventeen_content_width() { } add_action( 'after_setup_theme', 'twentyseventeen_content_width', 0 );
この関数の中で行われていることを解説します。
グローバル変数の、$content_widthを、ローカル変数$content_widthに代入しています。
$content_width = $GLOBALS['content_width'];
次に、ページレイアウトを取得しています。ページレイアウトというのは、カラム数とかです。
$page_layout = get_theme_mod( 'page_layout' );
カラム数が1の時、if文の中が実行されます。フロントページの時は644px、固定ページの時は740pxです。
if ( 'one-column' === $page_layout ) { if ( twentyseventeen_is_frontpage() ) { $content_width = 644; } elseif ( is_page() ) { $content_width = 740; } }
投稿ページ(ブログ)かつサイドバー無しのときは、740pxです。
if ( is_single() && ! is_active_sidebar( 'sidebar-1' ) ) { $content_width = 740; }
この関数が登録され、値がグローバル変数の$content_widthに代入されます。
$GLOBALS['content_width'] = apply_filters( 'twentyseventeen_content_width', $content_width );
しかし、実際のところコンテンツ幅は525pxであるため、この関数は実行されていないことがわかります。または、条件に合っていないか・・・
カスタムフォントの登録 twentyseventeen_fonts_url
このような関数名です。下の方で出てくる、スタイルを追加するtwentyseventeen_scripts()という関数の中で使われています。カスタムフォントのurlを返します。
function twentyseventeen_fonts_url() {}
コメントの引用です。
あなたの言語でLibre Franklinがサポートしていない文字がある場合は、これを「オフ」に変換してください。 あなた自身の言語に翻訳しないでください。
$fonts_url = ''; $libre_franklin = _x( 'on', 'Libre Franklin font: on or off', 'twentyseventeen' ); if ( 'off' !== $libre_franklin ) { $font_families = array(); $font_families[] = 'Libre Franklin:300,300i,400,400i,600,600i,800,800i'; $query_args = array( 'family' => urlencode( implode( '|', $font_families ) ), 'subset' => urlencode( 'latin,latin-ext' ), ); $fonts_url = add_query_arg( $query_args, 'https://fonts.googleapis.com/css' ); } return esc_url_raw( $fonts_url );
twentyseventeen_resource_hints
$relation_typeが’preconnect’かつtwentyseventeen-fontsが読み込まれている場合、GoogleのCDNサービスのURLを返します。
function twentyseventeen_resource_hints( $urls, $relation_type ) { if ( wp_style_is( 'twentyseventeen-fonts', 'queue' ) && 'preconnect' === $relation_type ) { $urls[] = array( 'href' => 'https://fonts.gstatic.com', 'crossorigin', ); } return $urls; } add_filter( 'wp_resource_hints', 'twentyseventeen_resource_hints', 10, 2 );
wp_resource_hintsフックは、headタグに特定のページへのリンクなどを出力します。例えば、次のようなCDN(Contents Delivery Network)プリフェッチリンクを出力しています。
ウィジェットの登録 twentyseventeen_widgets_init
ウィジェットの登録です。この関数の中に書けば、登録したいウィジェットを増やすことができます。
function twentyseventeen_widgets_init() { } add_action( 'widgets_init', 'twentyseventeen_widgets_init' );
ここでは、Sidebar、Footer 1、Footer 2が登録されていますね。
register_sidebar( array( 'name' => __( 'Sidebar', 'twentyseventeen' ), 'id' => 'sidebar-1', 'description' => __( 'Add widgets here to appear in your sidebar.', 'twentyseventeen' ), 'before_widget' => '<section id="%1$s" class="widget %2$s">', 'after_widget' => '</section>', 'before_title' => '<h2 class="widget-title">', 'after_title' => '</h2>', ) ); register_sidebar( array( 'name' => __( 'Footer 1', 'twentyseventeen' ), 'id' => 'sidebar-2', 'description' => __( 'Add widgets here to appear in your footer.', 'twentyseventeen' ), 'before_widget' => '<section id="%1$s" class="widget %2$s">', 'after_widget' => '</section>', 'before_title' => '<h2 class="widget-title">', 'after_title' => '</h2>', ) ); register_sidebar( array( 'name' => __( 'Footer 2', 'twentyseventeen' ), 'id' => 'sidebar-3', 'description' => __( 'Add widgets here to appear in your footer.', 'twentyseventeen' ), 'before_widget' => '<section id="%1$s" class="widget %2$s">', 'after_widget' => '</section>', 'before_title' => '<h2 class="widget-title">', 'after_title' => '</h2>', ) );
そのとおりのウィジェットが登録されています。
抜粋[…]に付け加え twentyseventeen_excerpt_more
どこでこの機能が有効になっているのか、よくわかりません。抜粋が表示されるとき自動的に[…]が付きますが、これを”Continue reading”に置き換えます。__()関数なので、ロケールによって翻訳されるので、日本語では「続きを読む」になるはずです。
function twentyseventeen_excerpt_more( $link ) { if ( is_admin() ) { return $link; } $link = sprintf( '<p class="link-more"><a href="%1$s" class="more-link">%2$s</a></p>', esc_url( get_permalink( get_the_ID() ) ), /* translators: %s: Name of current post */ sprintf( __( 'Continue reading<span class="screen-reader-text"> "%s"</span>', 'twentyseventeen' ), get_the_title( get_the_ID() ) ) ); return ' … ' . $link; } add_filter( 'excerpt_more', 'twentyseventeen_excerpt_more' );
Javascriptの検出 twentyseventeen_javascript_detection
<html>要素にJavascriptが検出されたら、jsのclassを追加します。
function twentyseventeen_javascript_detection() { echo "<script>(function(html){html.className = html.className.replace(/\bno-js\b/,'js')})(document.documentElement);</script>\n"; } add_action( 'wp_head', 'twentyseventeen_javascript_detection', 0 );
<head>内にタグが追加されています。
ピンバックURLの指定 twentyseventeen_pingback_header
ピンバックを有効にすると、そのurlを<head>内に追加するのだと思います。僕はいつも無効なので・・・?
function twentyseventeen_pingback_header() { if ( is_singular() && pings_open() ) { printf( '<link rel="pingback" href="%s">' . "\n", get_bloginfo( 'pingback_url' ) ); } } add_action( 'wp_head', 'twentyseventeen_pingback_header' );
追加されていますね。
カラーのカスタマイズ twentyseventeen_colors_css_wrap
色をカスタマイズしたときに、どのcssに適応するかを指定している(のだと思います。)
function twentyseventeen_colors_css_wrap() { if ( 'custom' !== get_theme_mod( 'colorscheme' ) && ! is_customize_preview() ) { return; } require_once( get_parent_theme_file_path( '/inc/color-patterns.php' ) ); $hue = absint( get_theme_mod( 'colorscheme_hue', 250 ) ); ?> <style type="text/css" id="custom-theme-colors" <?php if ( is_customize_preview() ) { echo 'data-hue="' . $hue . '"'; } ?>> <?php echo twentyseventeen_custom_colors_css(); ?> </style> <?php } add_action( 'wp_head', 'twentyseventeen_colors_css_wrap' );
下の図のように、配色を「カスタム」にしたとき、/inc/color-patterns.php の内容がずらーっと読み込まれます。colors-custom が何に適応されるかが決まります。
スクリプトとスタイルを追加する|twentyseventeen_scripts
スクリプトとスタイルを追加する関数です。
function twentyseventeen_scripts() { } add_action( 'wp_enqueue_scripts', 'twentyseventeen_scripts' );
順番に見ていきましょう。
まずは、カスタムフォントの追加です。
wp_enqueue_style( 'twentyseventeen-fonts', twentyseventeen_fonts_url(), array(), null );
次は、スタイルシートの追加です。
wp_enqueue_style( 'twentyseventeen-style', get_stylesheet_uri() );
もし、色のカスタマイズで「ダーク」が選ばれているときのスタイルシート選定です。
if ( 'dark' === get_theme_mod( 'colorscheme', 'light' ) || is_customize_preview() ) { wp_enqueue_style( 'twentyseventeen-colors-dark', get_theme_file_uri( '/assets/css/colors-dark.css' ), array( 'twentyseventeen-style' ), '1.0' ); }
IE9で、カスタマイズプレビューが表示されたとき、ie9.cssが追加されます。そして、スタイル’twentyseventeen-ie9’のメタ情報に’IE 9’が追加されます。
if ( is_customize_preview() ) { wp_enqueue_style( 'twentyseventeen-ie9', get_theme_file_uri( '/assets/css/ie9.css' ), array( 'twentyseventeen-style' ), '1.0' ); wp_style_add_data( 'twentyseventeen-ie9', 'conditional', 'IE 9' ); }
IE8以下のバージョンのための、スタイルシート追加だと思います。
wp_enqueue_style( 'twentyseventeen-ie8', get_theme_file_uri( '/assets/css/ie8.css' ), array( 'twentyseventeen-style' ), '1.0' ); wp_style_add_data( 'twentyseventeen-ie8', 'conditional', 'lt IE 9' );
こちらも、IE8以前での閲覧対応です。html5shiv.jsの追加です。
wp_enqueue_script( 'html5', get_theme_file_uri( '/assets/js/html5.js' ), array(), '3.7.3' ); wp_script_add_data( 'html5', 'conditional', 'lt IE 9' );
skip-link-focus-fix.jsというファイルの追加です。
wp_enqueue_script( 'twentyseventeen-skip-link-focus-fix', get_theme_file_uri( '/assets/js/skip-link-focus-fix.js' ), array(), '1.0', true );
ナビゲーションに関するjsの追加です。
$twentyseventeen_l10n = array( 'quote' => twentyseventeen_get_svg( array( 'icon' => 'quote-right' ) ), ); if ( has_nav_menu( 'top' ) ) { wp_enqueue_script( 'twentyseventeen-navigation', get_theme_file_uri( '/assets/js/navigation.js' ), array(), '1.0', true ); $twentyseventeen_l10n['expand'] = __( 'Expand child menu', 'twentyseventeen' ); $twentyseventeen_l10n['collapse'] = __( 'Collapse child menu', 'twentyseventeen' ); $twentyseventeen_l10n['icon'] = twentyseventeen_get_svg( array( 'icon' => 'angle-down', 'fallback' => true ) ); }
global.jsとjquery.scroolTo.jsの追加です。
wp_enqueue_script( 'twentyseventeen-global', get_theme_file_uri( '/assets/js/global.js' ), array( 'jquery' ), '1.0', true ); wp_enqueue_script( 'jquery-scrollto', get_theme_file_uri( '/assets/js/jquery.scrollTo.js' ), array( 'jquery' ), '2.1.2', true );
次のローカライズは、よくわかりません。
wp_localize_script( 'twentyseventeen-skip-link-focus-fix', 'twentyseventeenScreenReaderText', $twentyseventeen_l10n );
コメントに返信するとき、コメントフォームが、該当コメントの下に表示されるそうです。
if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) { wp_enqueue_script( 'comment-reply' ); }
まとめ
Codexを読みながら、進めていますが、完全に理解できていないところもあります。ごめんなさい。できたところまでを公開させていただいています。
なおきちさん、返信が遅れてしまい申し訳ありません!
naviを固定しないようにする簡単な方法です。
functions.phpの中の、global.js を読み込んでいる部分をコメントアウトします。
このような感じです。
/*wp_enqueue_script( ‘twentyseventeen-global’, get_theme_file_uri( ‘/assets/js/global.js’ ), array( ‘jquery’ ), ‘1.0’, true );*/
スティックになる理由は、スクロールしてnaviが隠れる位置までくると、navigation-top というクラスに site-navigation-fixedというクラスが追加されるからです。
global.jp の中でこの処理が行われています。
お試しください。
初めまして。
Twenty Seventeenの解析読ませていただきました。
細かく解析されていてわかりやすかったです。
質問したいことがあるのですが、Twenty Seventeenではメニューを設定するとPCで閲覧時にメニューがページ上部に追従してくる仕様になっていると思います。
いわゆるStickyと呼ばれるやつだと思うのですが、それを無効にする方法をご教授していただければと思います。
見たところ、このブログはその機能を無効化しているようなので質問しました。
もしよければコメント下さい。