準備が多くてしんどいですね。
screenshot.png
880*660px
配布目的でもなければ頑張って画像を作っても仕方がないと思う。なので、背景色を付けて白抜きででっかい文字で分かるようにしておけばいいんじゃないですかね。
CSS
style.css
/*
Theme Name: xxx
Author: xxx
Description: xxx
Version: xxx
*/
@import url(css/plugin.css);
/* @acab/reset.css */
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}:where([hidden]:not([hidden='until-found'])){display:none!important}:where(html){-webkit-text-size-adjust:none;color-scheme:dark light}@supports not (min-block-size:100dvb){:where(html){block-size:100%}}@media (prefers-reduced-motion:no-preference){:where(html:focus-within){scroll-behavior:smooth}}:where(body){block-size:100%;block-size:100dvb;line-height:1.5;font-family:system-ui,sans-serif;-webkit-font-smoothing:antialiased}:where(input,button,textarea,select){font:inherit;color:inherit}:where(textarea){resize:vertical;resize:block}:where(button,label,select,summary,[role='button'],[role='option']){cursor:pointer}:where(:disabled){cursor:not-allowed}:where(label:has(>input:disabled),label:has(+input:disabled)){cursor:not-allowed}:where(button){border-style:solid}:where(a){text-underline-offset:.2ex}:where(ul,ol){list-style:none}:where(img,svg,video,canvas,audio,iframe,embed,object){display:block}:where(img,picture,svg){max-inline-size:100%;block-size:auto}:where(p,h1,h2,h3,h4,h5,h6){overflow-wrap:break-word}:where(h1,h2,h3){line-height:calc(1em + 0.5rem)}:where(hr){border:none;border-block-start:1px solid;color:inherit;block-size:0;overflow:visible}:where(:focus-visible){outline:2px solid var(--focus-color,Highlight);outline-offset:2px}:where(.visually-hidden:not(:focus,:active,:focus-within,.not-visually-hidden)){clip-path:inset(50%)!important;height:1px!important;width:1px!important;overflow:hidden!important;position:absolute!important;white-space:nowrap!important;border:0!important}
body{
min-height: 100vh;
min-height: -webkit-fill-available;
font-family: "Helvetica Neue", "Helvetica", "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Arial", "Yu Gothic", "Meiryo", sans-serif;
color: #111;
line-height: 1.5;
}
テーマ情報も、配布目的とかガチガチの管理でもなきゃ無記入とかでいいけど「Theme Name」は入れておいてもいいような。
style.cssは基本ファイルなんで、ここでcssリセットとかimportとか初期設定をやっておくのがいいですね。全般的でないcssは別途functions.phpとかで割り振っていけばいいので、importで全部繋いだりとかする必要はないと思う。とはいえ結局functions.phpで読み込ませるから、importは封印していいな。
plugin周り
pluginの調整は地味にある。フォームとかなら個別に書いてもいいと思うけど、記述自体そんなにないし、プラグインでまとめたほうがむしろ楽かもしれない。使い回しやすいし。
/* reCAPTCHA https://developers.google.com/recaptcha/docs/faq */
.grecaptcha-badge { visibility: hidden; }
header.php
metaとかその辺は割愛して。
<html>
<head>
<?php get_template_part('parts/head_tag');?>
<?php get_template_part('parts/head_ogp');?>
<?php wp_head(); ?>
</head>
<body>
<?php get_template_part('parts/body_tag');?>
ベタ打ちするのはやめて、極力外部ファイルを取り込むことにした。どれがどれかわからなくなるんで、だったらファイル別にしてしまったほうがマシ。
広告周りのタグは運用をガチるとほぼ必須で、<head><body>に書き込む。
ogpはSEO系のプラグインで仕込めたりするので必須じゃない。
サイト内リンクはこんな感じで。
<ul>
<li><a href="<?php echo esc_url(home_url('/')); ?>" title="home">home</a></li>
<li><a href="<?php echo esc_url(home_url('/about/')); ?>" title="about">about</a></li>
</ul>
WordPress自体にあるメニュー機能を使ってもいいんだけど、必要に駆られたことがなかったり逆に手間がかかってめんどくさかったりで、触り始めた当初は頑張って使ってたけど、もう使ってない。
footer.php
こっちも要点だけ。
<?php wp_footer(); ?>
</body>
</html>
</body>周りに記載したい内容はたまにある。基本的にそんなにない。
あるとすればjsで、該当箇所以降に書けば済んだりするから、ここじゃなくてページの方に書いちゃってもいいような気がする。
index.php
<?php get_header(); ?>
<?php the_title(); ?>
<?php the_content(); ?>
<?php get_footer(); ?>
カスタムフィールドの活用が当たり前になってきたので、トップページは固定ページで作るようになった。各コンテンツ用のファイルも作ってるんでindex.php、home.phpの出番は無い。だけど仕様としてindex.phpは必須ファイルなんで、とりあえずで書いておく。
functions.php
<?php
require_once locate_template('functions/common.php');
require_once locate_template('functions/post.php');
require_once locate_template('functions/plugin.php');
慣れてくるとめっちゃ活用しだすので、functions.phpに書いてたら見返すのがしんどくなったりする。管理的によろしくない感じなので、用途別にファイルを作って読み込む感じにする。
汎用
<?php
//titleタグ生成
add_theme_support( 'title-tag' );
function wp_document_title_separator( $separator ) {
$separator = '|';
return $separator;
}
//css js読み込み
function add_headFiles() {
if(is_admin()) return;
if (is_home() || is_front_page()):
wp_enqueue_style('commonstyle', get_template_directory_uri() .'/style.css', array());
wp_enqueue_script('jQuery', 'https://code.jquery.com/jquery-3.6.1.js', array());
wp_enqueue_script('scripts', get_template_directory_uri() .'/js/script.js"', array());
endif;
if (is_page('form') || is_parent_slug('form')):
wp_enqueue_style('form', get_template_directory_uri() .'/css/form.css', array());
wp_enqueue_script('yubinbango', 'https://yubinbango.github.io/yubinbango/yubinbango.js', array());
wp_enqueue_style('jquery-ui', 'https://code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css', array());
wp_enqueue_script('jquery-ui', 'https://code.jquery.com/ui/1.13.2/jquery-ui.js', array());
wp_enqueue_script('datepicker-ja', get_template_directory_uri() .'/js/datepicker-ja.js', array());
wp_enqueue_script('jquery-autoKana', get_template_directory_uri() .'/js/jquery.autoKana.js', array());
endif;
if (is_single()):
wp_enqueue_style('post-single', get_template_directory_uri() .'/css/post.css', array());
endif;
if(is_singular('news')||is_post_type_archive('news')):
wp_enqueue_style('index', get_template_directory_uri() .'/css/news.css?'.date('Ymd'), array());
endif;
}
add_action('wp_enqueue_scripts', 'add_headFiles');
見たまんま、こんな感じで。
キャッシュさせたくない場合はファイルパスの末尾に何かしら追加すればいいんで、例えばこんな感じで対応。
wp_enqueue_style('commonstyle', get_template_directory_uri() .'/style.css?'.date('YmdHs'), array());
強制的に再読み込みになるんだけど、編集しない間もこれにしておくと不要な読み込みになるのでどうなんでしょうね。
webフォントを読ませたい場合はpreloadも仕込みたくなると思う。wpはカバーしてないっぽい。めんどかったらそこだけheader.phpに書く、ちゃんとやりたい場合は改造をやっていく感じになる。
is_parent_slugは親ページ判別のために作った関数で、後述の内容を追記して使うやつ。
固定ページ・投稿関連
<?php
add_filter( 'document_title_separator', 'wp_document_title_separator' );
//抜粋からpタグ削除
remove_filter('the_excerpt', 'wpautop');
//記事抜粋文字数
function my_excerpt_length($length) {
return 120;
}
add_filter('excerpt_mblength', 'my_excerpt_length');
//抜粋末尾省略文字変更
function my_excerpt_more($more) {
return '';
}
add_filter('excerpt_more', 'my_excerpt_more');
//固定ページ抜粋文有効化
add_post_type_support('page','excerpt');
//アイキャッチ有効化
add_theme_support('post-thumbnails');
//H2にspan追加
function the_content_after_filter($content) {
$content = str_replace('<h2>','<h2><span>',$content);
$content = str_replace('</h2>','</span></h2>',$content);
return $content;
}
add_filter('the_content', 'the_content_after_filter', 10);
//親ページ条件分岐用
function is_parent_slug() {
global $post;
if ($post->post_parent) {
$post_data = get_post($post->post_parent);
return $post_data->post_name;
}
}
ほぼ確実に使う内容。ここはfunctions.phpに書いても良かったようなきがするけど、まあ、うん。
プラグイン周り
<?php
//contact form 7 改行タグ解除
add_filter('wpcf7_autop_or_not', 'wpcf7_autop_return_false');
function wpcf7_autop_return_false() {
return false;
}
// Smart Custom Fields オプションページ生成
/**
* @param string $page_title ページのtitle属性値
* @param string $menu_title 管理画面のメニューに表示するタイトル
* @param string $capability メニューを操作できる権限(maange_options とか)
* @param string $menu_slug オプションページのスラッグ。ユニークな値にすること。
* @param string|null $icon_url メニューに表示するアイコンの URL
* @param int $position メニューの位置
*/
SCF::add_options_page( '共通情報', '共通情報', 'manage_options', 'common-options' );
導入するものとか組み方によっては要らない。
page.php
page.phpは固定ページ汎用、ページごとに分ける場合はpage-○○.phpのようにスラッグを追加する。スラッグを追加したらそのページ専用になるわけだけど、テンプレートにすれば他の固定ページでも使用することができる。
<?php
/*
Template Name: サンプル
*/
?>
<?php get_header(); ?>
<?php the_title(); ?>
<?php the_content(); ?>
<?php get_footer(); ?>
テンプレート化する場合は「Template Name:」を入れる。
テーマ内にテンプレートがある場合、投稿画面でテンプレートの選択ができるようになる。
アイキャッチ
<?php if (has_post_thumbnail()) : ?>
<?php the_post_thumbnail(); ?>
<?php else : ?>
アイキャッチが無い場合
<?php endif ; ?>
引数のところでサイズ調整。WP側の設定に引っ張られるので注意。
the_post_thumbnail(); // パラメータなし -> 'post-thumbnail'
the_post_thumbnail( 'thumbnail' ); // サムネイル (デフォルト 150px x 150px :最大値)
the_post_thumbnail( 'medium' ); // 中サイズ (デフォルト 300px x 300px :最大値)
the_post_thumbnail( 'large' ); // 大サイズ (デフォルト 640px x 640px :最大値)
the_post_thumbnail( 'full' ); // フルサイズ (アップロードした画像の元サイズ)
the_post_thumbnail( array( 100, 100 ) ); // 他のサイズ
URLだけ欲しいときはこう。引数を同様に使える。
<?php the_post_thumbnail_url(); ?>
プラグイン
自作で賄える機能も当然ある。だけどシステム自体をいじったり、テーマを変えたら消えたり、恒久的に使いたいのにってときに不自由するかもだから、後々のことを踏まえて検討するのがいい。めんどかったらプラグインで片付けちゃえばいい。
Custom Post Type UI
カスタム投稿はこれ。使っていて困ったことがない。
記事一覧の取得条件はカスタムフィールドとかタクソノミーの入力内容を含めることもできる。
記事一覧は12件ごとにしておくと大体の場合レスポンシブ時の収まりがよくて便利。
カスタムフィールド
地味に選択肢がある。必須級の要件は「繰り返し」ができること。規模がでかくなるなら「オプションページ」も便利。
SmartCustomFields
当初は好きじゃなかったけどこっちを使ったほうが都合がいいということが分かってしまった。
出力関係
ショートコード埋め込み
<?php echo apply_filters('the_content', ***); ?>
AdvancedCustomFields
繰り返し不要とか、入力箇所を見やすくしたいならこっち。課金すれば繰り返しが使えるようになる。
ショートコード埋め込み
<?php echo apply_filters('the_content', get_post_meta($post->ID, '***', true)); ?>
Custom Field Suite
繰り返しを入れ子にしたい場合はこれ。これ単体の使用はしてなくて、機能がほしいときに限定的に使用する。更新頻度が遅めなのでちょっと怖い。
WP-PageNavi
ブログ、新着情報、商品情報他、一覧が必須のコンテンツは多い。無いと困る。
WP本体の表示件数と一覧の表示件数が合致してないとバグるので注意。
Contact Form 7
フォームはもっぱらこれ。Framingoを入れたら送信内容が管理画面で見れるようになるので便利。
確認画面がないのでユーザーの手間が一つ減る。
ページ遷移しないので送信完了ページにタグを付けなければいけない場合は不向き。
法人用でのフォームだとyubinbango.jsとかで住所の自動挿入を入れるのが大体セット。
Site Kit by Google
アナリティクス関係を連携する。他のプラグインでもいいけど、サービス連携だけが目的ならこれのほうがシンプルにまとまる。
<head>とか要所にタグをベタ打ちしてもいいけど他の計測タグとか広告タグとか混ざったらダルい、header.phpを増やした際に入れ忘れたらめんどい、そういうためのやつ。だからまあ、管理しきれるならそれでいいので必須ではない。
All in One SEO
これを入れておけばだいたいのことが解決する。個人的にはページごとにタイトルとdescriptionを設定できるのがすごく便利。例えばLPを量産したときに、記事タイトルは判別用の記載にしておいてこっちで表示用の内容を指定できていい感じになれる。
Google XML Sitemaps
サーチコンソールで使用するためのサイトマップ生成。登録不要なページを指定できるから便利。ブログ系でSEOを狙っていくなら、既存のfeedよりプラグインに頼ったほうが良さげな面もある。
Breadcrumb NavXT
SEOをやっていきたいならパンくずはあった方がいい。
Easy FancyBox
記事内の画像のポップアップ表示。自分で用意して組むよりもプラグインを使っておけば勝手にやってくれてだいぶ助かる。
.htaccess
タグを含め英文が多い内容を投稿した場合、WAFに引っかかる場合がある。.htaccessに自分のIPを除外するように記載する。
コメント