WordPress 基本事項まとめ

## 基本系の内容
### WordPress Codes
* [英語](http://codex.wordpress.org/)
* [英語リファレンス](https://developer.wordpress.org/reference/)
* [英語関数リファレンス](https://developer.wordpress.org/reference/functions/)
* [日本語](https://wpdocs.osdn.jp/)
* [日本語テンプレートタグ（テーマファイルでよく使われる関数を**テンプレートタグ**と呼ぶ）](https://wpdocs.osdn.jp/テンプレートタグ)
* [日本語その他関数（テンプレートタグ以外）](https://wpdocs.osdn.jp/関数リファレンス)
* [非推奨関数一覧(バージョンアップ等で将来使用出来なくなる可能性のあるもの等）](https://wpdocs.osdn.jp/カテゴリ:非推奨)
* [セキュリティ、データ検証](https://wpdocs.osdn.jp/データ検証)

### WordPressの基本
* WP（WPテーマ)は**index.php**と**style.css**があれば動作する
* ```wp_head()```と```wp_body_open()```を必ず書く。
**wp_head()** : ```</head>```の直前に記入する。アクションフックを登録する関数。これを書かないとスタイルシートやJavaScriptが読み込まれない、プラグインが正常に動作しないといった事が起きる可能性が出てくる。
※他にもフッターがある場合、```wp_footer()```を```</body>```の直前に書く。

**wp_body_open()** : **<body>の直後に記入する。**これもアクションフックを登録する関数。<body>の直後にJavaScript等を出力したい場合に使う。
* 使用テーマのトップページを最新の投稿にするか、固定ページにするか、管理画面の「設定>表示設定」から変更出来る。
![スクリーンショット 2022-04-13 14.23.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/0eec09c0-2a3b-b6ff-d532-1f72d94ef8f2.png)
* phpのコードは通常```<?php ?>```の様に**末尾に「?>」を書くが、ファイルの末尾の場合は「?>」の後に不要な改行などがあるとエラーの原因になる事がある為、書かないのが一般的。


### WordPressの構成
例）
* トップページ（index.php)　**必須**
* style.css **必須**
* 固定ページ（page.php)
* ヘッダー(header.php)
* フッター（footer.php)
* アーカイブ（archive.php)※アーカイブは記事一覧ページの事
* 個別投稿ページ（singular.php)
* 検索結果ページ（search.php)
```the_category()```や```the_tags()```で作成したリンクをクリックするとこのページが使用されたページへ遷移する。
* 個別投稿（single.php)
* サイドバー（sidegar.php)
上記の様に役割によってファイルを分けて作成する。

#### style.css
* sytle.cssにはCSSの記述だけでなく、このWPテーマについての詳細説明をページの最初でコメントにて、記述するルールがある。これが抜けていると、管理画面の「外観>テーマ」で作成したテンプレートがテーマ一覧で表示されない。
* ```php
例）
Theme Name: Sample theme
Author: tanaka taro
Description: Sampletheme for PHP . Forked from Twenty Nineteen .
Requires at least: WordPress 5.2
Version: 1.4
License: hogehoge
Template: oyaTemplate //子テーマを作る場合には親テーマのフォルダ名を記載する。
```

#### singular.php
個別投稿と固定投稿で共通部分が多い場合はこのファイル内にif(){}の条件分岐を使用し、双方を管理する事が可能
```php
<?php
		the_content(); //本文を表示
		if( is_singular( 'post' ) && in_category( 'bookreview' ) ): //個別投稿の場合のみ表示するコード?>
		<table>
			<tr><td>書籍名</td><td><?php echo esc_html( get_post_meta( $post->ID, '書籍名', true ) ); ?></td></tr>
			<tr><td>出版社</td><td><?php echo esc_html( get_post_meta( $post->ID, '出版社', true ) ); ?></td></tr>
			<tr><td>著者</td><td><?php
				$authors = get_post_meta( $post->ID, '著者', false );
				echo esc_html( implode( ', ', $authors ));
			?></td></tr>
			<tr><td>価格</td><td><?php echo esc_html( get_post_meta( $post->ID, '価格', true ) ); ?>円</td></tr>
		</table>
		<?php
		endif;
		?>
```
この様に```is_singular('post')```で分岐させる。

### ページや条件の判定
* is_singular(投稿タイプ) : 個別投稿かどうか判定
* is_date() : 日付一覧ページかどうか
* is_date() : 月一覧ページかどうか
* has_post_thumbnil() : アイキャッチ画像があるかを判定

### 表示
* the_content() :　本文表示


### テーマファイル（大きく２種類ある）
※テーマファイルでよく使われる関数を**テンプレートタグ**と呼ぶ
#### テーマテンプレート
コンテンツに応じた表示を受け持つ
page.php, archive.php, single.php等

#### モジュールテンプレート
ヘッダー用、サイドバー用等、Webページの一部を担う
header.php, sidebar.php, footer.php等

#### 二つの違い
呼び出し方が違う。
テーマテンプレートはURLでWPが自動で呼び出す。
モジュールテンプレートはテーマテンプレートからインクルードで呼び出す。

### インクルード
呼び出す時は
```php
get_header(); // header.php呼び出し
get_sidebar(); // sidevar.php　〃
get_footer();　// footer.php 〃
get_template_part('hoge'); // hoge.phpを呼び出し
get_template_part('parts/fuga') // partsディレクトリ内のfuga.phpを呼び出し

// 上記の引数を使用すると、呼び出すファイルを指定できる
// 例)
get_header(sub); // header-sub.php　呼び出し
```
を使用する。
その他、自身で任意のファイルを呼び出す際は```get_template_part('hoge')```を使用する（この場合**hoge.php**をインクルードする）。


### テンプレート階層
![スクリーンショット 2022-04-13 8.00.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/101848e0-f4ae-0788-5878-768667572857.png)
図の左側から順にファイルがWPによって探されて、最後にindex.phpが確認される。
例）
* トップページ : index.php
* 本のページ（カテゴリ：book(カテゴリIDは1)） : category-1.php
* 本の種類のページ（カテゴリ：book,スラッグ：小説(slug:novel、漫画:comic、絵本:picture） : 
* ニュースのページ(カテゴリ：news(カテゴリIDは２) : category-2.php
* このサイトについて（固定ページ）

上記の例でページを作ると
* トップページ : index.php
* カテゴリ一覧ページ : category.php
* カテゴリ毎の一覧ページ : category-1.php(本一覧）, category-2.php（ニュース一覧）
* 本の種類の一覧ページ : category-novel.php(小説一覧）, category-comic.php（漫画一覧）, category-picture.php（絵本一覧）
* 各本の個別ページ : single.php/1, single.php/2, single.php/3.... (「~/番号」で投稿の個別ページへ飛ぶ）

上記の様な構成で各ファイルを作って制作出来る。





### PHPのよく使う関数
* printf
* sprintf
* function_exists
* isset
* empty
* in_array
* count
* array_shift
* implode
* var_dump
* array_key_exists


### よく使うサイト
* [WordPressCodex](https://wpdocs.osdn.jp/Main_Page)
* [WordPressCodex テンプレートタグ](https://wpdocs.osdn.jp/%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%82%BF%E3%82%B0)


### オブジェクトの扱い

```php
例）オブジェクトからデータを取り出す
$postdata = get_post(3); // 投稿ID３の記事を指定して投稿データを取得する
echo $postdata->post_title; // 投稿日時を表示
echo $postdata->post_date; // 投稿日時を表示
```
get_post()は投稿した記事のデータをWPのクラスからオブジェクトで取得出来るので、アロー演算子を使用してデータを取得する。

```php
例2)オブジェクトの配列からデータを取り出す
$category = get_the_category(3); // 投稿ID3の記事のカテゴリーを取得
echo $category->cat_name; // #categoryは配列の為、データを表示出来ない
echo $category[0]->cat_name; // 表示に成功する
```
上記の様ワードプレスの指定関数を使用してデータを取得する場合、似た様な取扱いだと思って同じ方法で値を取得しようとしても、取り扱いが違う事があるので、注意する。

### テンプレートタグ
* is_home() :  トップページかどうかの判定（管理画面の設定「設定＞表示設定」で「フロントページの表示」を最新の投稿にしている場合に設定可能
※is_front_page(): 上記で「フロントページの表示」を固定ページにしている場合はこちらを使用する
* is_singular() : 個別ページかどうかの判定が出来る。引数に指定の投稿ページを入れると、その投稿ページがどうかの判定につかえる 
* 

### テンプレートファイル



### プラグイン 
* ShowID for Post/Page/Category/Tag/Comment
![スクリーンショット 2022-04-13 8.32.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/29d7829f-0c09-ab4f-4860-662228d126c2.png)
WPの個別ページを開かなくても、管理画面状で、記事のIDを確認出来る様になる。
#### おすすめプラグイン 
* TinyMCE Advanced : ブロックエディタをよりリッチに出来る
* Gutenbrg Blocks-Ultimate Addons for Gutenberg
* Show Monkey Blocks
* LIQUI BLOOKS
* Block Lab : カスタムブロックを簡単に作れる
**管理画面カスタム用プラグイン**
* Admin Columns :投稿一覧でアイキャッチ画像やカスタムタクソノミーを表記出来る様に設定出来たりする。
* User Role Editor : 管理権限を編集
**SEO対策用プラグイン** 
※Yoast SEO
**マルチデバイス対応**
* Multi Device Switcher
### 繰り返し処理
```php
<?php while (have_posts()) : the_post(); ?>
…略…
<?php endwhile; ?>
```
上記の```the_post()```は１件の記事を取得するという機能
記事がある間(have_posts())は１件ずつ記事を取得する。の意味
[参考記事](https://php1st.com/1202#:~:text=the_post()%E3%81%AF1%E4%BB%B6%E3%81%AE%E8%A8%98%E4%BA%8B%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8BWordPress%E9%96%A2%E6%95%B0%EF%BC%88%E3%82%BF%E3%82%B0%EF%BC%89%E3%81%A7%E3%81%99%E3%80%82)


### セキュリティ対策

```php
①esc_html(); //HTMLタグが無効になる（テキスト出力に使用）
例）
<?php echo esc_html( $GET['s'] ); ?>

②esc_attr(); // HTMLの属性値としての出力に使用
// 例）
<input value="<?php echo esc_attr( $GET['s']); ?>">
esc_url(); // urlとして適切でない文字を除去する
```
その他にも、WP codexに記載がある
#### ポイント
テンプレートファイルでechoで出力する場合は必ず```echo esc_〇〇```とする。
* URLは全て```esc_url()```
* 属性値は全て```esc_attr()```
* データ出力は```esc_html()```
を使用する様にする。
その他```the_search_query()```の様にテンプレートタグには最初から、関数内にエスケープ処理が記述されているものもある。

### ページネーション 
```php
	//前後のページへのリンク。
the_posts_pagination( [
	'prev_text' => '&larr;',
	'next_text' => '&rarr;',
] );
```
上記```the_posts_pagination()```で実装可能。
記事の１ページ当たりの表示は管理画面の**「設定＞一般＞表示設定」**で変更可能

### 前後の記事
* prev_text() : 前の記事一覧へのリンクテキスト。デフォルトは「%title」
* next_text() : 次の　〃　。デフォルトは「%title」
* in_same_term() : 同じカテゴリー/タグを表示する場合はtrue。デフォルトはfalse
* exclude_terms() : 除外するカテゴリー/タグをIDで指定。デフォルトはなし
* taxonomy() : カテゴリー（category)、タグ(post_tag)などを指定する。デフォルトは「category」
※カスタムタクソノミーという機能もあり、自分でタクソノミーを追加することも可能
```php
the_post_navigation( [ //前後の投稿へのリンク
	'prev_text' => '<span class="post-title">&lt;&lt; %title</span>',
	'next_text' => '<span class="post-title">%title &gt;&gt;</span>',
] );
```
上記例では表示される前後のページのリンク先は**前後の記事**になる。
```php
the_post_navigation([ //前後の投稿へのリンク
    'prev_text' => '<span class="post-title">&lt;&lt; %title</span>',
    'next_text' => '<span class="post-title">%title &gt;&gt;</span>',
    'in_same_term' => true
]);
```
上記の様に、```in_same_term```を記述する事で、前後のページのリンク先は**同じカテゴリー/タグの前後の記事**になる。



### コメント
* 初期設定ではコメント機能は有効になっている。管理画面にて無効にも出来る（設定>ディスカッション）
「新しい投稿へのコメントを許可」にチェックをつけていないと、この設定をしている間に投稿した記事にはコメントが出来ない。
その後、チェックをつけると、つけてからの投稿にはコメント出来るが、**チェックがついていない時の投稿は依然として、コメントは出来ない**事を覚えておく
![スクリーンショット 2022-04-13 22.01.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/0f7fc6a9-a8e4-c9a7-5728-16e200906523.png)

### ウィジェット
利用する時は**functions.php**にウィジェットの名前等の記載が必要。
実際にどのウィジェットを表示するかは、管理画面の「外観>ウィジェット」で設定。主にサイドバーやフッター等、メインではない部分の表示に使用する。
![スクリーンショット 2022-04-14 8.08.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/03180d1e-89af-e893-7ced-3dc0977cc06e.png)
上記の様にブロックエディタからドラッグして表示するウィジェットを選べる。
ウィジェットで管理する利点は、テンプレート上で記入すると後々、並べ替えや内容の変更にテンプレートファイルの修正が必要になる。ウィジェットで管理する事で後の修正対応が楽になる。
#### 使い方
```is_active_sidebar('footer')```であるかどうか確認し
```dynamic_sidebar('footer')```で表示する
#### ショートコード
functions.phpで設定した関数などを呼び出して使える。
例えば以下の様に記事のタイトルを表示する関数を使ったり出来る
```php
//ショートコードの作り方
//1. 関数を定義（今回はタイトルを表示する関数）
function get_titleFunc()
{
    ob_start();
    echo the_title();
    return ob_get_clean();
}
//2.ショートコードに設定
add_shortcode('get_title', 'get_titleFunc');

//3. 上記設定後、WPのブロックっエディタのショートコードにて
//[get_title]
//上記で呼び出す。
```

### プライバシーポリシー
```php
<div class="site-info">
	<?php bloginfo( 'name' ); //サイト名を表示 ?>
	<?php the_privacy_policy_link(); //プライバシーポリシーページへのリンクを表示 ?>
</div><!-- .site-info -->
```
基本footer.phpに配置する。
```bloginfo()```でサイト名を表示し、```the_privacy_policy_link()```で管理画面の「設定>プライバシー」で設定のプライバシーポリシーへリンクを作れる（設定>プライバシーで設定していないとリンクは表示されない）。

### サブクエリ
個別投稿のタイトルや本文など、URLで表示が決まる**メインクエリ**と違い、指定したURLのメインクエリに含まれないコンテンツの事をいう。
※例えば、記事の下に表示する、同じ著者の書いた記事の一覧の抜粋表示など
サブクエリの表示を行う関数が```get_posts```である。
使用例は以下

```php
<?php
//同じ投稿者の記事を表示するコードの記述↓
if ( is_singular( 'post' ) ) { //個別投稿の場合
  $postid   = get_the_ID(); //現在の投稿のIDを取得
  $authorid = get_the_author_meta( 'ID' ); //投稿者の情報を取得

   $args = [
         	'posts_per_page' => 5, //表示する件数
			'author'         => $authorid, //著者IDで絞り込み
			'orderby'        => 'rand', //表示はランダム
			'exclude'        => $postid, //現在の投稿を除外
	     	];

   $myposts = get_posts( $args ); //$argsの条件を満たすデータを取得する

	echo '<h3>同じ人が書いた記事を表示</h3>';
if ( $myposts ) : //所得データが０件でないかチェックしている
	echo '<ul>';
	foreach ( $myposts as $post ) : //投稿を1つずつ取ってくる
		setup_postdata( $post ); //foreachのループ内でテンプレートタグを使えるようにする ?> 
        <li>
          <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a> //記事のリンクを取得し、表示するタイトルにリンクを付与している。
        </li>
   <?php endforeach;
		wp_reset_postdata(); //データを元に戻す（setup_postdata()の後に必ず書く
		echo '</ul>';
else :
		echo '記事はありません';
		endif;
} //is_singlar( 'post' ) ?>
```
* get_posts()
引数には連想配列を取る。
連想配列のキーは主に「posts_per_page, author, category, category__in, exclude, orderby」がある
* setup_postdata() : 通常のWPの処理（メインクエリ）をサブクエリへの処理に切り替えている。
* wp_reset_postdata() : setup_postdataの後に記述をして、WPの挙動を戻す。

### カスタムフィールド 
![スクリーンショット 2022-04-14 12.44.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/0bda520a-8e83-e54d-b62b-da54133983cf.png)

上記の様に投稿にカスタムフィールドを入力する。
すると
![スクリーンショット 2022-04-14 12.44.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/8d381ed5-6088-bd54-7fc0-2ff86afe297a.png)

上記の様に公開される。
**ポイント**
カスタムフィールドはコードの記述で表示させている為、表示順はコードの記述に依存する。又、コードに記載の無い項目（今回で言う「著者名」は表示されない）。

今回の表示コード
```php
<table>
	<tr><td>書籍名</td><td><?php echo esc_html( get_post_meta( $post->ID, '書籍名', true ) ); ?></td></tr>
	<tr><td>出版社</td><td><?php echo esc_html( get_post_meta( $post->ID, '出版社', true ) ); ?></td></tr>
	<tr><td>著者</td><td><?php
		$authors = get_post_meta( $post->ID, '著者', false );
		echo esc_html( implode( ', ', $authors ));
	?></td></tr>
	<tr><td>価格</td><td><?php echo esc_html( get_post_meta( $post->ID, '価格', true ) ); ?>円</td></tr>
</table>
```
「著者」の様に同じ項目で複数個登録される事が見込まれる場合は以下の様に配列を使用した記述をする事で複数表示が可能になっている。
```get_post_meta()```は第3引数にtrueを設定すると、複数のデータがあっても最初の一つのみが表示される。falseにすると複数の要素を持つ配列を返す。
配列で返される値に対しPHPの関数である```implode()```を使用し、文字列に変換して出力をする。

```php
<tr><td>著者</td><td><?php
	$authors = get_post_meta( $post->ID, '著者', false );
	echo esc_html( implode( ', ', $authors ));
?></td></tr>
```
#### 値のないカスタムフィールドの項目を表示させないテクニック
上記の例で「価格」の登録がない場合は記事のテーブル表示から価格の欄を消したい場合は
```php
<?php if( get_post_meta( $post->ID, '価格', true )): ?>
  <tr><td>価格</td><td><?php echo esc_html( get_post_meta( $post->ID, '価格', true ) ); ?>円</td></tr>
<?php endif ; ?>
```
上記の様にifを使用して表示させない事も出来る。


### 検索
search.phpで検索結果ページを作る。
検索の作り方は、ウィジェットや固定ページ、投稿ページのブロックエディタで「検索」をページに表示させる。その検索バーから検索した際、検索結果を表示するページが**search.php**である。
* the _search_query() : 検索キーワードをエスケープして出力
* get_search_form() : 検索フォームを表示
* 

### エディター
* Gutenberg(グーテンベルク） : 2018年12月リリース
* Classic Editor : 以前のエディター

#### Gutenberg
* よく使用するブロックは再利用可能ブロックとして登録できる。
* グーテンバークで作成されたブロックにはデフォルトで**wp-block-〇〇**というclassが付与されている。そして**wp-includes/css/dist/block-library/style.min.css**が読み込まれて適応されている。
以下のコードをfunctions.phpに記載する事で、グーテンバーク標準スタイルを読み込まない様に設定可能（**例えばブロックエディタでテキストの「左寄せ、右寄せ、中央」の設定をした時、標準ではその配置にCSSが掛かるが、以下のコードを実行すると文字の寄せは効かなくなる**)。
又、このコードは適用されると新規投稿だけでなく、過去の記事のCSSも効かなくなる。
```php
//グーテンバークのブロックエディタのCSSの読み込み回避
function gutenberg_style_skip(){
	wp_dequeue_style( 'wp-block-library');
}
add_action( 'wp_enqueue_scripts', 'gutenberg_style_skip');
```
* 新規投稿時にデフォルトで見出しや本文を設定できる
functions.phpに以下の記述を行う
```php
//新規投稿時にブロックを配置
function register_template() {
	$post_type_object = get_post_type_object('post'); //投稿の情報を取得
	$post_type_object->template = [ //templateプロパティにブロック情報を登録
		['core/heading', ['level' => '2', 'content' => '購入したもの']], //見出しブロックを登録
		['core/paragraph', ['content' => '以下の購入品を参照']] //段落ブロックを登録
	];
}
add_action('init', 'register_template');
```
![スクリーンショット 2022-04-14 15.44.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/aa66a5f3-d06d-5cdd-2b51-c5d6423402df.png)
すると、上記の様に新規投稿時に最初から、記述がされている。
* get_post_type_object() : 投稿タイプを指定、ブロックタイプを配列で登録する事で、新規投稿時にブロックが配置される。
主に「core/heading(見出し)[level, align, content], core/image(画像)[url, width, height, href], core/paragraph(段落)[content, fontSize, customFontSize, textColor, customTextColor]」等がある。
上記をinitアクションフックにフックする事でWP本体のコード読み込み完了時点で実行される。






### その他設定しておくと良い事や知っておくと良い事
#### 多言語対応

####　テーマカスタマイザー
管理画面「外観>カスタマイズ」でWPのヘッダー画像や背景、配色など変更可能

#### 先頭に固定表示








## Tips
### 日付の表示
```the_date()```と```get_the_date()```の違い。
* the_date() : : アーカイブ表示（一覧表示）で使用する場合、同一日の投稿が複数あると、**最初の投稿でのみ日付を表示**になる
* get_the_date() : アーカイブ表示で使用する場合こちらを使用すると**同一日の投稿それぞれに日付を表示**出来る

### エラー対応
* リカバリーモード
* メール通知
エラー発生時のメール通知先の設定が可能
1. wp-config.phpで設定のメールアドレス
2. 1を設定していない場合、管理画面の「設定>一般」で設定したメールアドレス
* デバッグモード
標準では無効になっている。有効にする時は**wp-config.phpを編集**する。
有効にするとエラーメッセージが表示される様になる。サイト公開後は無効にしておく方が良いが、テーマ作成中は有効にした方がエラーに気付きやすくなる。
#### wp-config.php
場所は以下の通り、WPをインストールしたフォルダ内にある。
データベースへの接続情報等のWPの設定が記述されている。
![スクリーンショット 2022-04-14 16.43.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/7d207fc3-61f3-6363-b31e-84ef8b58b3f5.png)
初期状態ではwp-config.php内で
```php
define( 'WP_DEBUG', false ); //デバッグモードオフ
```
となっている為
```php
define( 'WP_DEBUG', true ); //デバッグモードオン
```
に変更する。

エラーが出る例としては
```php
例）正しい状態
if(){
 ~省略~
}
```
上記が
```php
例）鍵かっこの始まりが無い（誤り）
if()
 ~省略~
}
```
こうした構文等の誤りがあると、公開ページを確認する際、所定のページでは無く、以下の様なエラーページが表示される。
![スクリーンショット 2022-04-14 16.49.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/22ed83c8-9f95-66ae-2714-a477ebb7e803.png)
* その他デバックの際には```var_dump()```を使用して変数や定数、関数から返った値などを確認していくと良い。



## まだ理解できていない項目
### フック
フックには**フィルターフック**と**アクションフック**がある。
#### フィルターフック
[参考:wpcodex(プラグイン API/フィルターフック一覧)](https://wpdocs.osdn.jp/%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3_API/%E3%83%95%E3%82%A3%E3%83%AB%E3%82%BF%E3%83%BC%E3%83%95%E3%83%83%E3%82%AF%E4%B8%80%E8%A6%A7)
主に変数を受け取って加工して返す処理を行う。
```apply_filters()```関数で作成されている。
※実際に自分で使う時は```apply_filters()```を使う事はなく、```add_filter()```を使用していく。**functions.phpに記述して使う**
　**apply_filters()を使うとしたら、プラグインを自作する時や、自作テーマを公式ディレクトリに公開する時等がある。**


#### アクションフック
[参考：wpcodex（プラグイン API/アクションフック一覧)](https://wpdocs.osdn.jp/%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3_API/%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%95%E3%83%83%E3%82%AF%E4%B8%80%E8%A6%A7)
変数を書き換えるのではなく、WPでなんらかのアクションが実行される際に、フック地点に処理を追加する。
```do_action()```関数で作成されている。
※実際に自分で使う時は```do_action()```を使う事はなく、```add_action()```を使用していく。**functions.phpに記述して使う**
　**do_action()を使うとしたら、プラグインを自作する時や、自作テーマを公式ディレクトリに公開する時等がある。**

### functions.php を使いこなす
スタイルシートやscriptタグを読み込んだり、ページタイトルを一括設定したり、色々触ると出来る。

### 子テーマ
* 既存のテーマを継承し、部分的に変更を加える為の仕組み。
元になるテーマは「親テーマ」と呼ぶ。
使い方の例としては、親テーマをWP公式配布のものを使用し、子テーマはその親テーマの一部を修正や変更してカスタマイズして使うなど。
元々WPの公式テーマは都度更新されてしまう為、自身の記述を配布テーマに行うのではなく、子テーマとして加筆する事で、親テーマは都度更新し、最新に出来るという利点がある。
**※注意**
親テーマの更新があった際に、セキュリティ上の観点などから削除されたファイルがあった際、その削除された項目をこテーマで上書きしている時は以下の修正を行う。
1. 親テーマをアップデートする
2. 子テーマの該当しているファイルを削除
3. 子テーマの該当ファイルを修正し、再度アップロードする


* 子テーマの作り方
設置場所は親テーマと同じ階層「wp-content/themes」の直下
**style.css**とそれを読み込むための**functions.php**が必須（子テーマではindex.phpは必須ではない)。
#### 親テーマと子テーマの考え方
本店と沖縄支店があったとする。
親テーマには、本店と沖縄の共通項目のみを記載したファイルを置き、子テーマに各支店事に追記や修正をする可能性のファイルを持たせる。
そうする事で、必要テーマの共通化と修正が容易になる。　

# 発展系の内容
## 管理画面について
### ブロックエディタの使い方
* 段落ブロック : 通常のテキスト（本文）を入力

### 投稿時の項目

<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/d2ce25a9-4e51-765b-d08e-a161116ad73e.png">
上記の各項目は右上の設定から表示・非表示の切替が可能


### カテゴリー
作成する際にスラッグを入れていないと、自動で生成される（基本カテゴリーの名前と同じ）。
スラッグはページのURLにも関係する為、意識的に入力するほうが良い。

### 設定
* パーマリンクでURLの表示設定が可能

### ユーザー登録
* 権限が５種類ある
「管理者、編集者、投稿者、寄稿者、購読者」」
* 管理画面の「ユーザー」から設定可能


## テーマ作成の方法


### ファイルパスの取得方法
```get_template_directory_uri()```を使用して使用してるテーマのディレクトリのURLを取得する。
取得できる情報はechoをすると
```http://ファイルのURL/wp-content/themes/テーマ名```
**使用例**
```php
<link href="<?php echo get_template_directory_uri(); ?>/assets/css/styles.min.css" rel="stylesheet">
<script src="<?php echo get_template_directory_uri(); ?>/assets/js/main.js"></script>
<img src="<?php echo get_template_directory_uri(); ?>/assets/img/common/logo@2x.png" alt="BISTRO CALME">
```

### タイトル取得
```	<title><?php bloginfo('name'); ?></title>```
WPで設定しているタイトル名を取得
しかし、上記方法だとheader.phpを共通で使用する為、全てのページのタイトルが同じになり、又、SEO的にも良くない。
投稿した記事に合わせてタイトル表示する時はfunctions.phpに記載をする。

### functions.php
* add_theme_support() : 指定した機能を有効にする。
*



**使用例**
#### タイトル表示
```php
<title>タグを出力する
add_theme_support('title-tag');
```
上記によってページに合わせたタイトルの出力が可能になる（bloginfo())は削除する。
他にも```add_filter()```関数を使用したフィルター操作「```document_title_separator```や```document_title_parts```」を使用したタイトルのカスタマイズも出来る。


### テンプレートファイル
**主なテンプレートファイル**
|テンプレートファイル名|概要 |
|:-:|:-:|
|front-page.php   |webサイトのトップページ   |
|single.php   |投稿の記事ページ   |
|page.php   |固定ページ   |
|category.php   | カテゴリーページ  |
|search.php   |検索結果表示ページ   |
|archive.php   |記事一覧ページ   |
|404.php   |404エラーページ   |

優勢順位はテンプレート階層（基本形を参照）に基づく。

### テンプレート階層
ページの種類について考える
* トップページ
* 記事ページ
* カテゴリー別記事一覧ページ
* 月別記事一覧ページ

#### トップページのテンプレート階層
テンプレート階層に基づいて表示される
![テンプレート階層.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/9e70fd96-a201-4042-130b-e58bb0bf088c.png)

**トップページのテンプレート階層**

|優先順位|テンプレートファイル名 |備考 |
|:-:|:-:|:-:|
| 1  |  front-page.php | -  |
| 2  | 固定ページ表示ルール  | 「設定>表示設定>フロントページの表示」が固定ページに設定されている場合  |
| 3  | home.php  | -  |
| 4  | index.php  |   |


**個別投稿ページのテンプレート階層**

|優先順位|テンプレートファイル名 |備考 |
|:-:|:-:|:-:|
| 1 | single-{post_type}.php  |例：投稿タイプがhogeの場合はsingle-hoge.php（投稿タイプはデフォルトだと「post」その場合はsingle-post.php。カスタム投稿タイプでせっていした「hoge」の場合はsingle-hoge.phpになる。  |
| 2  | single.php  |投稿記事ページ   |
| 3  | singular.php  | 投稿や固定ページ、カスタム投稿タイプの記事ページ  |
| 4  | index.php  |他の優先ファイルの設定がないと、このファイルが適用される   |

**カテゴリー別記事一覧ページのテンプレート構造**

|優先順位|テンプレートファイル名 |備考 |
|:-:|:-:|:-:|
| 1  | category-{slug}.php  |例：カテゴリーのスラッグが"news"の場合はcategory-news.php   |
| 2  | category-{ID}.php  | 例：カゲゴリーIDが5のテンプレートはcategory-5.php  |
| 3  | category.php  | -  |
| 4 | archive.php  | 一覧表示の基本ファイル  |
| 5 | index.php  | - |

**月別記事一覧ページのテンプレート構造**

|優先順位|テンプレートファイル名 |備考 |
|:-:|:-:|:-:|
| 1  |  date.php | -  |
| 2  | archive.php  |  - |
| 3  | index.php  | -  |


### 投稿タイプ（カスタム投稿タイプ含む）
WPではデフォルト投稿タイプとカスタム投稿タイプがある

#### デフォルト投稿タイプ
|ラベル|投稿タイプ |
|:-:|:-:|
|投稿  | post  |
|固定ページ|page   |
|添付ファイル   |attachment   |
| 添付ファイル  |revision   |
|   リビジョン|nav_menu_item   |

初期設定で管理画面から投稿をすると、データベースに対して「投稿タイプが**post**の記事をリクエストする」といった働きかけが行われる。
ここで設定されるpostが投稿タイプに当たるので、これを元に個別投稿のファイルを作ると、**single-post.php**とする事で、個別投稿ページを設定出来る。もちろん、細かく分けないのであれば、single.phpやsingular.phpを使用しても問題ない。


上記を考慮しページ構成を考えると
* トップページ : front-page.php
* 記事ページ一覧　 : archive.php
* 記事ページ : single.php
* カテゴリー別記事一覧ページ・月別記事一覧ページ : index.php（デザインが似ている為、同じファイルで管理する）。
**ポイント**
* ファイル名はカテゴリー一覧やアーカイブ一覧等のページのタイトル部分のみ表記を変えれば同じレイアウトで作れるファイルが複数ある最も凡庸性の高いものにindex.phpの様な優先度の低いファイルを使用するといった考え方が良い。
* while文なども別ファイルで同様の記述をする場合、**loop-main.php**、**loop-date.php**等を作成、**template-partsフォルダ**を作成しそこで一括管理し、```get_template_part```で呼び出すなどして管理すると分かりやすくなる。

### テンプレートタグ
主なテンプレートタグ
* bloginfo($show) 
 name : サイトの情報表示 （例）```<title><?php bloginfo('name'); ?></title>```
 description : サイトのキャッチフレーズ```
* home_url(): サイトのトップページへのリンクを作る(aタグ内href属性の中で設定）
echoで呼び出すと「http://サイトのURL」が表示される。
* body_class() : アクセスしているユーザーの状況（ログイン後、非ログイン等）や記述しているファイルがトップページ、個別投稿ページ、固定ページ等、どのファイルかによっても付与されるclassが変わる為、同一ファイルで異なるCSSの設定が可能になる。
* get_header('header.php') : ヘッダーページ読み込み
* get_footer('footer.php') : フッターページ読み込み
* wp_body_open()
* wp_enque_script()
* wp_head()
* wp_footer()

**使う場所**
```php
<body <?php body_class(); ?>>
<?php wp_body_open(); ?>
<?php wp_enqueue_script('jquery'); ?> <!--jequery読み込み-->
<?php wp_head(); ?>
</head>

<?php wp_footer(); ?>
</body>
```
wp_body_openをbodyタグの開始タグの直後、wp_headとwp_footerを上記の様にheadとbodyの閉じタグの直前に記入
wp_enqueue_script()を使用するとscriptタグ読み込みの記述も書き換え出来る
```php
<link href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" rel="stylesheet">
<script src="<?php echo get_template_directory_uri(); ?>/assets/js/main.js"></script>
<!--上記を-->
<?php wp_enqueue_style('font-awsome', 'https://use.fontawesome.com/releases/v5.6.1/css/all.css'); ?>
<?php wp_enqueue_script('bistoro-calme-main', get_template_directory_uri() . '/assets/js/main.js'); ?>
<!--に書き換え-->
```
WP公式ではwp_enqueue_styleやwp_enqueue_scriptでファイルを読み込むことを推奨している。
理由はファイルの重複した読み込みの防止等がある。
詳しくはこちらの記事に記載あり。
[参考記事](https://wemo.tech/205)
公式の関数リファレンス内でもwp_enqueue_style(script)の使用を推奨する記載がある。

### 条件分岐タグ
ifとセットで使うことでそのページの種類によって処理を分けることが出来る
|条件分岐タグ| 内容 |
|:-:|:-:|
| is_home()  | トップページかどうか  |
| is_single('パラメータ')  | 記事ページかどうか  |
|is_page('パラメータ')   | 固定ページかどうか  |
| is_category('パラメータ')  | カテゴリーページかどうか  |

上記以外にもあるので、WordPress Codexの条件分岐タグを検索する
[WordPress Codex　条件分岐タグ](https://wpdocs.osdn.jp/%E6%9D%A1%E4%BB%B6%E5%88%86%E5%B2%90%E3%82%BF%E3%82%B0)

### ループ
ifとwhileを使用して記事の分だけ一覧表示する
```php
<?php if (have_posts()): ?> <!--記事があるか判定-->
			<?php while (have_posts()) : the_post();?>　 <!--記事があれば１件ずつ取得-->
			<div class="col-md-4">
				<article id="post-<?php the_ID(); ?>" <?php post_class('news');?>>
					<div class="newses">
                    ~省略（ループする記事の内容を書く）
				</article>
			</div>
          <?php endwhile; ?>
		 <?php endif; ?>
```

#### ループ内で使用するタグ
* the_ID() : 現在の投稿のIDを表示（id属性の先頭に数字は使用出来ないので使う時は```id="post-<?php the_ID();>" ?>```の様にする。
*  post_class('$class') : 現在の投稿の種別に応じたクラス属性を表示する。$classには追加するクラス名を入れる。the_ID()と違い、このタグはclass属性自体にクラスを付与して表示する。
* the_category() : 記事が属するカテゴリーへのリンクを表示する。
このタグで生成されるのは以下の通り「ul,li,aタグ」であり、```post-categories```クラスが付与される。
```php
<ul class="post-categories">
  <li>
    <a href="http://52.199.244.147/category/uncategorized/" rel="category tag">Uncategorized</a>
  </li>
</ul>		
```
* the_time() :　指定したフォームで投稿時刻を表示する。htmlのtimeタグのdatetimeにも記述する事で検索結果に日時を表示させたり、SEOの効果を上げる。
```php
<time class="news_time" datetime="<?php the_time('Y-m-d'); ?>"><?php echo the_time('Y年m月d日');?></time>
```
* the_permalink() : 投稿の個別ページへのURLを付与する。
* the_excerpt() : 本文中に「続きを読む」ブロックがある時はそこまで、無い時は、５５文字までを抜粋表示し、その後ろに「...」を表示する。
※日本語のように語句の間を半角スペースで区切らない言語では「55単語」を判定できないため、抜粋できずに本文のほとんどが出力されてしまうことがあります。（公式より）
表示の際は```<p>テキスト</p>```の形式で出力される。

#### アイキャッチ画像
functions.phpで
```php
// アイキャッチ画像を使用可能にする
add_theme_support('post-thumbnails');
```
上記をアップロードすると、新規投稿画面「投稿」部分に「アイキャッチ画像」の項目が表示される様になる
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/9552e0f1-40e6-ff1c-6260-43a1662e6859.png">
```the_post_thumbnail()```で表示する。
以下の様に```has_post_thumbnail()```と併用すれば、アイキャッチ画像がない時に代わりの画像を表示できる。
```php
<div class="news_block">
  <a href="<?php the_permalink(); ?>">
	<?php if (has_post_thumbnail()) : ?>
    	<?php the_post_thumbnail('medium'); ?>
	<?php else : ?>
		<img src="<?php echo get_template_directory_uri(); ?>/assets/img/common/noimage_600x400.png" alt="">
    <?php endif; ?>
  </a>
</div>
```

### 個別投稿ページを作成する
* single.php等を使用する（テンプレート階層参照）。
* 個別ページでもワードプレスの内容を表示する部分にはWordPressループ（whileとif)を使用する。
これはWordPressメインクエリの考え方に基づいており、WPの機能としてトップページ等、では一覧表示用にループが複数回行われ、single.phpの様な個別投稿記事表示用のファイルではメインクエリが１回だけループするという機能になっている。
* 記事の本文は```the_content()```で表示する。設定によって全文か一部か変更出来る。

#### 前後の記事のリンク
* previous_post_link()
* next_post_link()
上記を使用する。表示させる文字を変更する場合、第一引数を使用する（デフォルトは```《％link```と%```link》```）。
のタグの仕様では<a></a>タグが生成される。
```php
<div class="postLink postLink-prev">
  <?php previous_post_link('<i class="fas fa-chevron-left"></i>%link') ?>
</div>
<div class="postLink postLink-next">
  <?php next_post_link('%link<i	class="fas fa-chevron-right"></i>') ?>
</div>
```

### sidebar.php（sidebar-{}.php）
別ファイルからsidebar.phpを読み取る際は```get_sidebar($name)```を使用し、ファイルを読み取る。
サイドバーの種類が一つなら引数無しで、作成するファイルは**sidebar.php**のみ。
サイドバーを複数（例えばカテゴリー用と、アーカイブ用）作るならば**sidebar-categories.php**と**sidebar-archives.php**を作成。```get_sidebar('categories')```と```get_sidebar('archives')```で読み込む。
* wp_get_categories() : カテゴリーページのリンク付き覧表示し<li></li>を生成。デフォルトでは見出しが表示される為、引数を設定する事で非表示に出来る。
```php
<?php 
$args = [
         'title_li' => '', //見出しを削除する
         ];
wp_list_categories($args);
?>
```
＊ wp_get_archives() : アーカイブページのリンク付き一覧表示<li></li>を生成。引数の設定で月別の他、日別、年別、アルファベット、投稿順等設定可能
```php
<?php 
$args = [
        'type' => 'daily' // monthly(defalt), weekly, yearly, postbypost, alpha等もある
         ];
wp_get_archives($args);
?>
```

### 固定ページ
* 固定ページはpage.php等で管理する。
* 固定ページもthe_titleやthe_contentでタイトルや本文を表示するので、WordPressループを使用する。
* abautベージの「about」等、ページのスラッグを表示したい時は```echo strtoupper($post->post_name);```を使用する(strtoupper()は大文字にするタグなので使うかは任意）。スラッグはグローバル変数$postに格納されているものを呼び出している。


#### 固定ページ作り方
1. 管理画面>固定ページ>新規作成で作成画面を開く
2. 必要な情報「見出し、画像、テキスト（段落）等を入力
3. サイドバーの「固定ページ」から任意のスラッグをローマ字で入力（デフォルトだと固定ページ名になる。例えばアバウトならスラッグも「アバウト」になるので「about」に変更する）。
4. page.phpに書く記述を表示するタグを記述し表示させる。
　
#### 固定ページの親子ページ作成
例えば
親 : company(URL : hoge.com/company)
子 : about(URL : hoge.com/company/about)

##### 作り方
1. 固定ページの新規作成で「会社」ページ（スラッグ：company)を作成し公開。
2. さらに固定ページの新規作成で「アバウト」ページ（スラッグ：about)を作成。
3. aboutの作成画面で「ページ属性」を選択し親（会社）を選択し公開
4. 公開されたページのURLをみるとhoge.com/company/about/が公開される。

#### アクセスページの作り方
ファイルはpage.phpで使いまわせる。
1. 管理画面から固定ページを新規作成
2. ブロックエディタで「カスタムHTML」を使用し、その中でiframeで地図を埋め込む
3. 「テーブル」ブロックで表を作る（所在地や、営業時間などを記入）。又、テーブルの色の種類も変更可能
4. スラッグに「access」と記入し公開。

### グローバルナビゲーション作成（カスタムメニュー）
#### 有効化する
* WordPressのカスタムメニューを使用するためにはfunctions.phpの記入が必要
functions.phpに```add_theme_support()```を記入する。
```php
// カスタムメニュー機能を使用可能にする
add_theme_support('menus');
```
#### 管理画面からカスタムメニューを設定する
カスタムメニューが有効になると、管理画面の「外観」の中に「メニュー」という項目が表示される。ここでメニューの編集をする。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/659180c1-71e2-f4a8-1aae-5a5359764eeb.png">
* メニュー名を任意で設定（grobal-navigation等）し、メニューを保存する
* 保存すると左側の固定ページが選択出来る様になる。任意のメニュー（上記ではお問い合わせやアバウトページ等）にチェックを入れ、メニューに追加を押す。そうすると選択肢メニューがメニュー構造に追加される。
* 同様の手順で今度は固定ページの「全て表示」を選択し、ホーム（トップページ）へのリンクも追加する。
* メニューの順序はメニュー構造の各メニュー項目をドラッグして変更出来る。
* メニュー項目の表示テキストは▼をクリックし、項目の詳細設定で「ナビゲーションラベル」の記載を変更する事で、変更出来る。その他クリック時の遷移先URLもここで変えられる。
#### ナビゲーション表示用のコード記述
* 表示する箇所に```wp_nav_menu()```を記入する。これだけでもナビゲーションの各項目へのリンクは表示出来るが、classやIDの付与等その他の設定をする場合、引数を入力する。
```php
<?php
$args = [
         'menu' =>'global-navigation', // 管理画面で設定した名前
	     'menu_class' =>'', // メニューを構成するulタグのクラス名
	     'container' =>false, // <ul>タグを囲んでいる<div>タグを削除
	     ];
wp_nav_menu($args); ?>
```

### 各記事へのリンク作成
これを設定する理由として、各ページのリンクは例えばトップページからアバウトページへのリンクを考えた時、直接「hoge.com/about/」の様に設定すれば良い様に思えるが、この「about」が管理画面で固定ページを登録の際、スラッグを「about」としているものであれば、スラッグを変更すると、このページへのリンクも書き換える必要が生じる。又、ドメイン変更時も同様に変更が必要になってしまう。
そうならない為に、**対象の固定ページの記事IDからURLを取得し、動的にリンクが変わる**様にする。

#### 手順1-1. パターン1 : プラグインを使う
**「ShowID for Post/Page/Category/Tag/Comment」**というプラグインを入れると、管理画面の固定ページの各項目をホバーするとIDが表示される様になる。
<img width="300" src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/9495b196-d2d2-a9f6-662f-f212d151a688.png'>

#### 手順1-2. パターン2 : 管理画面尾URLから記事IDを調べる。
* 該当の固定ページの編集画面を開くとそこURLの中に記載がある。
その中のpost=〇〇の部分に数字があるのでこれがID
* その他にもコードに```the_ID()```を使用して、ページのhtmlを開発者ツールで見る事でも確認可能。

#### 手順2. ページのURLを設定する
記事IDが分かったらリンクの設定をする。
aタグのhref属性に```echo get_permalink(該当のID)```を入力する。
```php
<div class="col-md-6">
  <a href="<?php echo get_permalink(157);?>" class="bnr" style="background-image: url('<?php echo get_template_directory_uri(); ?>/assets/img/home/bnr_access@2x.jpg')">
  <div class="bnr_inner">アクセス<span>ACCESS</span></div>
  </a>
</div>
```

#### 特定のカテゴリへのリンクを作成(get_termby, get_term_link ・ home_url()
IDで指定するとスラッグで指定する様に、スラッグが変わっても修正不要。スラッグで指定するとコードを見て何のリンクか分かりやすい。
それぞれの利点を理解して使う。
##### IDで指定する方法
使用するタグは
* get_term_by()
* get_term_link()
get_term_byで取得したターム（してしたカテゴリ等）情報を元に、get_term_linkでそのタームへのリンクを出力する。
```php
<?php 
$gw = get_term_by('slug', 'golden-week', 'category');
$gw_link = get_term_link($gw, 'category');
?>
<a href="<?php echo $gw_link;?>" class="btn btn-default">GWのお知らせ一覧<i class="fas fa-angle-right"></i></a>
```
##### 特定のスラッグで指定する方法
* home_url(相対パス) : ```echo home_url('/contact/');```の様に指定するとホームURLからの相対パス（**hoge.com/contact/**）を取得出来る。

### サイト内検索を作成
#### formタグの設定
* formタグのaction属性にトップページへのURLの設定
* formタグのmethod属性にgetを設定
* formタグ内のinputタグのname属性には「　s 」を使用する。
* formタグ内のinputタグのvalue属性に```the_search_query()```を設定する。これにより、検索結果ページが表示された際に、入力したキーワードを表示出来る。
#### formタグを別ファイルに切り分け
* searchform.phpを作成し、formタグの記載を全て移動させる
* 元々formタグがあったファイルで```get_search_form();```で**searchform.php**を呼び出す。
get_search_form()はsearchform.phpを読み込むWPのタグ。
#### 検索結果ページ（search.php）を作成
* 検索内容を表示させる```the_search_query()```を記入する
* それ以外はヘッダー、フッター、WPループの記入をすればOK
#### 検索結果が０件の時の対応を行う
WPループのendwhileとendifの間にelse文を追加すれば良い。
最終的なsearch.phpの主な記載は以下
```php
<div class="container">
  <h2 class="main_title">「<?php the_search_query(); ?>」の検索結果</h2>
	<div class="row">
		<?php if (have_posts()) : ?>
			<?php while (have_posts()) : the_post(); ?>
				<div class=">
					<?php get_template_part('template-parts/loop', 'news'); ?>
				</div>
			<?php endwhile; ?>
		<?php else : ?>
	     		<div class="">
			    	<p>検索結果はありませんでした</p>
		    	</div> 
        <?php endif; ?>
</div>
```

### 404エラーページ作成
存在しないURLが選択された場合、デフォルトだとindex.phpが表示されるが、404.phpへ遷移する様に設定する。
404.phpを設定すればテンプレート階層の仕組みにより、自動的に設定の無いURLが選択されると404.phpが選択される。
その為、```echo home_url('/')```をページ内に設定し、トップページへの移動を促せば良い。

### テーマのスクリーンショットの設定
自作したテーマは管理画面の「外観>テーマ」にて設定するが、最初に自作テーマを作ると画像などが設定されていない為、設定を行う。
* ファイル名が「screenshot.png」のpng画像を用意する。
* 画像の縦横比を3:4にする。
* 用意した上記画像をテーマディレクトリ（自作テーマの作成フォルダの直下）にアップロードする。

## プラグイン 
* プラグインには公式と非公式がある。非公式は管理画面から検索しても出てこないもので、配布先からインストールし、サーバーへ直接アップロードが必要。

#### パンクズリスト
* Breadcrumb NavXT（プラグイン）を使用する。パンクズリストプラグインの定番。
* 表示はbcn_display()
* function_exists()を使用して定義されているか確認

#### 問合せフォーム
* MW WP Formを使用する。簡単かつ、確認画面があるもの。

#### 記事一覧のページナビゲーション
* WP-PageNaviを使用する。ページナビゲーションプラグインの定番
```wp_pagenavi()```を使用して表示させる。
```php
<?php if(function_exists('wp_pagenavi')){wp_pagenavi();} ?>
```

#### 記事に対するコメント
* 管理画面の設定>ディスカッションから設定を行う
* 管理画面のコメントからコメントに対する設定を行う
* コメントの表示や投稿用のテンプレートファイルの読み込みは```comments_template()```で行う。このタグは**comments.php**を読み取る。

#### comments.php
コメントフォームの表示には```comment_form()```を使用する。
```php
<?php
$comment_form_args = [
    'title_reply' => 'コメント投稿フォーム',
    'logged_in_as' => '',
];
comment_form($comment_form_args);
if ( have_comments() ) :
?>
    <p><?php comments_number(); ?></p>
    <ol class="commentlist">
        <?php wp_list_comments(); ?>
    </ol>
<?php
paginate_comments_links();
endif;
?>
```

### REST APIでWPの情報を取得する
```https://hoge.com/wp-json/wp/v2/posts```
* 上記記述でそのサイトの情報がJSONで取得できる。
更に末尾にIDを設定すると指定IDの情報が取得可能。
```https://hoge.com/wp-json/wp/v2/posts/100```
他にも末尾にカテゴリ(```?categories=1```や投稿タイプ```pages```等を入力して、絞り込みが出来る。
※カスタムフィールドの値についてはfunctions.phpの追記やプラグイン「Custom Post Type UI」使用であれば設定の「REST APIで表示」がTrueになっている必要がある。
* REST APIは初期でONになっているがfunctions.phpに記載する事で停止する事も可能。
* WP REST API -OAuth 1.0a Serverプラグインでデーターの取得以外に新規登録、更新なども可能になる。
**セキュリティ**
* SiteGuard WP Plugin : 基本的なセキュリティ対策を実施できる
**その他プラグイン**
* Duplicate Post : 過去の記事と似た記事を作りたい時に便利なプラグイン
* Broken Link Checker : サイト内のリンク切れを確認してくれる
* Really Simple CSV Importer : 記事の内容を入力したCSVを用意する事で、一度に複数の記事を投稿できる様になる
* WP CSV Exporter : 記事のCSVファイルをエクスポートすることが出来る
* Smush Image Optimizatioon, Compression, and azy Load : 管理画面で画像をアップロードする際に、自動的に画像のファイルサイズを小さくできる
* WP Super Cache : 一度表示したファイルのキャッシュを一時的に保存する事で、サイト高速化が計れる
**※キャッシュ系のプラグインを入れるとサーバー側のキャッシュ操作と競合する恐れもあるので、慎重に採用する。

### セキュリティ対策
* [セキュリティの日本語版公式ドキュメント](https://wpdocs.osdn.jp/WordPress_の安全性を高める)
* [セキュリティの英語版公式ドキュメント](https://wordpress.org/support/article/hardening-wordpress)
上記サイトは一度眼を通すと良い。
* WPを常に最新版にする
* 信頼できるプラグインを使用する（公式のもの等）
* ユーザー名、パスワードを簡単な文字列にしない
* ファイルやディレクトリにアクセスを制限する
* .htaccessで```wp-config.php```へのアクセスを制限する
* ファイル編集の無効化をする
wp-config.phpに　```define('DISALLOW_FILE_EDIT', true);```と記述する。
* データベースのプレフィックス（接頭辞）を変更する。
* 管理画面のURLを変更する（デフォルトでは```http://hoge.com/wp-login.php```の様になっている為、変更しておくと良い

### サイトの高速化
* プラグインを多用しない
* [Webサイトのパフォーマンスを診断する](https://developers.google.com/speed/pagespeed/insights/)
#### カスタム投稿タイプ
作り方は２通りある。
* functions.phpにコードを記述する方法
* プラグインを使用する方法（Custom PostType UI等が人気)
カスタム投稿タイプが複数ある場合funcitons.phpに記述すると、記述が冗長になり大変な為、プラグインを使用する方が簡単。

#### カスタムフィールド
* Wordressのデフォルト機能より、プラグインの**Advanced Custom Fields**が便利

### タクソノミー
* 投稿の記事は「カテゴリー」と「タグ」を使用して分類が出来る。この分類をWPでは**タクソノミー**と読んでいる。
タクソノミーはカテゴリーとタグ以外にも作成が可能で、独自に作成したタクソノミーを**カスタムタクソノミー**と呼ぶ。
* カスタムタクソノミーを使用する方法は**functions.phpに記入する**方法と**プラグイン　Custom Post Type UI**を使用する方法がある。

### WP_Queryのパラメータ
使い方を押さえておくと良い。