ワードプレスのテーマとは、このフレームワークにそって画面に表示されるものを作り上げる雛形というようなものだと考えます。
そのフレームワーク自体は、php、javascriptというプログラミング言語で書かれており、データの読み込みや、エディターから入力された情報の解釈、処理は、このフレームワークとしての処理によるものです。
ここでは、必要最低限で構成された、_s(underscore)というブランカテーマを使って、自作のブログテーマを作っていきたいと思います。
目次
どういう用途を想定したテーマを作るのか
ワードプレスで作れるページは、固定ページとしてのホームページと、投稿ページとしてのブログです。ホームページの中に、投稿ページがはいっている場合もあり、ブログページの中に固定ページが入っている場合もあります。
ここでは、記事を投稿することによって構成される、ブログページとしてのテーマを作っていきます。
前提となる知識
WordPress テーマは、画像ファイルと JavaScript ファイルを除くと、大きく分けて次の3種類のファイルから構成されています。
- ウェブページの外観を制御しているスタイルシート
- ウェブページとして表示する情報をデータベースから取得し、ウェブページを生成するphp言語コードが埋め込まれたファイル(テンプレートファイル)
- テンプレートファイル生成に係わるオプション関数(functions.php)
テーマを作るというのはこのようなファイルをつくることであります。したがって、これらは作る為に必要な知識が以下のものになります。
- phpプログラミング言語(必須)
- javascriptプログラミング言語
- htmlマークアップ言語(html5)(必須)
- スタイルシート(css3) (必須)
- wordpressコード仕様 (必須)
- データベース(mysql)仕様
phpプログラミング言語
ワードプレスのテンプレートファイルはhtml文書の中にphpプログラミング言語コードが埋め込まれている構成になっております。
但し、プラグインを開発するということではない限り、オブジェクト生成処理などの高度な知識は必要としません。型・変数・演算子・制御構造・関数などの基本的な仕様を理解していればいいと思います。
html5仕様
ェブページはhtml文で記述されております。htmlタグの知識は必須と思われます。特に、最新の仕様である、html5はアクセスビリティを考慮したものであります。
wordpressコード
処理に係わるもののほとんどは、製作者自らphpコードで作成することなく、ワードプレスの処理のコアの部分から引き出して記述することで事足ります。膨大な量の関数が用意されていますが、それらは、必要に応じて、ワードプレスのマニュアルが詰まっているcodexを参照し使用すればよいでしょう。
但し、テーマを作るにあたり、ファイル構成や書き方の基本は習得する必要があります。
スタイルシート(css)
スタイルシートはページのデザイン構成を定義するものです。wordpressのテーマでは、style.cssというファイルが、デザインの基本構成を定義しています。
アンダースコアーの初期画面は、ブラウザ特有のデザインの差異をリセットした状態にさせるコーディングとなっており、一からスタイリングするコードを書く必要があります。
レスポンシブ画面として、スマホでの表示にも対応した、デザインをしなければいけません。flexboxレイアウトやSASS(SASS使用にチェックを入れてダウンロードした場合)の知識も必要になってきます。
javascriptとデータベース(mysql)
javascriptはワードプレステーマの中で、表示に動作を加えることに使われます。
ワードプレスで書かれた文書、メタ情報はすべて、データベースとして保管され、リクエストされるたびに、そこから取り出される(データベースを通さず、キャッシュされるものもありますが) ことになっております。
この2点は、習得していれば、製作内容の幅が広がりますが、必須というわけではありません。
製作に必要とされたpc環境・ツール
- Windows7 professional Service Pack 1
- FireFox 63.0.3(64ビット)
- Google Chrome 77.0(64ビット)
- Internet Explorer11
- NVDA スクリーンリーダー
- テキストエディタNotepad++
- Poedit 翻訳編集ソフト
- PHP_CodeShiffer phpコーディング標準チェックツール
「underscore」とは
ブランクテーマである
ワードプレスのテーマは、最小限の構成として、表示メイン操作処理であるindex.phpと、表示画面装飾(スタイルシート)を担うstyle.cssがあれば、機能します。
ウェブページとして仕上げていく処理は、ほとんどがワードプレス本体からのコアファイルから必要とされる関数を引き出して来れば、実装できます。一からphpコードを組み立てていくことは少ないでしょう。
独自、自作のテーマを作る作業は、そのテーマの目的にあわせて、機能を引き出し、組み合わせることになります。
データベースからデータを引き出し、html文書として仕立てる作業は、大まかなところは定番のコード構成になります。
ブランクテーマとはこのような定番の処理コードを記述したテーマ製作の土台となるテーマとして、提供されております。(もちろん、ブランクテーマを使わずに一から製作することもいいとおもいます。)
数あるブランクテーマの中で、_s(アンダースコアー)はわかりやすい、シンプルな構成になっていると思います。

テーマ名はテーマ内でドメイン名として使われ、グローバル関数などの変数名の接頭辞になります。(自動で生成されます。)したがって、英字で簡潔なものにする必要があると思います。
シンプルな構成とテンプレート階層

テンプレートファイルは、ページ内容に応じて、上図のようにパーツ化されたファイルを読み込み、画面表示されます。
- ヘッダー領域は、header.phpを読み込みます。get_header()
- 本文領域は、template-partsフォルダー内のcontent-○○.phpを読み込みます。○○の部分は該当テンプレートファイル名になります。get_template_part( ‘template-parts/content’, get_post_type() )
- 但し、初期状態では、archive.phpとsingle.phpの content-○○.php は存在せず、content.phpが読み込まれます。
- single.phpとpage.phpでは、さらにコメントフォームの出力に係わるcomments.phpが読み込まれます。
- 指定テンプレートファイルが見つからないときに表示される404.phpにおいて、 content-○○.php の読み込みはありません。
- サイド領域は、sidebar.phpを読み込みます。get_sidebar() 但し、404.phpでは読み込みはありません。
- フッター領域は、footer.phpを読み込みます。get_footer()
グローバルな関数が定義されている、functions.phpにおいて、incフォルダー内、template-partsフォルダー内のファイルはインクルードされているので、テンプレートファイルを編集する際に、インクルードする必要はありません。
フォルダー・ファイル構成
inc/
|-custom-header.php // カスタムヘッダー画像出力用
|-cuntomizer.php //
|-jetpack.php //
|-template-functions.php // フック定義用
|-template-tags.php // 独自のタグ出力用
js/
|-customizer.js //
|-navigation.js // スマボ画面トグルメニュー処理
languages/ テーマの国際化対応翻訳に係わるフォルダー
|-undersample.pot // 翻訳のベースとなるファイル
|-readme.txt // 翻訳ファイル生成する為の説明リンク先が記述されている
template-parts // テンプレートファイル内で使用されるパーツ化されたテンプレート
.eslintrc
.stylelintrc.json
404.php
archive.php
footer.php
functions.php
header.php
index.php
LICENSE
package.json
page.php
phpcs.xml.dist // php_CodeSniffer 設定サンプル用
README.md // _sのインストール等の説明(マークダウン)
readme.txt // _sのインストール等の説明(テキスト)
screenshot.png
search.php
sidebar.php
single.php
style.css
style-rtl.css // 右から読み対応スタイルシートファイル
</code></pre>
<!-- /wp:code -->
管理画面から設定できるもの
テンプレートファイルに追加記述しなくても管理画面から設置できるものには以下のものがあります。但し、【】は出力するには該当テンプレートファイルにその記述が必要なものです。
- サイト基本情報 ロゴ 【 the_custom_logo() 】
- サイト基本情報 サイトタイトル bloginfo(‘name’) で出力
- サイト基本情報 キャッチフレーズ bloginfo(‘description’) で出力
- サイト基本情報 サイトアイコン
- 色 背景色
- ヘッダー画像 【 the_header_image_tag() 】
- 背景画像
- メニュー メニュー項目
- 追加css
- ウィジェット
- 設定 一般設定 サイトアドレス home_url()で取得
- 設定 一般設定 管理者メールアドレス bloginfo(‘admin_email’) で取得
- 設定 プライバシー プライバシーポリシー
追加する機能
- メニュー(ナビゲーション)
- 1カラムとしてのスタイリング設定
- 翻訳ファイル設置 国際化対応
管理画面からカスタマイズできるものを使用することを前提にします。ここではあえて追加する機能は上記、最低限のものにとどめます。
製作手順
ブランクテーマを生成
雛形となるブランクテーマに上記の機能を追加します。初期生成されたテンプレートファイルには、関数名の接頭辞やテーマ名の記述が、ジェネレータの記述名で生成されております。
テンプレートファイルの階層を確認し、必要であれば追加する
優先度高いページ | → | → | → | -> | → 低い |
フロントページ front-page.php | index.php | ||||
ホームページ home.php | |||||
カテゴリー category-slug.php | category-id.php | category.php | archive.php | ||
タグ tag-slug.php | tag-id.php | tag.php | |||
カスタム分類 taxonomy-taxonomy-term.php | taxonomy-taxonomy.php | taxonomy.php | |||
作成者 author-nicename.php | author-id.php | author.php | |||
日付 date.php | |||||
アーカイブ archive-post_type.php | |||||
検索表示 search.php | |||||
Not Found表示 404.php | |||||
固定ページ ○○.php (○○はページ名) | page-slug.php | page-id.php | page.php | singular.php | |
投稿・カスタム投稿 single-post_type.php | single.php | ||||
添付ファイル MIME_type.php image.php video.php audio.php application.php | attachment.php | single-attachment.php |
必要に応じて、上記に記載されているテンプレートファイルを製作して、表示に反映させることが出来ます。
初期画面

上図は、アンダースコアーブランクテーマを有効化し、初期状態を画面表示したものです。
スタイリングがリセットされているので、ほぼ一から設定することになります。スマボ画面にしたときのメニュートグルボタンはセットされています。
管理画面からデータを記入する
カテゴリ

自作テーマのメニューは2階層を想定しているので、図のように、記入する必要があります。
設定項目-一般設定

サイトのタイトル名とキャッチフレーズを記入します 。ローカル環境で製作している場合は、wordpressアドレスを後から本番環境に合わせる必要があります。
設定項目-表示設定

製作中は、検索エンジンにインデックスされないようにし、運用後に設定を替えます。ホームページ表示画面の設定及び一ページに表示する投稿数も後から設定できるので、最小限の状態にします。
設定-プライバシー

既存のプライバシーポリシーをいれます。これはあくまでも、レイアウト用としての仮設定なので、利用者が、のちに編集する必要があります。
サンプルデータを投稿画面から入力する
htmlサンプルタグを使った記事投稿を作成する

htmlサンプルタグは記事を投稿する際に、ビジュアルエディターの部品として使用できます。実際にこの部品を羅列し、表示することにより、デフォルトでどのようにデザインされているか確認することが出来ます。
実際の記事を投稿する
使いそうな記事をいくつかいれてみます。
また、テストデータをインポートして使うような方法もあります。
トップページの記事表示を抜粋表示に替える
ワードプレスでは、データベースから記事情報をループ処理で取得しています。トップページでは、index.php( archive.php search.php も同様) テンプレートファイルがここでは使用されております。そのままでは、ループ処理により、投稿記事全文をそのまますべてひょうじされてしまいますので、これを抜粋表示に変えます。
/template-parts/content.php と content-search.php
・
・
<div class="entry-content">
<?php
if ( is_singular() ) : // **add**
the_content(
・
・
・
);
else : // **add**
the_excerpt(); // **add**
endif; // **add**
wp_link_pages(
・
・
メディアクエリー ブレークポイントを決める
ページをレスポンシブデザインにする場合、画面の幅によって、レイアウトを替える必要があります。ここでは、1カラムのデザインを想定しておりますので、レイアウトの大きな変更はありませんが、フォントや見出しなどを調整する必要があるので、あらかじめ、決めておく必要があります。
下記のようなスマホ・タブレット・pcの3種類のブレークポイント(画面幅の区切り)を設定してスタイリングを考えていきたいと思います。
- モバイルからタブレットへのブレークポイント min-width 37.5em(600px)
- タブレットからpc画面のブレークポイント min-width: 60em(960px)
スタイリング(全体のレイアウト)

html
<body>
<div id="page" class="site">
.
.
.
</div>
</body>
style.css
.site {
width: 95%; // コンテンツ領域の全体に占める割合
max-width: 1000px; // 表示領域の限界幅
margin: 0 auto; // 領域を中央に
padding: 3%; // コンテンツ領域のパディング
}
siteクラスは出力されるhtmlファイルのすべてに共通のポジションにつけられているdivタグです。よって、コンテンツ領域の全体のレイアウトは、このタグをスタイリングすることになります。
表示領域の限界幅を設定しておかないと、画面幅が大きいpcでは間延びしてしまいます。領域は、中央に合わせておいたほうが良いでしょう。必要があれば、メディアクエリーのブレークポイント境界ごとに、幅とパディングを調整するのもよいでしょう。
スタイリング(ヘッダー)

管理画面からロゴ画像をいれる
「外観–>カスタマイズ–>サイト基本情報–>ロゴ–>ロゴ選択–>画像アップロード–>添付ファイルの詳細画–>代替テキスト記入–>選択ボタンプッシュ」
画面表示させるには、header.phpにthe_custom_logo()を追記する必要があります。functions.phpにある、add_theme_support()関数に動作が記述されているので、画面サイズ等は、ここを書き換えて調整することが出来ます。
また、外観–>カスタマイズ–>ヘッダー画像 から、ヘッダー画像を設定することが出来ます。これは、custom-header.phpでの記述によるものであり、画面表示させるには、the_header_img_tag()を追記する必要があります。
header.php
<header>
.
.
<div class="site-branding">
<?php
if ( is_front_page() && is_home() ) :
?>
<h1 class="site-title">....</h1>
<?php
else :
?>
<p class="site-title">...</p>
<?php
endif;
the_custom_logo(); // add!
the_header_image_tag(); // カスタムヘッダー使用時に必要
$undersample_description = get_bloginfo( 'description', 'display' );
if ( $undersample_description || is_customize_preview() ) :
?>
<p class="site-description"><?php echo $undersample_description; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></p>
<?php endif; ?>
</div><!-- .site-branding -->
.
.
.
</header>
functions.php
function undersample_setup() {
.
.
.
add_theme_support(
'custom-logo',
array(
'height' => 250,
'width' => 250,
'flex-width' => true,
'flex-height' => true,
)
);
.
.
.
}
site-brandingクラス内、スタイリング
style.css
.
.
.site-branding {
display: flex;
flex-direction: column-reverse;
}
.site-branding a {
width: 100px;
margin: 0 auto;
}
.site-title {
text-align: center;
margin-top: 0;
font-size: 2.5rem;
font-weight: bold;
}
.site-title a {
text-decoration: none;
}
.
.
title、logo、descriptionの並びは、flexboxレイアウトで、行の逆順にしてあります。
main-navigationクラスのスタイリング

管理画面にて、位置調整を行う

上図のように、位置管理画面を表示し、固定ページとカテゴリを登録します。ナビゲーションの2段階層表示をするためには、親カテゴリの下層に入れるカテゴリを選択し、移動項目の「○○下の階層」を選択します。登録し終えたら、メニュータブの保存ボタンをクリックします。
プライマリーメニューを表示させるテンプレートファイルを確認する
header.php
<header id="masthead" class="site-header">
.
.
.
<nav id="site-navigation" class="main-navigation">
<button class="menu-toggle" aria-controls="primary-menu" aria-expanded="false"><?php esc_html_e( 'Primary Menu', 'undersample' ); ?></button>
<?php
wp_nav_menu(
array(
'theme_location' => 'menu-1',
'menu_id' => 'primary-menu',
)
);
?>
</nav><!-- #site-navigation -->
.
.
.
</header>
プライマリーメニューの表示はheader.phpに定義されているので、記述する必要はありません。上図位置管理画面のメニュー名がwp_nav_menu()のtheme_location
の値「menu-1」と一致していることを確認します。
スマホ画面のトグルメニューの表示
スマホ画面では、プライマリーメニューはボタンのトグル操作にて表示されます。この動作は、jsフォルダーのnavigation.jsで定義されている為、動作に係わるファイルを作る必要がありません。
ボタン表示の切り替えは、ここでは、メディアクエリーのブレークポイントをスマホ画面とタブレット画面との境界に設定しました。
プライマリーメニューのスタイリング
style.css
/* Navigation
--------------------------------------------- */
.main-navigation {
display: block;
width: 100%;
}
.main-navigation ul {
display: none;
list-style: none;
margin: 0;
padding-left: 0;
}
.main-navigation ul a:hover {
text-decoration: underline;
}
.main-navigation ul li {
padding: 3%;
}
.main-navigation ul ul {
/* box-shadow: 0 3px 3px rgba(0, 0, 0, 0.2); */
float: left;
position: absolute;
top: 100%;
left: -999em;
z-index: 99999;
background-color: Orange;
text-align: center;
margin-left: 50px;
}
.main-navigation ul ul a {
color: white;
}
.main-navigation ul ul ul {
left: -999em;
top: 0;
}
.main-navigation ul ul li:hover > ul,
.main-navigation ul ul li.focus > ul {
display: block;
left: auto;
}
.main-navigation ul ul a {
width: 200px;
}
.main-navigation ul li:hover > ul,
.main-navigation ul li.focus > ul {
left: auto;
}
.main-navigation li {
position: relative;
}
.main-navigation a {
display: block;
text-decoration: none;
}
/* Small menu. */
.menu-toggle,
.main-navigation.toggled ul {
display: block;
}
@media screen and (min-width: 37.5em) {
.menu-toggle {
display: none;
}
.main-navigation ul {
display: flex;
justify-content: space-around;
}
.main-navigation ul ul {
flex-direction: column;
margin-left: 0;
}
}
.site-main .comment-navigation,
.site-main
.posts-navigation,
.site-main
.post-navigation {
margin: 0 0 1.5em;
}
.comment-navigation .nav-links,
.posts-navigation .nav-links,
.post-navigation .nav-links {
display: flex;
}
.comment-navigation .nav-previous,
.posts-navigation .nav-previous,
.post-navigation .nav-previous {
flex: 1 0 50%;
}
.comment-navigation .nav-next,
.posts-navigation .nav-next,
.post-navigation .nav-next {
text-align: end;
flex: 1 0 50%;
}
スマボ画面とタブレット・PC画面とは、異なったスタイリングになっております。第2階層メニューは第1階層メニューと適切に離れるよう調整してあります。
検索フォームの設置
エーサイドへ、ウィジェットとして、設置してもかまいません。ここでは、ヘッダーの最下部に以下の記述でセットしました。
header.php
<header>
.
.
.
<div class="search-form">
<?php
if ( ! is_404() ) { // 404ページはページ内で検索欄が表示されるので除外
get_search_form();
}
?>
</div>
</header><!-- #masthead -->
style.css
/* search form */
.search-form {
text-align: right;
margin-top: 30px;
}
スタイリング(フッター)

ソーシャルメニュー・フッターメニュー追加
プライマリーメニューと基本的には同じ要領で追加処理することになります。但し、functions.phpへの追加記述する必要があります。
functions.phpにメニューを登録する
functions.php
.
.
function undersample_setup()
.
.
.
register_nav_menus(
array(
'menu-1' => esc_html__( 'Primary', 'undersample' ),
'menu-2' => esc_html__( 'Footer', 'undersample' ),
'menu-3' => esc_html__( 'Social', 'undersample' ),
)
);
.
.
ソーシャルメニュー追加・位置調整
上記、カテゴリ追加設定と同じように使用するであろうソーシャルメディアの枠を設定します。
メニュー編集画面から、menu-3を選択します。メニュー項目ではカスタムリンクを選択し、必要な数だけ追加処理をします。メニュー設定のsocialにチェックをいれ、メニュー保存ボタンをクリックします。
フッターメニュー追加・位置調整
上記同様に、menu-2を選択し、追加処理をします。サイトマップとしての機能を持たせる為に、ここでは、カテゴリと固定メニューすべてをいれました。設定・プライバシーのところで、プライバシーポリシーを入れる場合は、編集ページを開き、公開にすれば、固定ページのリストに入ります。
ソーシャルメニュー・フッターメニューの登録、有効化
プライマリーメニューと同様にこれらのメニューもfunctions.phpに登録しなければいけません。アンダースコアーの場合は、追加のタグ出力に係わるファイルは、functions.phpにてインクルードされる、inc/template-tags.phpに追記することにします。
inc/template-tags.php
function undersample_social_menu() {
if ( has_nav_menu( 'menu-3' ) ) {
wp_nav_menu(
array(
'theme_location' => 'menu-3',
'container' => 'div',
'container_id' => 'menu-social',
'container_class' => 'menu-social',
'menu_id' => 'menu-social-items',
'menu_class' => 'menu-items',
'depth' => 1,
'fallback_cb' => '',
)
);
}
}
function undersample_footer_menu() {
if ( has_nav_menu( 'menu-2' ) ) {
wp_nav_menu(
array(
'theme_location' => 'menu-2',
'container' => 'div',
'container_id' => 'menu-footer',
'container_class' => 'menu-footer',
'menu_id' => 'menu-footer-items',
'menu_class' => 'menu-items',
'depth' => 1,
'fallback_cb' => '',
)
);
}
}
ソーシャルメニュー・フッターメニュー・コピーライトの表示
ソーシャルメニュー・フッターメニューを出力させるには、テンプレートファイルに上記の関数を記述します。
footer.php
<footer id="colophon" class="site-footer">
<?php undersample_social_menu(); ?>
<div class="site-info">
<?php undersample_footer_menu(); ?>
<small class="copyright">© 2021 <?php bloginfo( 'name' ); ?>.</small><!-- copyright -->
.
.
フッターメニューのスタイリング
style.css
/* Social Footer menu */
.menu-items {
list-style: none;
margin: 0 auto;
}
.menu-footer {
padding-top: 50px;
margin: 50px 0;
}
.menu-footer ul {
display: flex;
flex-direction: column;
margin-left: -20px;
}
.menu-footer li a {
display: block;
padding: 5%;
}
@media screen and (min-width: 37.5em) {
.menu-footer ul {
flex-direction: row;
flex-wrap: wrap;
}
.menu-footer ul li {
width: 150px;
}
}
/* social button */
/* アイテム番号はDB登録ごとに変ります */
.menu-social {
margin: 60px 0;
}
.menu-items {
display: flex;
flex-wrap: wrap;
}
@media screen and (min-width: 37.5em) {
.menu-items {
display: flex;
flex-wrap: wrap;
}
}
.menu-social li {
width: 300px;
text-align: center;
font-family: 'Verdana',sans-serif;
font-size: 1.2em;
border-radius: 4px;
}
.menu-social li a {
display: block;
padding: 10px 0;
transition: .4s;
}
.menu-social li a:hover {
color: #fff;
text-decoration: none;
}
@media screen and (min-width: 37.5em) {
.menu-item {
flex-grow: 1;
}
}
#menu-item-71 { /* twitter */
border: solid 1px #55acee;
color: #55acee;
}
#menu-item-71:hover {
border: solid 1px #55acee;
background: #55acee;
}
#menu-item-72 { /* facebook */
border: solid 1px #3b5998;
color: #3b5998;
}
#menu-item-72:hover {
border: solid 1px #3b5998;
background: #3b5998;
}
#menu-item-73 { /* Instagram */
border: solid 1px #c6529a;
color: #c6529a;
}
#menu-item-73:hover {
border: solid 1px #c6529a;
background: #c6529a;
}
#menu-item-74 { /* Feedly */
border: solid 1px #6cc655;
color: #6cc655;
}
#menu-item-74:hover {
border: solid 1px #6cc655;
background: #6cc655;
}
#menu-item-75 { /* Pocket */
border: solid 1px #ef3f56;
color: #ef3f56;
}
#menu-item-75:hover {
border: solid 1px #ef3f56;
background: #ef3f56;
}
#menu-item-76 { /* Hatena */
border: solid 1px #1ba5dc;
color:#1ba5dc ;
}
#menu-item-76:hover {
border: solid 1px #1ba5dc;
background: #1ba5dc;
}
#menu-item-77 { /* YouTube */
border: solid 1px #fc0d1c;
color: #fc0d1c;
}
#menu-item-77:hover {
border: solid 1px #fc0d1c;
background: #fc0d1c;
}
#menu-item-78 { /* LINE@ */
border: solid 1px #00c300;
color: #00c300;
}
#menu-item-78:hover {
border: solid 1px #00c300;
background: #00c300;
}
.site-info {
text-align: center;
}
.copyright {
display: block;
}
スタイリング(エーサイド)

ウィジットを登録する
WordPress の既存のウィジェットを使用するには、functions.phpにおいて、 register_sidebar() を使って機能を有効化 する必要がありますが、アンダースコアーは導入済みになっております。
但し、エーサイド以外の利用(たとえば、フッターにウィジットをいれる)を考えているならば、functions.phpにて、追加登録し、表示対象のテンプレートファイルに表示処理をする( dynamic_sidebar() )必要があります。

管理画面からウィジェット画面を開き、使用するウィジェットを選択します。
ウィジットのスタイリング
style.css
/* 全体・共通の設定 */
.widget-area {
margin: 50px auto;
}
.widget-area ul {
list-style: none;
margin-left: -30px;
}
/* カテゴリ・タグ・コメント内のタグ共通 */
.cat-links,
.tags-links,
.comment-link {
display: block;
}
.cat-links a,
.tags-links a,
.comment-link a {
text-decoration: none;
}
.cat-links a:hover,
.tags-links a:hover,
.comment-link a:hover {
text-decoration: underline;
}
.tagcloud a,
.tags-links a {
display: inline;
line-height: 1.5em;
border: 1px solid #333;
border-radius: 3px;
}
@media screen and (min-width: 37.5em) {
.tagcloud a,
.tags-links a {
display: inline;
}
.cat-links,
.tags-links,
.comment-link {
display: inline;
}
}
/*カテゴリウィジェット*/
.widget_categories li,
.cat-links a {
display: inline;
margin-left: 1px;
margin-right: 1px;
padding: 0 10px;
line-height: 1.5em;
white-space: nowrap;
border-radius: 3px;
color: #fff;
background-color: #777;
}
.widget_categories li a {
color: #fff;
text-decoration: none;
}
.widget_categories li a:hover {
text-decoration: underline;
}
.widget_categories li:before {
/* font-family: 'Font Awesome 5 Free'; */
/* font-size: .8em; */
/* font-weight: bold; */
/* padding-right: 2px; */
/* content: '\f02b'; */
/* color: #fff; */
}
/*タグウィジェット*/
.tagcloud a,
.tags-links a {
line-height: 3em;
font-size: .8em;
text-decoration: none;
margin: 2px;
padding: 0 10px;
white-space: nowrap;
color: #333;
}
.tags-links a:hover,
.tagcloud a:hover {
text-decoration: underline;
}
.cat-links,
.tags-links,
.comment-link {
display: block;
}
.cat-links a,
.tags-links a,
.comment-link a {
text-decoration: none;
}
.cat-links a:hover,
.tags-links a:hover,
.comment-link a:hover {
text-decoration: underline;
}
.tagcloud a,
.tags-links a {
display: inline;
line-height: 1.5em;
border: 1px solid #333;
border-radius: 3px;
}
@media screen and (min-width: 37.5em) {
.tagcloud a,
.tags-links a {
display: inline;
}
.cat-links,
.tags-links,
.comment-link {
display: inline;
}
}
以上のように。使うであろう部品に対して、個々にスタイリングすることになります。
スタイリング(本文)
index.phpで出力される画面スタイリング

index.php画面では、個別ページ画面とのスタイリングを区別させる為に以下のように変更を加えます。
- articleタグ内にdivタグ not-singularクラスを追加する。
- サムネイル画像と文章を横並びにする為にdivタグwrap-contentクラスを追加する。
- divタグpost-thumbnailクラス内に出力する画像の大きさをindex.php画面と個別記事画面それぞれに設定する。(the_post_thumbnail())
- タブレット画面・PC画面において、画像と文章を横並びにスタイリングする。
template-parts/content.php
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<?php
if ( ! is_singular() ) :
?>
<div class="not-singular">
<?php endif; ?>
<header class="entry-header">
<?php
if ( is_singular() ) :
the_title( '<h1 class="entry-title">', '</h1>' );
else :
the_title( '<h2 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h2>' );
endif;
if ( 'post' === get_post_type() ) :
?>
<div class="entry-meta">
<?php
undersample_posted_on();
undersample_posted_by();
?>
</div><!-- .entry-meta -->
<?php endif; ?>
</header><!-- .entry-header -->
<?php
if ( ! is_singular() ) :
?>
<div class="wrap-contents">
<?php endif; ?>
<?php undersample_post_thumbnail(); ?>
<div class="entry-content">
<?php
if ( is_singular() ) : // **add**
the_content(
sprintf(
wp_kses(
/* translators: %s: Name of current post. Only visible to screen readers */
__( 'Continue reading<span class="screen-reader-text"> "%s"</span>', 'undersample' ),
array(
'span' => array(
'class' => array(),
),
)
),
wp_kses_post( get_the_title() )
)
);
else : // **add**
the_excerpt(); // **add**
endif; // **add**
wp_link_pages(
array(
'before' => '<div class="page-links">' . esc_html__( 'Pages:', 'undersample' ),
'after' => '</div>',
)
);
?>
</div><!-- .entry-content -->
<?php
if ( ! is_singular() ) :
?>
</div><!-- .wrap-contents -->
<?php endif; ?>
<footer class="entry-footer">
<?php undersample_entry_footer(); ?>
</footer><!-- .entry-footer -->
<?php
if ( ! is_singular() ) :
?>
</div><!-- .not-singular -->
<?php endif; ?>
</article><!-- #post-<?php the_ID(); ?> -->
inc/template_tags.php
function undersample_post_thumbnail() {
.
.
.
if ( is_singular() ) :
?>
<div class="post-thumbnail">
<?php the_post_thumbnail('full'); ?>
</div><!-- .post-thumbnail -->
<?php else : ?>
<a class="post-thumbnail" href="<?php the_permalink(); ?>" aria-hidden="true" tabindex="-1">
<?php
the_post_thumbnail(
'medium',
array(
'alt' => the_title_attribute(
array(
'echo' => false,
)
),
)
);
?>
</a>
<?php
endif; // End is_singular().
.
.
style.css
.post-thumbnail {
display: block;
text-align: center;
}
.entry-footer {
text-align: right;
}
.not-singular {
padding: 3%;
}
.entry-title {
font-size: 1.2rem;
}
@media screen and (min-width: 37.5em) {
.wrap-contents {
display: flex;
padding: 0;
}
.post-thumbnail {
text-align: left;
width: auto;
margin: 3%;
padding: 0;
}
.entry-title {
font-size: 2.0rem;
}
}
.pagination {
text-align: center;
font-size: 1.5rem;
margin: 50px 0;
}
.page-numbers {
padding: 2%;
}
single.phpで出力される画面スタイリング

single.php(個別ページ)では、サムネイル画面の大きさをfullサイズにしてあります。
その他
以下の箇所を修正・追加します。
404.php
.
.
<?php
wp_list_categories(
array(
'orderby' => 'count',
'order' => 'DESC',
'show_count' => 1,
'title_li' => '',
'number' => 10,
'depth' => -1, // add
)
);
?>
</ul>
</div><!-- .widget -->
使用頻度の高いhtmlタグ、divタグidセレクタ・classセレクタのスタイリング
投稿画面より設定できるものもありますが、以下のようなものをスタイリングしておくと、より利用しやすいページになるでしょう。下記タグ、クラス名は投稿画面の中で使われているブロックタイプで表示されるものです。
- h1 h2 h3などの見出しタグ
- ページネーション
- 引用 blockquoteタグ wp-block-quoteクラス
- コード preタグ wp-block-codeクラスcodeタグ
- ポエム preタグ wp-block-verseクラス
- コメントフォーム
テストデータをインポートして、次項の検証で示されている「テストデータによるチェック」も兼ねてスタイリングしてもよいでしょう。
screenshot.png作成

スクリーンショット
テーマの作成
テーマのスクリーンショットを作ります。ファイル名は screenshot.png と付け、テーマディレクトリに保存する。スクリーンショットはテーマのデザインを正しく反映し、PNG形式で保存する。推奨する画像サイズは 880×660。実際には 387×290 のサイズで表示されますが、画像サイズを2倍にすることで画面解像度の高い HiDPI ディスプレイにも対応できます。
注:場合により、 .jpg、.jpeg、.gif は 有効な拡張子 でスクリーンショットのファイル形式です。 (推奨ではありません).
スクリーンショット画像を設定しなくても、テーマとしては使用できます。但し、公に配布することを想定した場合は、設定すべきでしょう。
翻訳ファイル設置 国際化対応
テーマの国際化対応の仕組み
作成したテーマを多言語に対応させるためには、どうしたらいいのでしょうか。その国の言語ごとにテンプレートファイルを作るというやり方も考えられます。
但し、このやり方は、世界中にあるすべての言語に対して一つずつ作るということになり、凡庸的ではありません。
wordpressではこのような、多言語化に対応した以下のような仕組み( gettext ライブラリおよびツールを使用 )を備えております。何よりも、wordpressのコア部分そのものも、その仕組みで、各国に配布している次第です。
- ソースコードの翻訳関数を施された部分を抜き出し、一定の書式にしたがって翻訳リソースファイル(POTファイル)を作成します。このファイルの中身はテキストになっております。 pot拡張子がつきますが、 PowerPointのテンプレートファイル ではありません。
- 上記のファイルを元に、翻訳が必要な部分に翻訳を加え、poファイルを作成します。
- このファイルをコンパイル、バイナリ化し、moファイルを作成します。
- load_thema_textdomain関数により、テーマ翻訳ファイル(moファイル)を読み込み、翻訳されたものが表示されます。
テンプレートファイルに記述する翻訳関数
ファイルに記述する翻訳関数は主に以下のものがあります。ここでは、生成されたテンプレートファイル(404.phpなど)に記載されている例文を取り上げております。
__($message, $domain)
翻訳された$messageをreturnで返す
文字列を変数に入れたり、HTMLの属性値を設定する時に使います。
$domainはload_theme_textdomain関数で指定した第一引数であり、一般的にはテーマ名を設定しています。
esc_html__()は__()の第一引数$messageをwordpressのesc_html関数でエスケープ処理して翻訳されることを意味しております。以下、esc_html_e()においても、同様です。
template-parts/content.php
wp_link_pages(
array(
'before' => '<div class="page-links">' . esc_html__( 'Pages:', 'undersample' ),
'after' => '</div>',
)
);
languages/undersample.pot
#: template-parts/content-page.php:25
#: template-parts/content.php:53
msgid "Pages:" // 翻訳対象文字列.
msgstr "" // ここに翻訳された文字列がセットされる.
sprintf(__($message, $domain), $variable)
messageにパーセント文字を含めることにより、変数$variableを埋め込んだ翻訳になる。埋め込まれた変数は翻訳対象になるわけではありません。
テンプレートファイルにおいてパーセント文字は、下記のようにどういった内容のものに置き換えられるかをコメントアウトして記載する必要があります。
404.php
/* translators: %1$s: smiley */
$undersample_archive_content = '<p>' .
sprintf(
esc_html__(
'Try looking in the monthly archives. %1$s', 'undersample'
),
convert_smilies( ':)' ) // 絵文字smilies
) .
'</p>';
languages/undersample.pot
#. translators: %1$s: smiley
#: 404.php:49
msgid "Try looking in the monthly archives. %1$s"
msgstr ""
_e($message, $domain)
翻訳された$messageをechoで返す
404.php
<h2 class="widget-title"><?php esc_html_e( 'Most Used Categories', 'undersample' ); ?></h2>
languages/undersample.pot
#: 404.php:31
msgid "Most Used Categories"
msgstr ""
_x($message, $context, $domain)
同じmessage文字列で2つ以上の解釈にする場合に使われる。
contextはそれを識別する為に使われる文字列であります。
下記の場合は、これ以外に識別を要する同一メッセージがあるわけではないが、おそらく、同一のものが使われる可能性があるため、この関数を使用していると推測されます。
inc/template-tags.php
/* translators: used between list items, there is a space after the comma */
$tags_list = get_the_tag_list( '', esc_html_x( ', ', 'list item separator', 'undersample' ) );
languages/undersample.pot
#. translators: used between list items, there is a space after the comma
#: inc/template-tags.php:63
msgid ", "
msgstr ""
_n( $single, $plural, $number, $domain )
_nx($single, $plural, $number, $context, $domain)
$numberが単数のときは$singleの翻訳文字列、複数のときは$pluralの翻訳文字列が返ります。
comments.php
printf(
/* translators: 1: comment count number, 2: title. */
esc_html(
_nx( '%1$s thought on “%2$s”', '%1$s thoughts on “%2$s”', $undersample_comment_count, 'comments title', 'undersample' )
),
number_format_i18n( $undersample_comment_count ), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
'<span>' . wp_kses_post( get_the_title() ) . '</span>'
);
languages/undersample.pot
#. translators: 1: comment count number, 2: title.
#: comments.php:41
msgctxt "comments title"
msgid "%1$s thought on “%2$s”"
msgid_plural "%1$s thoughts on “%2$s”"
msgstr[0] "" // 単数形のときの文字列
msgstr[1] "" // 複数形のときの文字列
一般的な設置手順
- metaタグ charset属性UTF-8をセットする。
header.php <meta charset="<?php bloginfo('charset'); ?>">
- htmlタグのlang属性をセットする。
header.php <html <?php language_attributes(); ?>>
- テンプレートファイル、関数ファイル内の翻訳して出力させる部分に翻訳関数を適用させる記述をします。
- テーマフォルダ直下に「languages」フォルダを作成します。
- テーマ翻訳ファイル(.moファイル)を読み込む関数を定義します。functions.phpの先頭付近に記述します。
function undersample_setup() { load_theme_textdomain( 'undersample', get_template_directory() . '/languages' ); .
- 翻訳リソースファイル(POTファイル)を作成します。
書式については、wp-contents/languages/ja.poファイルを参考にして記述します。 - 作成した翻訳リソースファイル(POTファイル)のmsgstr セクションを自分の言語に翻訳しpoファイルを作成します。 翻訳を記述したものをロケール名poファイル(ja.po)として保存します。
- msgfmt ツールを使用してpotファイルをバイナリ化して、moファイルを作成します。 msgfmt コマンドは、msgfmt -o filename.mo filename.po です。
- ページを表示し、適切に翻訳されているか確認します。
underscores + Poeditを使った設置手順
アンダースコアーの翻訳関数の記述をそのまま使用した場合は、languageフォルダー内のpotファイルをそのまま利用すればいいので、上記1~6手順は済んでいることになります。残りの手順はPoeditというフリーソフトを使用して、作成するのが一般的になっております。
翻訳関数を使って新たに記述を加えたり、変更した場合は、新しくpotファイルを作らなければいけません。その手順は、以下のようになります。
1. Poeditをダウンロードインストールします。特別な設定はありません
2. Poeditを使って、potファイルを作成します。但し、生成されるのはpoファイルとなっております。このpoファイルに翻訳を記述することになります。
空のpoファイルを生成する




続けて、ソースコード読み込み設定をする。







- 生成されたja.poファイル
languages/ja.po
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2021-06-28 15:31+0900\n"
"PO-Revision-Date: 2021-06-28 17:04+0900\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: ja\n" // 日本語ロケールに翻訳することを意味する.
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.4.2\n"
"X-Poedit-Basepath: ..\n"
"Plural-Forms: nplurals=1; plural=0;\n" // 日本語では単数複数の区別がないので、_nx,_xの解釈は一つになることを意味する.
"X-Poedit-KeywordsList: __;_e;_nx;esc_html_e;esc_html__;esc_html_x\n" // 読み込まれた翻訳関数.
"X-Poedit-SearchPath-0: .\n"
.
.
#: 404.php:30
msgid "Most Used Categories"
msgstr ""
.
.
#: 404.php:49
#, php-format
msgid "Try looking in the monthly archives. %1$s"
msgstr ""
.
.
#: comments.php:41
#, php-format
msgid "%1$s thought on “%2$s”"
msgstr ""
.
.
#: inc/template-tags.php:63 inc/template-tags.php:70
msgid ", "
msgstr ""
.
.
#: template-parts/content-page.php:25 template-parts/content.php:65
msgid "Pages:"
msgstr ""
- 翻訳します。

wordpress本体にある翻訳ファイル
wp-content/
|-languages/
|-plugins/
|-themes/
|-
|-ja.po // 翻訳ファイル
|-
wp-includes/
wp-includesフォルダーに収められている関数は、テーマ内でテンプレートタグとして使用されています。この関数内での画面出力コードが翻訳関数を伴っている場合は、上図のja.poファイルが翻訳ファイルになります。
検証
wordpressのテーマとしての妥当性をチェックする方法として、以下のようなものが考えられます。
- テストデータを入れてのチェック
- アクセスビリティのチェック
- クロスブラウザチェック
- ワードプレスとしてのコーディングになっているかのチェック
公式テーマとして登録する為には、これらの作業は必須と思われますが、そこまでは考えないまでも、品質向上のためには避けられない項目であると思います。
テストデータを入れてのチェック
サンプルデータを投稿画面から入力する」項目と重複しますが、テスト用に用意されたサンプルデータを使ってテーマをテストします。
データの入手方法・テスト手順についてはテーマユニットテストページを参考に実施しました。

テストの手順については、上記のページもしくは、画面内に記載されております。
手順が前後しますが、スタイリングは、このテストデータを使って行っても良いでしょう。
アクセスビリティチェック
ウェブアクセスビリティとは
Webコンテンツ・アクセシビリティに関する指針 (W3C)では以下のように定義しております。
Webアクセシビリティとは、障害を持つ人々がそれらを使用できるようにWebサイト、ツール、およびテクノロジーが設計および開発されていることを意味します。
,,,,,
Webアクセシビリティは、障害のない人々にもメリットがあります。…..Webアクセシビリティの概要 (WAI)
アクセスビリティを考えたページとは、障害を持つ人にとって使いやすいものであるべきということのようです。そのようなページは、たとえ、障害のあるなしに係わらず、使いやすいものになるということでしょう。
見易さ、聞きやすさ、操作しやすさは、老若男女問わず、ウェブ製作者にもとめられているものとして認識すべきものと考えます。
WAI-ARIAについて
WAI-ARIA は W3C によって定められた仕様で、アクセスビリティ向上のために、html文に追加的な属性として意味を付け加えるものであります。特に視覚障害者がwebページを見る際に、この仕様が、スクリーンリーダーによって解釈され、音声によるアナウンスにつながるといった、有用なものとして構築されております。
WAI-ARIA 「6.6. Definitions of States and Properties (日本語訳)」
NVDAについて
詳細についてはNVDA日本語チームサイトをみていただきたい。
以下、主な特徴と使い方について、簡単にリストアップしてみました。
- NVDA (Non Visual Desktop Access) は、無料の Windows 用スクリーンリーダーです。
- キーボードのみで操作することを前提に作られております。
- USBメモリーなど、持ち運びのできる記憶装置に NVDAをインストールしポータブル版として利用できます。
- 日本語版は日本語で音声読みあげをしますが、英語が混じると、一語ずつ読み上げることになり、聞きづらくなります。
- 起動はCtrl + Alt + Nキー、終了はNVDA(Insert) + Qになります。
- フォーカス・モード(フォーム入力)とブラウズ・モード(web閲覧時)があり、切り替えはNVDA(Insert) + spaceです。
- ヘルプ表示はNVDA(Insert) + 1になります。
- 一行ずつ読ませる [下矢印][上矢印] 一文字ずつ読ませる [右矢印][左矢印]により、文章を閲覧することになります。
- 見出し [H] リンク [K] リスト [L]・リスト項目 [I] テーブル [T] [下矢印]キーを押すと、次の(右の)セルに移動 フォームフィールド [F] (テキストフィールド)[E] コンボボックス [C] チェックボックス [X] ラジオボタン [R] 画像 [G]など目的コンテンツにジャンプできます。
アクセスビリティに係わるコードをNVDAを使って検証
スクリーンリーダ使用時だけフォーカス・アナウンスする
single.php テストデータ 「テンプレート: 先頭固定表示」タイトルのページ
the_post_navigation(
array(
'prev_text' => '<span class="nav-subtitle">' . esc_html__( 'Previous:', 'undersample' ) . '</span> <span class="nav-title">%title</span>',
'next_text' => '<span class="nav-subtitle">' . esc_html__( 'Next:', 'undersample' ) . '</span> <span class="nav-title">%title</span>',
'screen_reader_text' => esc_html__('Post Navigation', 'undersample' ), // 追加
)
);
出力されるhtml
<nav class="navigation post-navigation" role="navigation" aria-label="Post Navigation">
<h2 class="screen-reader-text">Post Navigation</h2>
<div class="nav-links"><div class="nav-previous"><a href="http://localhost/wp17/2012/01/template-password-protected/" rel="prev"><span class="nav-subtitle">Previous:</span> <span class="nav-title">テンプレート: パスワードで保護されたページ</span></a></div><div class="nav-next"><a href="http://localhost/wp17/2012/01/template-paginated/" rel="next"><span class="nav-subtitle">Next:</span> <span class="nav-title">テンプレート: ページ分け</span></a></div></div>
</nav>
style.css
/* Text meant only for screen readers. */
.screen-reader-text {
border: 0;
clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(50%);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute !important;
width: 1px;
word-wrap: normal !important;
}

Hキーまたは↓↑キーでページを辿り、1px四方の枠で表示され、音声アナウンスされる。
role=”navigation”はスクリーンリーダーがnavigationとして認識させる、ランドマークとして定義されております。
aria-label=”Post pagination“は、html文書におけるalt属性と同じ様な振る舞いをするものであり、代替テキストのようにその値が読み上げられることを定義しております。
メニューアナウンスをとばすスキップリンク
header.php
<a class="skip-link screen-reader-text" href="#primary"><?php esc_html_e( 'Skip to content', 'undersample' ); ?></a>
出力されるhtml
<a class="skip-link screen-reader-text" href="#primary">Skip to content</a>
.
.
<main id="primary" class="site-main"> // リンク先
style.css
.screen-reader-text {
border: 0;
clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(50%);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute !important;
width: 1px;
word-wrap: normal !important;
}
.screen-reader-text:focus {
background-color: #f1f1f1;
border-radius: 3px;
box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.6);
clip: auto !important;
clip-path: none;
color: #21759b;
display: block;
font-size: 0.875rem;
font-weight: 700;
height: auto;
left: 5px;
line-height: normal;
padding: 15px 23px 14px;
text-decoration: none;
top: 50%; // change 5px --> 50%
width: auto;
z-index: 100000;
}
/* Do not show the outline on the skip link target. */
#primary[tabindex="-1"]:focus {
outline: 0;
}

スキップリンクとは、スクリーンリーダーでウェッブページを見ているときに、メインナビゲーション手前で表示される、リンクです。キーボードのタブキーでフォーカスされるときに表示されるので、スクリーンリーダーを利用しなくても表示することが出来ます。
同じサイトのページ間を行き来する場合に、スクリーンリーダーがページを替えるたびにメインナビゲーションでの音声アナウンスをする煩わしさを回避する為に、設置してあります。リンクさせると、指定の位置(ここではid=#primaryである本文先頭)にジャンプします。
上記も同じ screen-reader-textクラス を使っておりますが、スキップリンクでは、aタグを使っているので、フォーカス機能が動作可能になり、screen-reader-text:focusの擬似要素が適用され、画面表示になる仕組みを使っております。
アコーディオン・トグルコンテンツまたはメニューの開閉状態を知らせる
header.php
<nav id="site-navigation" class="main-navigation">
<button class="menu-toggle" aria-controls="primary-menu" aria-expanded="false"><?php esc_html_e( 'Primary Menu', 'undersample' ); ?></button>
<?php
wp_nav_menu(
array(
'theme_location' => 'menu-1',
'menu_id' => 'primary-menu',
)
);
?>
</nav><!-- #site-navigation -->
js/navigation.js
// Toggle the .toggled class and the aria-expanded value each time the button is clicked.
button.addEventListener( 'click', function() {
siteNavigation.classList.toggle( 'toggled' );
if ( button.getAttribute( 'aria-expanded' ) === 'true' ) {
button.setAttribute( 'aria-expanded', 'false' );
} else {
button.setAttribute( 'aria-expanded', 'true' );
}
} );
// Remove the .toggled class and set aria-expanded to false when the user clicks outside the navigation.
document.addEventListener( 'click', function( event ) {
const isClickInside = siteNavigation.contains( event.target );
if ( ! isClickInside ) {
siteNavigation.classList.remove( 'toggled' );
button.setAttribute( 'aria-expanded', 'false' );
}
} );
出力されるhtml
<nav id="site-navigation" class="main-navigation">
<button class="menu-toggle" aria-controls="primary-menu" aria-expanded="false">Primary Menu</button>
<div id="primary-menu" class="menu">
<ul>
<li>....</li>
.
.
</ul>
</nav><!-- #site-navigation -->
style.css
/* Small menu. */
.menu-toggle,
.main-navigation.toggled ul {
display: block;
}
@media screen and (min-width: 37.5em) {
.menu-toggle {
display: none;
}
.
.
}
メニューなどの開閉状態をスクリーンリーダーに認識させるには、WAI-ARIAの構文aria-expanded要素を使用します。その属性として、false(閉じた状態)、true(開いた状態)を定義します。上記のように、開いた状態を定義しているulタグに対してではなく、開閉アクションになる、button要素に対して、設定します。その関連付けを示す構文がaria-controls=
“…”となります。ここでは、このul要素につけられているidがその値になります。
この設定により、NVDAでは、開閉されているか否かを音声アナウンスします。
尚、開閉をコントロールするファイルとして、ここでは、navigation.jsが設置されております。ここで、aria-expandedの値である、false/trueをコントロールしております。
フォームのアクセスビリティ向上(コメントフォームの場合)
comment.php
comment_form();
出力されるhtmlの一部
<div class="reply">
<a rel='nofollow' class='comment-reply-link' href='http://localhost/wp17/2021/07/hello-world/?replytocom=1#respond' data-commentid="1" data-postid="1" data-belowelement="div-comment-1" data-respondelement="respond" data-replyto="WordPress コメントの投稿者 に返信"
aria-label='WordPress コメントの投稿者 に返信'>返信</a>
<!-- ① タブ・矢印キーで「コメントの投稿者 に返信」アナウンス -->
</div>
</article><!-- .comment-body -->
</li><!-- #comment-## -->
</ol><!-- .comment-list -->
<h3 id="reply-title" class="comment-reply-title">コメントを残す <small><a rel="nofollow" id="cancel-comment-reply-link" href="/wp17/2021/07/hello-world/#respond" style="display:none;">コメントをキャンセル</a></small></h3>
<!-- ② H・矢印キーで「コメントを残す」アナウンス -->
<form action="http://localhost/wp17/wp-comments-post.php" method="post" id="commentform" class="comment-form" novalidate>
<p class="comment-notes">
<span id="email-notes">メールアドレスが公開されることはありません。</span>
<span class="required">*</span> が付いている欄は必須項目です
</p>
<p class="comment-form-comment">
<label for="comment">コメント</label>
<!-- ③ タブ・矢印キーで「コメント」と「必須」であることをアナウンス -->
<textarea id="comment" name="comment" cols="45" rows="8" maxlength="65525" required="required"></textarea>
</p>
<p class="comment-form-author">
<label for="author">名前 <span class="required">*</span></label>
<!-- ④ タブ・矢印キーで「名前」と「必須」であることをアナウンス -->
<input id="author" name="author" type="text" value="" size="30" maxlength="245" required='required' />
</p>
<p class="comment-form-email">
<!-- ⑤ タブ・矢印キーで「メール」と「必須」と ⑥ 「メールアドレスが公開されることはありません」アナウンス -->
<label for="email">メール <span class="required">*</span></label>
<input id="email" name="email" type="email" value="" size="30" maxlength="100" aria-describedby="email-notes" required='required' />
</p>
<p class="comment-form-url">
<!-- ⑦ タブ・矢印キーで「サイト」とアナウンス -->
<label for="url">サイト</label>
<input id="url" name="url" type="url" value="" size="30" maxlength="200" />
</p>
<p class="comment-form-cookies-consent">
<!-- ⑧ タブ・矢印キーで「次回のコメントで使用するためブラウザーに自分の名前、メールアドレス、サイトを保存する」アナウンス -->
<input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes" />
<label for="wp-comment-cookies-consent">次回のコメントで使用するためブラウザーに自分の名前、メールアドレス、サイトを保存する。</label>
</p>
<p class="form-submit">
<!-- ⑨ タブ・矢印キーで「コメントを送信」アナウンス-->
<input name="submit" type="submit" id="submit" class="submit" value="コメントを送信" />
<input type='hidden' name='comment_post_ID' value='1' id='comment_post_ID' />
<input type='hidden' name='comment_parent' id='comment_parent' value='0' />
</p>
</form>
</div><!-- #respond -->
ここで使われているスクリーンリーダー音声アナウンスに係わる記述は以下のようなものです。
- aria-label=’文字列’ タブ・矢印キーで文字列がアナウンスされる。
- <h3>見出し</h3> H・矢印キーで見出しがアナウンスされる。②
- <label for=”id名”>文字列</label> <textarea or input id=”id名”…….required=”required”></textarea> タブ・矢印キーで文字列必須とアナウンスされる。③④⑤⑦⑧
- <input type=”email”> タブ・矢印キーで入力内容がemail書式に合致しない場合、アナウンスされる。 aria-describedby=”ターゲットid名” <span id=”ターゲットid名”>文字列</span> タブ・矢印キーでターゲットid名の文字列がアナウンスされる ⑥
- <input type=”submit”……value=”文字列”> タブ・矢印キーで文字列がアナウンスされる。⑨
送信後。失敗した場合のhtml表示
.
.
<title>コメント送信失敗</title>
.
.
<div class="wp-die-message"><p><strong>エラー</strong>: 必須項目 (名前、メールアドレス) を入力してください。</p></div>
<p><a href='javascript:history.back()'>« 戻る</a></p>
<!-- コメント送信失敗 戻るとアナウンスされる -->
<title>コメント送信失敗</title> <a href=’….’>戻る</a> コメント送信失敗 戻るとアナウンスされる
送信ボタンを押して、無事に送信されたことに対するアクションはありません。
moreクイックタグの扱いについて
moreクイックタグについて、codexでは以下のように定義しております。
本文中に<!–more–>クイックタグがある場合、先頭からそのクイックタグまでの内容のみを抜粋として表示します。 ただし単一投稿ページ(パーマリンクで投稿を特定したページ)では、抜粋のみでなく本文をすべて表示します。 the_content() テンプレートタグは の表示方法を決めるパラメータを受け取り、投稿の全文を「続けて読む」ためのリンクを表示する、という設計になっています。
moreタグについて
indexページ(ここではindex.phpなど、!singular()==trueとなるページ)における、記事表示に、the_content()テンプレートタグを使用した場合、moreタグが有効になるということが、上記の文で示されております。
改変前のunderscoresのコードとサンプルデータを使ったhtml出力は以下のようになります。
template-parts/content.php
the_content(
sprintf(
wp_kses(
/* translators: %s: Name of current post. Only visible to screen readers */
__( 'Continue reading<span class="screen-reader-text"> "%s"</span>', 'undersample' ),
array(
'span' => array(
'class' => array(),
),
)
),
wp_kses_post( get_the_title() )
)
);
indexページ「テンプレート: More タグ」記事のhtml出力
<p>
<a href="http://localhost/wp17/2012/03/template-more-tag/#more-996"
class="more-link">Continue reading<span class="screen-reader-text">
“テンプレート: More タグ”</span>
</a>
</p>
この場合は、「Continue reading」という語句がフォーカスされ、スクリーンリーダーでは、タブキー・矢印キーにより、語句がアナウンスされる。この語句をクリックすると、以下、後続の文が表示される仕組みになっております。
但し、このテーマでは、index.phpをトップページとしており、the_content()をthe_excerpt()にかえて、抜粋表示としているので、moreクイックタグの使用は、有効になりません。the_content()はシングルページにのみ、使用することにしているので、the_content()のパラメータコードは削除することにしてあります。
抜粋表示におけるアイキャッチ画像
このテーマの抜粋表示とは、index.phpで表示される画面表示を指します。
ここではtemplate-tags.phpの中にある、undersample_post_thumbnail()関数を使って、画像を表示させております。以下、そのphpコード、出力htmlと音声アナウンスの関係をみていきたいとおもいます。
inc/template-tags.php
function undersample_post_thumbnail() {
.
.
if ( is_singular() ) :
?>
<div class="post-thumbnail">
<?php the_post_thumbnail( 'full' ); ?>
</div><!-- .post-thumbnail -->
<?php else : ?>
<a class="post-thumbnail" href="<?php the_permalink(); ?>" aria-hidden="true" tabindex="-1">
<?php
the_post_thumbnail(
'medium',
array(
'alt' => the_title_attribute(
array(
'echo' => false,
)
),
)
);
?>
</a>
<?php
endif; // End is_singular().
.
.
}
index.php(!is_singular())での表示
<!-- アイキャッチ画像は表示されるが、フォーカス・アナウンスは無視される。 -->
<a class="post-thumbnail" href="http://localhost/wp17/2021/07/tesuto/"
aria-hidden="true" tabindex="-1">
<img width="640" height="480"
src="http://localhost/wp17/wp-content/uploads/2011/01/canola2.jpg"
class="attachment-medium size-medium wp-post-image" alt="tesuto"
loading="lazy" />
</a>
single.php(is_singular())での表示
<!-- アイキャッチ画像は矢印キーとGキーでアナウンスされる -->
<div class="post-thumbnail">
<img width="640" height="480"
src="http://localhost/wp17/wp-content/uploads/2011/01/canola2.jpg"
class="attachment-full size-full wp-post-image" alt="canola" loading="lazy" />
抜粋表示の時は、アイキャッチ画像のアナウンスはしませんが、本文表示の場合は、アナウンスするという仕組みになっております。
コード上では、aria-hiddenをtrue、 tabindexを-1で要素を隠し、キーボードフォーカスさせない属性を指定することにより、この仕組みを実現させております。
画像の説明をアナウンスさせる
投稿入力欄で、画像ブロックを選択し、記事に挿入すると、figureタグで取り込まれます。imgタグ単独と違い、figcaptionタグが使えるので、キャプションとして、説明文を挿入することが出来ます。

<!-- 矢印キーで代替テキスト、キャプションがアナウンスされる -->
<figure class="wp-block-image size-large">
<img loading="lazy" width="1600" height="1200"
src="http://localhost/wp17/wp-content/uploads/2008/06/100_5540.jpg"
alt="Golden Gate Bridge" class="wp-image-755"
srcset="http://localhost/wp17/wp-content/uploads/2008/06/100_5540.jpg 1600w,
http://localhost/wp17/wp-content/uploads/2008/06/100_5540-768x576.jpg 768w,
http://localhost/wp17/wp-content/uploads/2008/06/100_5540-1536x1152.jpg 1536w,
http://localhost/wp17/wp-content/uploads/2008/06/100_5540-1200x900.jpg 1200w"
sizes="(max-width: 1600px) 100vw, 1600px" />
<figcaption>Golden Gate Bridge caption</figcaption>
</figure>
画像の説明は、alt属性値のみでも事足りますが、少し長い説明文をつけたい場合や、音声アナウンスとしてではなく、視覚的に説明が必要な場合は有用なものとなります。
html5にはない、要素の役割を示す
header.php
get_search_form();
出力html
<div class="search-form">
<form role="search" method="get" class="search-form" action="http://localhost/wp17/">
<label>
<span class="screen-reader-text">検索:</span>
<input type="search" class="search-field" placeholder="検索 …" value="" name="s" />
</label>
<input type="submit" class="search-submit" value="検索" />
</form>
</div>
html5ではnav(ナビゲーション) article(記事の括り) main(本文)など、html文の中で、文書構造を表すタグが追加されました。スクリーンリーダーはこれらを認識し、アナウンスします。これとは別に、wai-ariaにおいて、roleという、html5よりもさらに厳密にタグ要素の意味論的に細分されたものがあります。上記のような検索フォームであることを示す、ロール属性は、aria独自のものであり、より細かい情報をスクリーンリーダーに伝える為に、使用されます。これをどのように活用するかは、スクリーンリーダーにおける処理に委ねられますが、アナウンスするという点では、roleを定義しなくても、事足りるようです。但し、古いバージョンのブラウザなどは、html5を認識しないので、有用な場合があるようです。
role属性はその他、いろいろな役割を持つものが、wai-ariaで定義されております。
アイコンフォントのアクセスビリティ
ここでは取り上げていませんが、Font Awesome などのアイコンを使って、ページを装飾している場合があります。
wordpressコーディング標準ハンドブックでは、以下のようにする必要があると、書かれております。
アイコンフォントの場合、フォントアイコン自体にaria-hidden属性があり、隣接する要素にscreen-reader-textが含まれている必要があります。
コーディング標準ハンドブック
アイコンが装飾用の場合、フォントアイコンには引き続きaria-hidden
属性が含まれている必要がありますが、スクリーンリーダーのテキストは省略されている必要があります。
テンプレートタグ内の screen-reader-text
クラスの編集
テンプレートタグの中には、screen-reader-text
というパラメータを設置できるものがあります。これに 値を設置することによって、スクリーンリーダー使用時にアナウンスさせることが出来ます。
single.php
.
.
the_post_navigation(
array(
'prev_text' => '<span class="nav-subtitle">' . esc_html__( 'Previous:', 'undersample' ) . '</span> <span class="nav-title">%title</span>',
'next_text' => '<span class="nav-subtitle">' . esc_html__( 'Next:', 'undersample' ) . '</span> <span class="nav-title">%title</span>',
'screen_reader_text' => esc_html__('Post Navigation', 'undersample' ), )
);
.
.
上記は前後の記事へのリンクを表示するテンプレートタグです。screen_reader_textパラメータを設置することにより、アナウンスされる値を設置することが出来ます。尚、設置前は、本体翻訳ファイルにより「投稿ナビゲーション」という値になっておりましたが、これを一旦「Post Navigation」とし、あとは、翻訳ソフトPoeditにより、適切な日本語に翻訳すれば、良いでしょう。
テキストの読みやすさ
文字の大きさ・行間の幅については、テストデータにある、「マークアップ: HTML タグとフォーマット」で確認できます。老眼の人にとっては、文字の大きさは、気にかかるところでありますが、主要ブラウザでは、画面右上の設定ボタンを押せば、画面ズーム調整の設定変更項目がありますので、コード上で特別な操作は必要ないと思われます。
弱視・色覚異常者への配慮として、「文字がはっきり見える」ということが求められると思います。ページのテキストの見易さを計測する尺度としてコントラスト比というものがあります。テキストそのものの色とその背景色とを比較するものです。以下のツールを利用すると簡単に計測することが出来ます。
2色のコントラスト比を計算し評価するツール ColorTester
W3Cのウェブコンテンツ・アクセシビリティ・ガイドライン(WCAG 2.0)では、少なくとも 4.5:1 、大きい文字では少なくとも 3:1のコントラスト比としています。
クロスブラウザチェック
クロスブラウザテストとは
作成したwebサイトの表示に係わるもの、webアプリケーションとしての処理に係わるものをブラウザごとにチェックすることであります。正しくhtml出力されていれば、最新のブラウザ間の違いは少なくなったので、最新のものを想定するして、表示よりも動作の違いにウエイトをおいて見ていく必要があります。
まずは、htmlタグが正しく設置されていることが前提となります。
最新でないものを加えるならば、どのバージョンのもの以降にするのかを線引きする必要があります。 レスポンシブデザインであれば、スマートフォン、タブレットの表示と動作をチェックする必要があります。
アクセスビリティにも関係しますが、テキスト表示しか出来ないブラウザでも、適切な表示ができるかどうかも考えなければいけません。
対象ブラウザの選定
すべてのバージョン・すべてのブラウザをチェック対象とするのは現実的でありません。wordpress本家では動作環境について以下のように述べております。
2021年7月にリリースされたwordpress5.8では Internet Explorer 11 はサポートされなくなりました。現在、IE11 をお使いの方は、Google Chrome、Mozilla Firefox、Safari、Microsoft Edge などの最新のブラウザーに切り替えることを強くおすすめします。
wordpress日本語サポートInternet Explorer 11 サポート終了

古いバージョンのものは使用している人も少なく、対象外にすべきでしょう。 IE11 はwordpressではサポート外なので、これも除外対象になります。
以下のものに絞られると思います。
- 主要ブラウザ Google Chrome、Mozilla Firefox、Safari、Microsoft Edge のWindows版とMac版
- 主要スマートフォン・タブレット端末 iOS Android
- テキストブラウザ
チェックすべき項目
特に、チェックが必要な項目は以下のように考えます。
- 全体のレイアウト、pc。タブレット、スマホ画面にコンテンツが適切に配置されているか。
- テキストの大きさ
- タブレット・スマホ画面でのリンク領域が適切に確保されており、窮屈になっていないか
- ナビゲーションメニュー、特に2階層以上の場合に適切に動作しているか
- javascriptやアニメーションなどを使用している場合に各端末が滞りなく動作しているか。
- 送信フォーム等、サーバーとやり取りするプログラムが適切に動作・表示処理されているかどうか
- 障害者にも配慮されているか。
クロスブラウザチェックツール
オンライン上でクロスブラウザをテストするツールがあります。
参考:2021年のトップ10クロスブラウザテストツール(最新ランキング)
レスポンシブデザインをチェックするには、Chrome・FireFoxなどのブラウザの開発ツールに主要メーカーのタブレット・スマートフォン画面を表示する機能が利用できます。
Lynxによるアクセスビリティチェック

Lynxは、テキストベースのブラウザです。pcunix・mac・windows・msdosなどで動作します。もちろん、最新のブラウザでも大丈夫です。但し、テキスト表示しか出来ません。画像は代替テキストで表示されます。キーボードでの操作になります。
テキストしか表示されないのに、使用する意味があるだろうかと思われるでしょう。
ところが、視覚障害の方がこれを必要としています。余計な画像表示が無く、軽快に動きます。スクリーンリーダーで音声アナウンスもできます。
シンプルであるがゆえに、サイトの文章構成をチェックするのに都合がいいです。そういう観点からアクセスビリティをチェックするのに使用できるツールであると思います。
ワードプレスコーディング標準チェック
ワードプレスには、ワードプレスコーディング標準があります。テーマを作成するに当たって、以下の仕様に沿って、製作する必要があります。phpソースコードは 、PHPにおける基本的なコーディング標準である PSR-1 とは異なるものがあるので注意が必要です。
また、ドキュメント(コメントとしてソースに記載したもの)はインラインドキュメテーション標準というものがあります。
PHP_CodeShifferによるコードチェック
PHP_CodeShifferはphpで書かれたコードがphpのコーディング規約に合致しているかどうかをチェックしてくれるツールです。
ツールの詳細はPHP_CodeShifferサイトを参照していただき、ここでは割愛いたします。
製作したテーマをこのツールを使って誤りチェックしたものは、以下のように表示されます。
コマンドライン
C:\target_directory>phpcs -p -s -v --standard=WordPress content.php
表示
----------------------------------------------------------------------
FOUND 3 ERRORS AFFECTING 3 LINES
----------------------------------------------------------------------
45 | ERROR | [x] Line indented incorrectly; expected 2 tabs, found
| | 1
| | (Generic.WhiteSpace.ScopeIndent.IncorrectExact)
46 | ERROR | [x] Line indented incorrectly; expected at least 3
| | tabs, found 2
| | (Generic.WhiteSpace.ScopeIndent.Incorrect)
59 | ERROR | [x] Line indented incorrectly; expected at least 4
| | tabs, found 2
| | (Generic.WhiteSpace.ScopeIndent.Incorrect)
----------------------------------------------------------------------
PHPCBF CAN FIX THE 3 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------
Time: 349ms; Memory: 10MB
英語で出力されます。以下、その内容と修正したものを一部ピックアップしてあります。
Doc comment short description must start with a capital letter(Generic.Commenting.DocComment.ShortNotCapital) 短いディスクリプションコメントの最初の一文字は大文字にします。
doc domment —>Doc comment Array double arrow not aligned correctly;…(WordPress.Arrays.MultipleStatementAlignment.DoubleArrowNotAligned) =>記号のインデントをそろえて下さい。=>記号の後ろは半角スペースを入れます。
間違い
array(
'post-details' => array(
'stylesheet' => 'undersample-style',
'date' => '.posted-on',
正しい
array(
'post-details' => array(
'stylesheet' => 'undersample-style',
'date' => '.posted-on',
Expected 1 spaces after opening bracket; 0 found(PEAR.Functions.FunctionCallSignature.SpaceAfterOpenBracket) Expected 1 spaces before closing bracket; 0 found(PEAR.Functions.FunctionCallSignature.SpaceBeforeCloseBracket) 配列や関数呼び出しの際の引数において、要素と引数の前後には常にスペースを入れてください。
the_post_thumbnail(‘full’); —>the_post_thumbnail( ‘full’ ); Found precision alignment of 1 spaces.(WordPress.WhiteSpace.PrecisionAlignment.Found)
Expected 5 space(s) before asterisk; 4 found.(Squiz.Commenting.DocCommentAlignment.SpaceBeforeStar)
There must be no blank lines after the function comment.(Squiz.Commenting.FunctionComment.SpacingAfter)
関数を定義するには、関数のドキュメンテーションコメントが必要となってきます。コメント終了タグ、*の位置関係は以下のとおりにする必要があります。コメント終了タグの下の行はつめて記述してください。
間違い
/**
Function of display social menu.
*/
function undersample_social_menu()
正しい
/**
* Function of display social menu.
*/
function undersample_social_menu()
上記のコーディング基準の一部を改変したい場合、たとえばドキュメントの書式を変えたい、一部のコーディング基準は適用しない、適用範囲を指定したいなどは、phpcs:ignoreが使用できます。
comments.php
number_format_i18n( $undersample_comment_count ), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
上記はphpcsでコーディングチェックをするとエラーがでる箇所をエラー回避する構文になっております。echo出力直前にセキュリティエスケープしなけらばエラーになる仕様になっているので、関数内部で既にエスケープ処理されているなどの場合は、これを無視しても構わないということで使われております。
グローバルな設定は、phpcsの設定ファイルの雛形であるphpcs.xml.distファイルとして、undersampleのフォルダーに入っていますので、これを編集して、phpcs.xmlファイルとして設置できます。
参照: PHP_CodeSniffer @ GitHub phpcs の ignore 新構文
さらなる機能強化のために
ここでは、最低限の機能しか入れていないので、物足りなさを感じるテーマとなっております。以下に示す機能を付け加えれば、さらに、テーマとして充実するでしょう。
- webフォント・アイコン設置
- ツイッターガード等snsとの連係
- パンくずリスト設置
- カスタムフィールドの活用
- 構造化マークアップ
日本語の場合、プラグインとしてWP Multibyte Patch を入れる必要があります。
尚、ここで製作されたテーマのコードはgithubに入れてありますので、自己責任にてご自由に使用されても良いです。