ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
WordPress テーマと PHP
WordPress のテーマは PHP ファイルの集合体です。テンプレート階層 (Template Hierarchy) に従って、表示されるページに対応する PHP が選ばれて実行されます。
| ページ | 使われる PHP(優先順) |
|---|---|
| トップ(投稿一覧) | home.php → index.php |
| 個別投稿 | single-{post_type}.php → single.php → singular.php → index.php |
| 固定ページ | page-{slug}.php → page-{id}.php → page.php |
| カテゴリーアーカイブ | category-{slug}.php → category.php → archive.php |
| 404 | 404.php → index.php |
| 検索結果 | search.php → index.php |
functions.php でフックを使う
WordPress は「アクション (action)」と「フィルター (filter)」のフックで動作を拡張します:
<?php
// テーマの functions.php
// アクション: 何かの「タイミング」で処理を実行
add_action('after_setup_theme', function () {
// テーマがセットアップされた直後
add_theme_support('post-thumbnails'); // アイキャッチ画像
add_theme_support('title-tag'); // <title> 自動出力
add_theme_support('html5', ['search-form', 'comment-form', 'gallery']);
register_nav_menus([
'primary' => 'メインメニュー',
'footer' => 'フッターメニュー',
]);
});
// フィルター: 値を加工して返す
add_filter('the_title', function ($title, $post_id) {
if (is_admin()) return $title;
return '★ ' . $title;
}, 10, 2);
add_filter('excerpt_more', function () {
return ' ... <a href="' . get_permalink() . '">続きを読む</a>';
});
// 投稿保存時に何かしたい
add_action('save_post', function ($post_id) {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
// 何か処理(キャッシュ削除など)
});
テンプレートでの The Loop
WordPress テンプレートの中核は「The Loop」と呼ばれる投稿の繰り返し処理です:
<?php
// single.php の例
get_header();
?>
<main>
<?php if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<h1><?php the_title(); ?></h1>
<div class="meta">
<time datetime="<?php the_time('c'); ?>">
<?php the_time(get_option('date_format')); ?>
</time>
by <?php the_author(); ?>
</div>
<?php if (has_post_thumbnail()) : ?>
<?php the_post_thumbnail('large'); ?>
<?php endif; ?>
<div class="content"><?php the_content(); ?></div>
</article>
<?php comments_template(); ?>
<?php endwhile; ?>
<?php else : ?>
<p>投稿が見つかりません</p>
<?php endif; ?>
</main>
<?php
get_sidebar();
get_footer();
WP_Query / get_posts でカスタムクエリ
<?php
// 特定カテゴリの最新 5 件
$query = new WP_Query([
'post_type' => 'post',
'posts_per_page' => 5,
'category_name' => 'news',
'orderby' => 'date',
'order' => 'DESC',
]);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
// The Loop の中
echo '<h3><a href="' . get_permalink() . '">' . get_the_title() . '</a></h3>';
}
wp_reset_postdata(); // ★ 必須: グローバル $post を戻す
}
// より簡潔に get_posts(自動リセット不要だが少し低機能)
$posts = get_posts([
'numberposts' => 3,
'category' => 5,
'meta_key' => 'featured',
'meta_value' => 'yes',
]);
foreach ($posts as $p) {
setup_postdata($GLOBALS['post'] = $p);
echo get_the_title($p);
}
wp_reset_postdata();
カスタム投稿タイプ (Custom Post Type)
add_action('init', function () {
register_post_type('product', [
'label' => '商品',
'public' => true,
'has_archive' => true,
'menu_icon' => 'dashicons-cart',
'supports' => ['title', 'editor', 'thumbnail', 'custom-fields'],
'rewrite' => ['slug' => 'products'],
'show_in_rest' => true, // Gutenberg / REST API 対応
]);
register_taxonomy('product_category', 'product', [
'label' => '商品カテゴリ',
'hierarchical' => true, // カテゴリ風(false ならタグ風)
'show_in_rest' => true,
]);
});
// アーカイブテンプレート: archive-product.php
// 個別テンプレート: single-product.php
ACF (Advanced Custom Fields)
ACF プラグインを入れると、管理画面でカスタムフィールド(任意のキー・型)を設計でき、テーマからは関数で値を呼べます:
// テキストフィールド
$price = get_field('price');
echo esc_html($price);
// 画像フィールド(return format = Image Array)
$img = get_field('hero_image');
if ($img) {
echo '<img src="' . esc_url($img['url']) . '" alt="' . esc_attr($img['alt']) . '">';
}
// 繰り返しフィールド
if (have_rows('faqs')) {
echo '<dl class="faq">';
while (have_rows('faqs')) {
the_row();
echo '<dt>' . esc_html(get_sub_field('question')) . '</dt>';
echo '<dd>' . wp_kses_post(get_sub_field('answer')) . '</dd>';
}
echo '</dl>';
}
JS / CSS の読み込み (wp_enqueue)
テンプレートに直接 <script> や <link> を書くのは非推奨。WordPress の依存解決機構を活かすため wp_enqueue_script / wp_enqueue_style を使います。
add_action('wp_enqueue_scripts', function () {
// CSS
wp_enqueue_style(
'theme-main',
get_stylesheet_uri(),
[],
wp_get_theme()->get('Version') // バージョン (キャッシュ対策)
);
// JS(footer に出力、jQuery 依存)
wp_enqueue_script(
'theme-main',
get_template_directory_uri() . '/js/main.js',
['jquery'],
'1.0.0',
true // footer 読み込み
);
// JS に PHP からデータ受け渡し
wp_localize_script('theme-main', 'ThemeData', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('theme_nonce'),
]);
});
ショートコード (Shortcode)
add_shortcode('hello', function ($atts, $content = null) {
$atts = shortcode_atts(['name' => 'Guest'], $atts);
return '<div class="hello">こんにちは、' . esc_html($atts['name']) . 'さん!'
. do_shortcode($content) . '</div>';
});
// 投稿本文中で [hello name="太郎"]中身[/hello]
子テーマ (Child Theme)
親テーマをそのまま改造するとアップデートで上書きされます。子テーマを作って差分だけ書きます:
// wp-content/themes/twentytwentyfour-child/style.css
/*
Theme Name: Twenty Twenty-Four Child
Template: twentytwentyfour
Version: 1.0.0
*/
// functions.php
add_action('wp_enqueue_scripts', function () {
wp_enqueue_style('parent-style', get_template_directory_uri() . '/style.css');
wp_enqueue_style('child-style',
get_stylesheet_directory_uri() . '/style.css',
['parent-style'],
wp_get_theme()->get('Version')
);
});
// 親と同じ名前のテンプレ (例: single.php) を置けば子が優先される
デバッグ: WP_DEBUG
// wp-config.php
define('WP_DEBUG', true); // エラー表示有効
define('WP_DEBUG_LOG', true); // wp-content/debug.log に出力
define('WP_DEBUG_DISPLAY', false); // 画面には出さない(本番準拠)
define('SCRIPT_DEBUG', true); // 非ミニファイ版 JS/CSS
// テーマからログ
error_log('値: ' . print_r($value, true));
セキュリティ: エスケープ / Nonce
// 出力時のエスケープ(必須)
echo esc_html($user_input); // HTML 用
echo esc_attr($attr); // 属性用
echo esc_url($link); // URL 用
echo wp_kses_post($html_content); // 投稿本文相当の HTML を許可
// CSRF (Nonce)
$nonce = wp_create_nonce('my_action');
// フォーム内に <?php wp_nonce_field('my_action'); ?>
if (!wp_verify_nonce($_POST['_wpnonce'] ?? '', 'my_action')) {
wp_die('不正なリクエスト');
}
// SQL(プレースホルダ)
global $wpdb;
$wpdb->get_results($wpdb->prepare(
"SELECT * FROM {$wpdb->posts} WHERE post_status = %s LIMIT %d",
'publish', 10
));
FAQ
Q: functions.php と プラグインの違い
A: 機能がテーマ固有(見た目寄り)なら functions.php、サイト共通機能(CPT 等)はプラグイン化推奨。テーマ変更しても残せます。
Q: Gutenberg ブロックを PHP で作りたい
A: register_block_type + render_callback。ブロックエディタ側は JS 必要ですが「ダイナミックブロック」はサーバ側 PHP でレンダリングします。
Q: WP_Query と get_posts どっちを使う?
A: 機能差はあまり無く、WP_Query はオブジェクト指向で柔軟、get_posts は配列で受け取れる手軽さ。複雑なクエリやページング使うなら WP_Query。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- IPv6とは|128bitアドレス・コロン16進表記/::省略・リンクローカル・SLAAC・デュアルスタック NEW 2026-06-22 12:34:44
- MAC アドレスフィルタリングの仕組みと限界 | ネットワーク入門 NEW 2026-06-22 12:19:10
- VPNとは|暗号トンネル・サイト間/リモートアクセス・IPsec/SSL-VPN/WireGuardを解説 NEW 2026-06-22 12:19:10
- WebRTC とは ブラウザ間 P2P の音声・映像・データ通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/2 とは 多重化・HPACK・バイナリフレーム | ネットワーク入門 NEW 2026-06-22 12:17:25
- Web通信プロトコル入門 HTTP/2・HTTP/3・WebSocket・gRPC・WebRTC | ネットワーク入門 NEW 2026-06-22 12:17:25
- gRPC とは HTTP/2 + Protocol Buffers の高速 RPC | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/3 (QUIC) とは UDP ベースの低遅延 Web 通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- WebSocket とは 全二重リアルタイム通信 ws/wss | ネットワーク入門 NEW 2026-06-22 12:17:25
- 証明書と認証局(CA)とは|X.509・信頼チェーン・DV/OV/EV・失効(CRL/OCSP)を解説 NEW 2026-06-22 12:17:24
- ファイアウォールとは|パケットフィルタ・ステートフル・DMZ・次世代FW(L4/L7)を解説 NEW 2026-06-22 12:17:24
- iptables/nftablesとは|テーブル・チェーン・ルール例・永続化をLinux視点で解説 NEW 2026-06-22 12:17:24
- HAProxy とは frontend/backend と設定例 | ネットワーク入門 NEW 2026-06-22 12:17:24
- CDN とは エッジキャッシュ・TTL・Cloudflare/CloudFront | ネットワーク入門 NEW 2026-06-22 12:17:24
- TLS/SSLの仕組み|ハンドシェイク・暗号スイート・前方秘匿性・証明書検証をわかりやすく解説 NEW 2026-06-22 12:17:24
コメントを削除してもよろしいでしょうか?