1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

必要最低限のwordpress オリジナルテンプレートひな形

1
Last updated at Posted at 2025-02-16

wordpressの必要最低限のサンプル

説明の多い、親切なサイトがたくさんありますが、コピペできるような超シンプルなテンプレートのひな形を作りました。各テンプレートファイルの必要最低限の記載です。
とりあえず貼り付けての改造用にどうぞ。

style.css

必須のテンプレートの1つで、テーマ名の記載が必要です。

/*
Theme Name: Minimal Theme
Theme URI: 
Author: Your Name
Author URI: 
Description: A minimal WordPress theme
Version: 1.0
License: GNU General Public License v2 or later
*/

/* style.css */
body {
    font-family: Arial, sans-serif;
    line-height: 1.6;
    margin: 0;
    padding: 0;
}

.container {
    width: 80%;
    margin: 0 auto;
}

header.php

※タイトルタグをheadに書かず、functions.phpに下記を入れるとwordpressが書き出してくれます。

add_theme_support( 'title-tag' );
/* header.php */
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
    <meta charset="<?php bloginfo('charset'); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
<header>
    <div class="container">
        <h1><a href="<?php echo home_url(); ?>"><?php bloginfo('name'); ?></a></h1>
        <nav>
            <?php wp_nav_menu(array('theme_location' => 'primary-menu')); ?>
        </nav>
    </div>
</header>

index.php

/* index.php */
<?php get_header(); ?>

<main class="container">
    <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
        <article>
            <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
            <?php the_excerpt(); ?>
        </article>
    <?php endwhile; endif; ?>
</main>

<?php get_footer(); ?>

front-page.php

/* front-page.php */
<?php get_header(); ?>

<main class="container">
    <section class="hero">
        <h2><?php bloginfo('description'); ?></h2>
    </section>

    <section class="latest-posts">
        <h2>最新の記事</h2>
        <?php
        $args = array(
            'post_type' => 'post',
            'posts_per_page' => 3
        );
        $latest_posts = new WP_Query($args);
        
        if ($latest_posts->have_posts()) : while ($latest_posts->have_posts()) : $latest_posts->the_post();
        ?>
            <article>
                <?php if (has_post_thumbnail()) : ?>
                    <div class="post-thumbnail">
                        <?php the_post_thumbnail('medium'); ?>
                    </div>
                <?php endif; ?>
                <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
                <?php the_excerpt(); ?>
            </article>
        <?php 
        endwhile;
        wp_reset_postdata();
        endif;
        ?>
    </section>
</main>

<?php get_footer(); ?>

page.php

/* page.php */
<?php get_header(); ?>

<main class="container">
    <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
        <article class="page-content">
            <h1><?php the_title(); ?></h1>
            <?php if (has_post_thumbnail()) : ?>
                <div class="page-thumbnail">
                    <?php the_post_thumbnail('large'); ?>
                </div>
            <?php endif; ?>
            <div class="page-text">
                <?php the_content(); ?>
            </div>
        </article>
    <?php endwhile; endif; ?>
</main>

<?php get_footer(); ?>

single.php

/* single.php */
<?php get_header(); ?>

<main class="container">
    <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
        <article class="single-post">
            <header class="post-header">
                <h1><?php the_title(); ?></h1>
                <div class="post-meta">
                    <time><?php the_time('Y年n月j日'); ?></time>
                    <span class="post-author"><?php the_author(); ?></span>
                    <span class="post-categories"><?php the_category(', '); ?></span>
                </div>
            </header>

            <?php if (has_post_thumbnail()) : ?>
                <div class="post-thumbnail">
                    <?php the_post_thumbnail('large'); ?>
                </div>
            <?php endif; ?>

            <div class="post-content">
                <?php the_content(); ?>
            </div>

            <footer class="post-footer">
                <?php the_tags('<div class="post-tags">タグ: ', ', ', '</div>'); ?>
                <?php comments_template(); ?>
            </footer>
        </article>
    <?php endwhile; endif; ?>
</main>

<?php get_footer(); ?>

archive.php

/* archive.php */
<?php get_header(); ?>

<main class="container">
    <header class="archive-header">
        <h1>
            <?php
            if (is_category()) {
                single_cat_title('カテゴリー: ');
            } elseif (is_tag()) {
                single_tag_title('タグ: ');
            } elseif (is_author()) {
                echo '投稿者: ' . get_the_author();
            } elseif (is_date()) {
                if (is_year()) {
                    echo get_the_date('Y年').'の記事';
                } elseif (is_month()) {
                    echo get_the_date('Y年n月').'の記事';
                }
            } else {
                echo 'アーカイブ';
            }
            ?>
        </h1>
    </header>

    <?php if (have_posts()) : ?>
        <div class="archive-posts">
            <?php while (have_posts()) : the_post(); ?>
                <article class="archive-post">
                    <?php if (has_post_thumbnail()) : ?>
                        <div class="post-thumbnail">
                            <?php the_post_thumbnail('medium'); ?>
                        </div>
                    <?php endif; ?>
                    <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
                    <div class="post-meta">
                        <time><?php the_time('Y年n月j日'); ?></time>
                    </div>
                    <?php the_excerpt(); ?>
                </article>
            <?php endwhile; ?>

            <div class="pagination">
                <?php echo paginate_links(); ?>
            </div>
        </div>
    <?php else : ?>
        <p>記事が見つかりませんでした。</p>
    <?php endif; ?>
</main>

<?php get_footer(); ?>

footer.php

/* footer.php */
    <footer>
        <div class="container">
            <p>&copy; <?php echo date('Y'); ?> <?php bloginfo('name'); ?></p>
        </div>
    </footer>
    <?php wp_footer(); ?>
</body>
</html>

###404.php

/* 404.php */
<?php get_header(); ?>

<main class="container">
    <div class="error-404">
        <h1>404 - ページが見つかりません</h1>
        <p>お探しのページは存在しないか、移動した可能性があります。</p>
        
        <div class="search-form">
            <h2>サイト内検索</h2>
            <?php get_search_form(); ?>
        </div>

        <div class="recent-posts">
            <h2>最近の投稿</h2>
            <ul>
                <?php
                wp_get_archives(array(
                    'type' => 'postbypost',
                    'limit' => 5
                ));
                ?>
            </ul>
        </div>
    </div>
</main>

<?php get_footer(); ?>

searchform.php

/* searchform.php */
<form role="search" method="get" class="search-form" action="<?php echo home_url('/'); ?>">
    <label>
        <span class="screen-reader-text">検索:</span>
        <input type="search" class="search-field" placeholder="検索..." value="<?php echo get_search_query(); ?>" name="s" />
    </label>
    <button type="submit" class="search-submit">検索</button>
</form>

search.php

/* search.php */
<?php get_header(); ?>

<main class="container">
    <header class="page-header">
        <h1>
            <?php
            printf(
                '検索結果: %s',
                '<span>' . get_search_query() . '</span>'
            );
            ?>
        </h1>
    </header>

    <?php if (have_posts()) : ?>
        <div class="search-results">
            <?php while (have_posts()) : the_post(); ?>
                <article class="search-result">
                    <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
                    <div class="entry-meta">
                        <span class="post-type"><?php echo get_post_type(); ?></span>
                        <time><?php the_time('Y年n月j日'); ?></time>
                    </div>
                    <?php the_excerpt(); ?>
                </article>
            <?php endwhile; ?>

            <?php echo paginate_links(); ?>
        </div>
    <?php else : ?>
        <div class="no-results">
            <p>検索条件に一致する記事は見つかりませんでした。</p>
            <?php get_search_form(); ?>
        </div>
    <?php endif; ?>
</main>

<?php get_footer(); ?>

sidebar.php

/* sidebar.php */
<aside class="widget-area">
    <?php if (is_active_sidebar('sidebar-1')) : ?>
        <?php dynamic_sidebar('sidebar-1'); ?>
    <?php else : ?>
        <section class="widget">
            <h2 class="widget-title">カテゴリー</h2>
            <ul>
                <?php wp_list_categories('title_li='); ?>
            </ul>
        </section>
        
        <section class="widget">
            <h2 class="widget-title">アーカイブ</h2>
            <ul>
                <?php wp_get_archives('type=monthly'); ?>
            </ul>
        </section>
    <?php endif; ?>
</aside>

###comments.php

/* comments.php */
<?php
if (post_password_required()) {
    return;
}
?>

<div id="comments" class="comments-area">
    <?php if (have_comments()) : ?>
        <h2 class="comments-title">
            <?php
            printf(
                _n(
                    'コメント(%1$s)',
                    'コメント(%1$s)',
                    get_comments_number()
                ),
                number_format_i18n(get_comments_number())
            );
            ?>
        </h2>

        <ol class="comment-list">
            <?php
            wp_list_comments(array(
                'style'       => 'ol',
                'short_ping'  => true,
                'avatar_size' => 60,
            ));
            ?>
        </ol>

        <?php if (get_comment_pages_count() > 1 && get_option('page_comments')) : ?>
            <nav class="comment-navigation">
                <div class="nav-previous"><?php previous_comments_link('前のコメント'); ?></div>
                <div class="nav-next"><?php next_comments_link('次のコメント'); ?></div>
            </nav>
        <?php endif; ?>
    <?php endif; ?>

    <?php if (!comments_open() && get_comments_number() && post_type_supports(get_post_type(), 'comments')) : ?>
        <p class="no-comments">コメントは締め切られました。</p>
    <?php endif; ?>

    <?php comment_form(); ?>
</div>

template-parts/content.php

/* template-parts/content.php */
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
    <header class="entry-header">
        <?php if (is_singular()) : ?>
            <h1 class="entry-title"><?php the_title(); ?></h1>
        <?php else : ?>
            <h2 class="entry-title">
                <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
            </h2>
        <?php endif; ?>

        <?php if ('post' === get_post_type()) : ?>
            <div class="entry-meta">
                <span class="posted-on">
                    <?php the_time('Y年n月j日'); ?>
                </span>
                <span class="byline">
                    <?php the_author_posts_link(); ?>
                </span>
            </div>
        <?php endif; ?>
    </header>

    <?php if (has_post_thumbnail() && !is_singular()) : ?>
        <div class="post-thumbnail">
            <a href="<?php the_permalink(); ?>">
                <?php the_post_thumbnail('medium'); ?>
            </a>
        </div>
    <?php endif; ?>

    <div class="entry-content">
        <?php
        if (is_singular()) {
            the_content();
        } else {
            the_excerpt();
            echo '<a href="' . esc_url(get_permalink()) . '" class="more-link">続きを読む</a>';
        }
        ?>
    </div>
</article>

functions.php

/* functions.php */
<?php
//スイッチオフになっている機能をオンにする
function minimal_theme_setup() {
    register_nav_menus(array('primary-menu' => 'Primary Menu')); //管理画面でメニューの作成・編集が可能になる
    add_theme_support('automatic-feed-links'); //RSSフィードのリンクを自動的に出力
    add_theme_support('post-thumbnails'); //投稿やページでアイキャッチ画像を使用可能に
    add_theme_support('title-tag'); //ページタイトルの自動出力をサポート
}
add_action('after_setup_theme', 'minimal_theme_setup');

//jsとCSS読み込み
function my_script_init() {
  wp_enqueue_style("font-awesome", "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.2/css/all.min.css", array(), "5.8.2", "all");
  wp_enqueue_style("my", get_template_directory_uri() . "/css/style.css", array(), filemtime(get_theme_file_path('css/style.css')), "all");
  wp_enqueue_script("my", get_template_directory_uri() . "/js/script.js", array("jquery"), filemtime(get_theme_file_path('js/script.js')), true);
}
add_action("wp_enqueue_scripts", "my_script_init");

カスタムフィールド

よくありそうなサンプル集

<?php
/**
 * WordPress ACF Pro テンプレートサンプル(シンプル版)
 * post_type: post を使用
 */

// ===========================================
// 1. functions.php - 基本設定のみ
// ===========================================

// テーマサポート
function theme_setup() {
    add_theme_support('post-thumbnails');
    add_theme_support('title-tag');
}
add_action('after_setup_theme', 'theme_setup');

// カテゴリー自動作成(テーマ有効化時)
function create_default_categories() {
    $categories = ['ビジネス', 'テクノロジー', 'ライフスタイル', 'エンターテイメント', 'スポーツ'];
    
    foreach ($categories as $cat_name) {
        if (!term_exists($cat_name, 'category')) {
            wp_insert_term($cat_name, 'category');
        }
    }
}
add_action('after_switch_theme', 'create_default_categories');

// ===========================================
// 2. index.php - メインページ
// ===========================================
?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
    <meta charset="<?php bloginfo('charset'); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <?php wp_head(); ?>
</head>
<body>
    <div class="container">
        <header>
            <h1><?php bloginfo('name'); ?></h1>
            <p><?php bloginfo('description'); ?></p>
        </header>

        <!-- カテゴリーナビゲーション -->
        <nav>
            <a href="<?php echo home_url(); ?>">すべて</a>
            <?php
            $categories = get_categories();
            foreach ($categories as $category) {
                echo '<a href="' . get_category_link($category->term_id) . '">' . $category->name . '</a> ';
            }
            ?>
        </nav>

        <!-- 投稿一覧 -->
        <main>
            <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
                <?php 
                $priority = get_field('priority');
                $subtitle = get_field('subtitle');
                ?>
                <article>
                    <?php if (has_post_thumbnail()) : ?>
                        <div>
                            <a href="<?php the_permalink(); ?>">
                                <?php the_post_thumbnail('medium'); ?>
                            </a>
                        </div>
                    <?php endif; ?>
                    
                    <div>
                        <h2>
                            <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
                        </h2>
                        
                        <?php if ($subtitle) : ?>
                            <p><em><?php echo $subtitle; ?></em></p>
                        <?php endif; ?>
                        
                        <div>
                            <?php echo get_the_date(); ?> | 
                            <?php the_category(', '); ?>
                            <?php if ($priority && $priority !== 'normal') : ?>
                                | <strong><?php echo $priority === 'important' ? '重要' : '緊急'; ?></strong>
                            <?php endif; ?>
                        </div>
                        
                        <div>
                            <?php the_excerpt(); ?>
                        </div>
                        
                        <?php 
                        $custom_tags = get_field('tags_custom');
                        if ($custom_tags) :
                            $tags_array = explode(',', $custom_tags);
                        ?>
                            <div>
                                <strong>タグ: </strong>
                                <?php foreach ($tags_array as $tag) : ?>
                                    <span><?php echo trim($tag); ?></span> 
                                <?php endforeach; ?>
                            </div>
                        <?php endif; ?>
                    </div>
                </article>
                <hr>
            <?php endwhile; endif; ?>
        </main>
    </div>
    <?php wp_footer(); ?>
</body>
</html>

<?php
// ===========================================
// 3. single.php - 個別投稿ページ
// ===========================================
?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
    <meta charset="<?php bloginfo('charset'); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <?php wp_head(); ?>
</head>
<body>
    <div class="container">
        <a href="<?php echo home_url(); ?>">← トップページに戻る</a>
        
        <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
            <?php 
            $priority = get_field('priority');
            $subtitle = get_field('subtitle');
            $featured_alt = get_field('featured_image_alt');
            $custom_tags = get_field('tags_custom');
            $related_links = get_field('related_links');
            ?>
            
            <article>
                <header>
                    <h1>
                        <?php the_title(); ?>
                        <?php if ($priority && $priority !== 'normal') : ?>
                            <span><?php echo $priority === 'important' ? '重要' : '緊急'; ?></span>
                        <?php endif; ?>
                    </h1>
                    
                    <?php if ($subtitle) : ?>
                        <p><em><?php echo $subtitle; ?></em></p>
                    <?php endif; ?>
                    
                    <div>
                        投稿日: <?php echo get_the_date(); ?> | 
                        カテゴリー: <?php the_category(', '); ?> | 
                        投稿者: <?php the_author(); ?>
                    </div>
                </header>
                
                <?php if (has_post_thumbnail()) : ?>
                    <div>
                        <?php the_post_thumbnail('large'); ?>
                    </div>
                <?php endif; ?>
                
                <div>
                    <?php the_content(); ?>
                </div>
                
                <?php if ($featured_alt) : ?>
                    <div>
                        <h3>関連画像</h3>
                        <img src="<?php echo $featured_alt['url']; ?>" alt="<?php echo $featured_alt['alt']; ?>">
                    </div>
                <?php endif; ?>
                
                <?php if ($custom_tags) : ?>
                    <div>
                        <strong>タグ: </strong>
                        <?php 
                        $tags_array = explode(',', $custom_tags);
                        foreach ($tags_array as $tag) : 
                        ?>
                            <span><?php echo trim($tag); ?></span> 
                        <?php endforeach; ?>
                    </div>
                <?php endif; ?>
                
                <?php if ($related_links) : ?>
                    <div>
                        <h3>関連リンク</h3>
                        <ul>
                            <?php foreach ($related_links as $link) : ?>
                                <li>
                                    <a href="<?php echo $link['link_url']; ?>" target="_blank" rel="noopener">
                                        <?php echo $link['link_title']; ?>
                                    </a>
                                </li>
                            <?php endforeach; ?>
                        </ul>
                    </div>
                <?php endif; ?>
            </article>
        <?php endwhile; endif; ?>
    </div>
    <?php wp_footer(); ?>
</body>
</html>

<?php
// ===========================================
// 4. category.php - カテゴリー別一覧ページ
// ===========================================
?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
    <meta charset="<?php bloginfo('charset'); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title><?php single_cat_title(); ?> | <?php bloginfo('name'); ?></title>
    <?php wp_head(); ?>
</head>
<body>
    <div class="container">
        <a href="<?php echo home_url(); ?>">← トップページに戻る</a>
        
        <header>
            <h1><?php single_cat_title(); ?></h1>
            <p><?php echo category_description(); ?></p>
            <p><strong><?php echo $wp_query->found_posts; ?></strong> 件の記事があります</p>
        </header>
        
        <main>
            <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
                <?php 
                $priority = get_field('priority');
                $subtitle = get_field('subtitle');
                ?>
                <article>
                    <?php if (has_post_thumbnail()) : ?>
                        <div>
                            <a href="<?php the_permalink(); ?>">
                                <?php the_post_thumbnail('medium'); ?>
                            </a>
                        </div>
                    <?php endif; ?>
                    
                    <div>
                        <h2>
                            <a href="<?php the_permalink(); ?>">
                                <?php the_title(); ?>
                                <?php if ($priority && $priority !== 'normal') : ?>
                                    <span><?php echo $priority === 'important' ? '重要' : '緊急'; ?></span>
                                <?php endif; ?>
                            </a>
                        </h2>
                        
                        <?php if ($subtitle) : ?>
                            <p><em><?php echo $subtitle; ?></em></p>
                        <?php endif; ?>
                        
                        <div>
                            <?php echo get_the_date(); ?> | <?php the_author(); ?>
                        </div>
                        
                        <div>
                            <?php the_excerpt(); ?>
                        </div>
                    </div>
                </article>
                <hr>
            <?php endwhile; else : ?>
                <div>
                    <h2>まだ投稿がありません</h2>
                    <p>このカテゴリーにはまだ記事が投稿されていません。</p>
                </div>
            <?php endif; ?>
        </main>
        
        <!-- ページネーション -->
        <div>
            <?php previous_posts_link('← 前のページ'); ?>
            <?php next_posts_link('次のページ →'); ?>
        </div>
    </div>
    <?php wp_footer(); ?>
</body>
</html>

<?php
// ===========================================
// 5. style.css - テーマ情報
// ===========================================
/*
Theme Name: ACF Sample Theme
Description: ACF Proを使ったシンプルなサンプルテーマ
Version: 1.0
Author: Your Name
*/
?>

<?php
// ===========================================
// ACF Pro プラグイン設定内容
// ===========================================
/*

【フィールドグループ作成手順】

1. ACF Pro管理画面で「フィールドグループ」→「新規追加」

2. フィールドグループ名: 「投稿詳細情報」

3. 以下のフィールドを追加:

■ フィールド1: サブタイトル
- フィールドラベル: サブタイトル
- フィールド名: subtitle
- フィールドタイプ: テキスト
- 説明: タイトルの補足説明

■ フィールド2: アイキャッチ画像(追加)
- フィールドラベル: アイキャッチ画像(追加)
- フィールド名: featured_image_alt
- フィールドタイプ: 画像
- 説明: メイン画像とは別の補助画像
- 戻り値: 画像配列

■ フィールド3: 記事の重要度
- フィールドラベル: 記事の重要度
- フィールド名: priority
- フィールドタイプ: セレクトボックス
- 選択肢:
  normal : 通常
  important : 重要
  urgent : 緊急
- デフォルト値: normal

■ フィールド4: カスタムタグ
- フィールドラベル: カスタムタグ
- フィールド名: tags_custom
- フィールドタイプ: テキスト
- 説明: カンマ区切りで入力

■ フィールド5: 関連リンク
- フィールドラベル: 関連リンク
- フィールド名: related_links
- フィールドタイプ: リピーター
- 最小行数: 0
- 最大行数: 5
- レイアウト: テーブル

  サブフィールド1:
  - フィールドラベル: リンクタイトル
  - フィールド名: link_title
  - フィールドタイプ: テキスト

  サブフィールド2:
  - フィールドラベル: URL
  - フィールド名: link_url
  - フィールドタイプ: URL

4. 位置ルール設定:
- 投稿タイプ が次と等しい post

5. 設定:
- 位置: コンテンツエディタの下
- スタイル: デフォルト
- ラベルの配置: 上

*/
?>

カスタム投稿タイプサンプル2



<?php
/**
 * WordPress Food カスタム投稿テンプレート(別パターン)
 * カスタム投稿タイプ: food
 * カスタムタクソノミー: cuisine_type
 */

// ===========================================
// 1. functions.php - カスタム投稿タイプとタクソノミー登録
// ===========================================

// カスタム投稿タイプ「food」の登録
function register_food_post_type() {
    register_post_type('food', array(
        'label' => 'レシピ',
        'public' => true,
        'has_archive' => true,
        'supports' => array('title', 'editor', 'thumbnail', 'author'),
        'menu_icon' => 'dashicons-carrot',
        'rewrite' => array('slug' => 'recipe'),
        'labels' => array(
            'name' => 'レシピ',
            'singular_name' => 'レシピ',
            'add_new' => '新規追加',
            'add_new_item' => '新しいレシピを追加',
            'edit_item' => 'レシピを編集',
            'new_item' => '新しいレシピ',
            'view_item' => 'レシピを表示',
            'search_items' => 'レシピを検索',
            'not_found' => 'レシピが見つかりません',
        ),
    ));
}
add_action('init', 'register_food_post_type');

// カスタムタクソノミー「cuisine_type」の登録
function register_cuisine_taxonomy() {
    register_taxonomy('cuisine_type', 'food', array(
        'label' => '料理ジャンル',
        'public' => true,
        'hierarchical' => true,
        'show_ui' => true,
        'show_admin_column' => true,
        'rewrite' => array('slug' => 'cuisine'),
        'labels' => array(
            'name' => '料理ジャンル',
            'singular_name' => '料理ジャンル',
            'add_new_item' => '新しいジャンルを追加',
            'edit_item' => 'ジャンルを編集',
        ),
    ));
}
add_action('init', 'register_cuisine_taxonomy');

// デフォルトタクソノミーターム作成
function create_default_cuisine_terms() {
    $terms = array(
        'japanese' => '和食',
        'western' => '洋食',
        'chinese' => '中華',
        'italian' => 'イタリアン',
        'korean' => '韓国料理'
    );
    
    foreach ($terms as $slug => $name) {
        if (!term_exists($name, 'cuisine_type')) {
            wp_insert_term($name, 'cuisine_type', array('slug' => $slug));
        }
    }
}
add_action('after_switch_theme', 'create_default_cuisine_terms');

// ===========================================
// 2. archive-food.php - レシピ一覧ページ
// ===========================================
?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
    <meta charset="<?php bloginfo('charset'); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>レシピ一覧 | <?php bloginfo('name'); ?></title>
    <?php wp_head(); ?>
</head>
<body>
    <div class="container">
        <header>
            <h1>今日のおすすめレシピ</h1>
            <p>各ジャンルから最新のレシピをご紹介</p>
            <a href="<?php echo home_url(); ?>">← ホームに戻る</a>
        </header>

        <?php
        // 投稿があるタクソノミータームのみ取得
        $terms = get_terms(array(
            'taxonomy' => 'cuisine_type',
            'hide_empty' => true,
            'orderby' => 'slug',
            'order' => 'ASC'
        ));
        ?>

        <?php if (!empty($terms) && !is_wp_error($terms)) : ?>
            <!-- ページ内ナビゲーション -->
            <nav class="quick-nav">
                <h2>ジャンル別メニュー</h2>
                <ul>
                    <?php foreach ($terms as $term) : ?>
                        <li>
                            <a href="#<?php echo esc_attr($term->slug); ?>">
                                <?php echo esc_html($term->name); ?>
                                <span>(<?php echo $term->count; ?>)</span>
                            </a>
                        </li>
                    <?php endforeach; ?>
                </ul>
            </nav>

            <!-- 各ジャンルのセクション -->
            <main class="recipes-container">
                <?php foreach ($terms as $term) : ?>
                    <section id="<?php echo esc_attr($term->slug); ?>" class="cuisine-section">
                        <header class="section-header">
                            <h2><?php echo esc_html($term->name); ?></h2>
                            <?php if ($term->description) : ?>
                                <p><?php echo esc_html($term->description); ?></p>
                            <?php endif; ?>
                            <a href="<?php echo get_term_link($term); ?>" class="view-all">
                                すべての<?php echo esc_html($term->name); ?>を見る →
                            </a>
                        </header>
                        
                        <?php
                        // 各ジャンルの最新レシピ1件を取得
                        $recipe_query = new WP_Query(array(
                            'post_type' => 'food',
                            'post_status' => 'publish',
                            'posts_per_page' => 1,
                            'orderby' => 'date',
                            'order' => 'DESC',
                            'tax_query' => array(
                                array(
                                    'taxonomy' => 'cuisine_type',
                                    'field' => 'term_id',
                                    'terms' => $term->term_id,
                                ),
                            ),
                        ));
                        ?>

                        <?php if ($recipe_query->have_posts()) : ?>
                            <?php while ($recipe_query->have_posts()) : $recipe_query->the_post(); ?>
                                <article class="featured-recipe">
                                    <div class="recipe-image">
                                        <?php if (has_post_thumbnail()) : ?>
                                            <a href="<?php the_permalink(); ?>">
                                                <?php the_post_thumbnail('large'); ?>
                                            </a>
                                        <?php else : ?>
                                            <div class="no-image">画像なし</div>
                                        <?php endif; ?>
                                    </div>
                                    
                                    <div class="recipe-content">
                                        <h3>
                                            <a href="<?php the_permalink(); ?>">
                                                <?php the_title(); ?>
                                            </a>
                                        </h3>
                                        
                                        <div class="recipe-meta">
                                            <span class="date">投稿: <?php echo get_the_date('Y.m.d'); ?></span>
                                            <span class="author">by <?php the_author(); ?></span>
                                        </div>

                                        <div class="recipe-excerpt">
                                            <?php 
                                            if (has_excerpt()) {
                                                the_excerpt();
                                            } else {
                                                echo wp_trim_words(get_the_content(), 30, '...');
                                            }
                                            ?>
                                        </div>

                                        <?php
                                        // ジャンル別カスタムフィールド表示
                                        echo '<div class="recipe-details">';
                                        
                                        switch ($term->slug) {
                                            case 'japanese':
                                                $cooking_method = get_field('cooking_method');
                                                $dashi_type = get_field('dashi_type');
                                                $regional_style = get_field('regional_style');
                                                
                                                if ($cooking_method) echo '<span class="detail-item"><strong>調理法:</strong> ' . esc_html($cooking_method) . '</span>';
                                                if ($dashi_type) echo '<span class="detail-item"><strong>だし:</strong> ' . esc_html($dashi_type) . '</span>';
                                                if ($regional_style) echo '<span class="detail-item"><strong>郷土:</strong> ' . esc_html($regional_style) . '</span>';
                                                break;
                                                
                                            case 'western':
                                                $course_type = get_field('course_type');
                                                $origin_country = get_field('origin_country');
                                                $wine_pairing = get_field('wine_pairing');
                                                
                                                if ($course_type) echo '<span class="detail-item"><strong>コース:</strong> ' . esc_html($course_type) . '</span>';
                                                if ($origin_country) echo '<span class="detail-item"><strong>発祥:</strong> ' . esc_html($origin_country) . '</span>';
                                                if ($wine_pairing) echo '<span class="detail-item"><strong>ワイン:</strong> ' . esc_html($wine_pairing) . '</span>';
                                                break;
                                                
                                            case 'chinese':
                                                $cooking_style = get_field('cooking_style');
                                                $spice_level = get_field('spice_level');
                                                $region_china = get_field('region_china');
                                                
                                                if ($cooking_style) echo '<span class="detail-item"><strong>調理法:</strong> ' . esc_html($cooking_style) . '</span>';
                                                if ($spice_level) echo '<span class="detail-item"><strong>辛さ:</strong> ' . esc_html($spice_level) . '</span>';
                                                if ($region_china) echo '<span class="detail-item"><strong>地方:</strong> ' . esc_html($region_china) . '</span>';
                                                break;
                                                
                                            case 'italian':
                                                $pasta_type = get_field('pasta_type');
                                                $cheese_type = get_field('cheese_type');
                                                $region_italy = get_field('region_italy');
                                                
                                                if ($pasta_type) echo '<span class="detail-item"><strong>パスタ:</strong> ' . esc_html($pasta_type) . '</span>';
                                                if ($cheese_type) echo '<span class="detail-item"><strong>チーズ:</strong> ' . esc_html($cheese_type) . '</span>';
                                                if ($region_italy) echo '<span class="detail-item"><strong>地方:</strong> ' . esc_html($region_italy) . '</span>';
                                                break;
                                                
                                            case 'korean':
                                                $fermentation = get_field('fermentation');
                                                $gochujang_level = get_field('gochujang_level');
                                                $meal_type = get_field('meal_type');
                                                
                                                if ($fermentation) echo '<span class="detail-item"><strong>発酵:</strong> ' . ($fermentation ? 'あり' : 'なし') . '</span>';
                                                if ($gochujang_level) echo '<span class="detail-item"><strong>コチュジャン:</strong> ' . esc_html($gochujang_level) . '</span>';
                                                if ($meal_type) echo '<span class="detail-item"><strong>食事タイプ:</strong> ' . esc_html($meal_type) . '</span>';
                                                break;
                                        }
                                        
                                        // 共通フィールド
                                        $prep_time = get_field('prep_time');
                                        $difficulty = get_field('difficulty');
                                        $servings = get_field('servings');
                                        
                                        if ($prep_time) echo '<span class="detail-item"><strong>調理時間:</strong> ' . esc_html($prep_time) . '分</span>';
                                        if ($difficulty) echo '<span class="detail-item"><strong>難易度:</strong> ' . esc_html($difficulty) . '</span>';
                                        if ($servings) echo '<span class="detail-item"><strong>人数:</strong> ' . esc_html($servings) . '人分</span>';
                                        
                                        echo '</div>';
                                        ?>

                                        <a href="<?php the_permalink(); ?>" class="read-more">
                                            レシピを見る →
                                        </a>
                                    </div>
                                </article>
                            <?php endwhile; ?>
                            <?php wp_reset_postdata(); ?>
                        <?php else : ?>
                            <div class="no-recipes">
                                <p>まだ<?php echo esc_html($term->name); ?>のレシピがありません。</p>
                            </div>
                        <?php endif; ?>
                    </section>
                <?php endforeach; ?>
            </main>
        <?php else : ?>
            <div class="no-content">
                <h2>レシピがまだありません</h2>
                <p>最初のレシピを投稿してみましょう!</p>
            </div>
        <?php endif; ?>

        <!-- トップに戻るリンク -->
        <div class="back-to-top">
            <a href="#page-top">↑ ページトップへ</a>
        </div>
    </div>
    <?php wp_footer(); ?>
</body>
</html>

<?php
// ===========================================
// 3. single-food.php - 個別レシピページ
// ===========================================
?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
    <meta charset="<?php bloginfo('charset'); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <?php wp_head(); ?>
</head>
<body>
    <div class="container">
        <nav class="breadcrumb">
            <a href="<?php echo home_url(); ?>">ホーム</a> &gt; 
            <a href="<?php echo get_post_type_archive_link('food'); ?>">レシピ一覧</a> &gt; 
            <span><?php the_title(); ?></span>
        </nav>
        
        <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
            <article class="recipe-detail">
                <header class="recipe-header">
                    <h1><?php the_title(); ?></h1>
                    
                    <div class="recipe-meta">
                        <div class="meta-item">
                            <strong>投稿日:</strong> <?php echo get_the_date('Y年m月d日'); ?>
                        </div>
                        <div class="meta-item">
                            <strong>投稿者:</strong> <?php the_author(); ?>
                        </div>
                        <div class="meta-item">
                            <strong>ジャンル:</strong>
                            <?php 
                            $terms = get_the_terms(get_the_ID(), 'cuisine_type');
                            if ($terms && !is_wp_error($terms)) {
                                $term_links = array();
                                foreach ($terms as $term) {
                                    $term_links[] = '<a href="' . get_term_link($term) . '">' . esc_html($term->name) . '</a>';
                                }
                                echo implode(', ', $term_links);
                            }
                            ?>
                        </div>
                    </div>
                </header>
                
                <?php if (has_post_thumbnail()) : ?>
                    <div class="recipe-image">
                        <?php the_post_thumbnail('full'); ?>
                    </div>
                <?php endif; ?>
                
                <div class="recipe-summary">
                    <?php the_content(); ?>
                </div>
                
                <?php
                // 現在の投稿のジャンルを取得
                $current_terms = get_the_terms(get_the_ID(), 'cuisine_type');
                if ($current_terms && !is_wp_error($current_terms)) {
                    foreach ($current_terms as $current_term) {
                        echo '<section class="cuisine-details">';
                        echo '<h2>' . esc_html($current_term->name) . ' レシピ詳細</h2>';
                        
                        // ジャンル別の詳細フィールド表示
                        switch ($current_term->slug) {
                            case 'japanese':
                                $cooking_method = get_field('cooking_method');
                                $dashi_type = get_field('dashi_type');
                                $regional_style = get_field('regional_style');
                                $ingredients_japanese = get_field('ingredients_japanese');
                                $seasonality = get_field('seasonality');
                                
                                echo '<div class="detail-grid">';
                                if ($cooking_method) echo '<div class="detail-item"><strong>調理法:</strong> ' . esc_html($cooking_method) . '</div>';
                                if ($dashi_type) echo '<div class="detail-item"><strong>だしの種類:</strong> ' . esc_html($dashi_type) . '</div>';
                                if ($regional_style) echo '<div class="detail-item"><strong>郷土料理:</strong> ' . esc_html($regional_style) . '</div>';
                                if ($seasonality) echo '<div class="detail-item"><strong>旬の季節:</strong> ' . esc_html($seasonality) . '</div>';
                                echo '</div>';
                                
                                if ($ingredients_japanese) {
                                    echo '<h3>材料</h3><ul>';
                                    foreach ($ingredients_japanese as $ingredient) {
                                        echo '<li>' . esc_html($ingredient['ingredient_name']) . ' - ' . esc_html($ingredient['amount']) . '</li>';
                                    }
                                    echo '</ul>';
                                }
                                break;
                                
                            case 'western':
                                $course_type = get_field('course_type');
                                $origin_country = get_field('origin_country');
                                $wine_pairing = get_field('wine_pairing');
                                $ingredients_western = get_field('ingredients_western');
                                $cooking_tips = get_field('cooking_tips');
                                
                                echo '<div class="detail-grid">';
                                if ($course_type) echo '<div class="detail-item"><strong>コース:</strong> ' . esc_html($course_type) . '</div>';
                                if ($origin_country) echo '<div class="detail-item"><strong>発祥国:</strong> ' . esc_html($origin_country) . '</div>';
                                if ($wine_pairing) echo '<div class="detail-item"><strong>ワインペアリング:</strong> ' . esc_html($wine_pairing) . '</div>';
                                echo '</div>';
                                
                                if ($ingredients_western) {
                                    echo '<h3>材料</h3><ul>';
                                    foreach ($ingredients_western as $ingredient) {
                                        echo '<li>' . esc_html($ingredient['ingredient_name']) . ' - ' . esc_html($ingredient['quantity']) . '</li>';
                                    }
                                    echo '</ul>';
                                }
                                
                                if ($cooking_tips) echo '<div class="cooking-tips"><h3>調理のコツ</h3><p>' . esc_html($cooking_tips) . '</p></div>';
                                break;
                                
                            case 'chinese':
                                $cooking_style = get_field('cooking_style');
                                $spice_level = get_field('spice_level');
                                $region_china = get_field('region_china');
                                $seasonings_chinese = get_field('seasonings_chinese');
                                
                                echo '<div class="detail-grid">';
                                if ($cooking_style) echo '<div class="detail-item"><strong>調理法:</strong> ' . esc_html($cooking_style) . '</div>';
                                if ($spice_level) echo '<div class="detail-item"><strong>辛さレベル:</strong> ' . esc_html($spice_level) . '</div>';
                                if ($region_china) echo '<div class="detail-item"><strong>中国地方:</strong> ' . esc_html($region_china) . '</div>';
                                echo '</div>';
                                
                                if ($seasonings_chinese) {
                                    echo '<h3>調味料</h3><ul>';
                                    foreach ($seasonings_chinese as $seasoning) {
                                        echo '<li>' . esc_html($seasoning['seasoning_name']) . ' - ' . esc_html($seasoning['usage']) . '</li>';
                                    }
                                    echo '</ul>';
                                }
                                break;
                                
                            case 'italian':
                                $pasta_type = get_field('pasta_type');
                                $cheese_type = get_field('cheese_type');
                                $region_italy = get_field('region_italy');
                                $olive_oil_type = get_field('olive_oil_type');
                                
                                echo '<div class="detail-grid">';
                                if ($pasta_type) echo '<div class="detail-item"><strong>パスタの種類:</strong> ' . esc_html($pasta_type) . '</div>';
                                if ($cheese_type) echo '<div class="detail-item"><strong>チーズ:</strong> ' . esc_html($cheese_type) . '</div>';
                                if ($region_italy) echo '<div class="detail-item"><strong>イタリア地方:</strong> ' . esc_html($region_italy) . '</div>';
                                if ($olive_oil_type) echo '<div class="detail-item"><strong>オリーブオイル:</strong> ' . esc_html($olive_oil_type) . '</div>';
                                echo '</div>';
                                break;
                                
                            case 'korean':
                                $fermentation = get_field('fermentation');
                                $gochujang_level = get_field('gochujang_level');
                                $meal_type = get_field('meal_type');
                                $kimchi_pairing = get_field('kimchi_pairing');
                                
                                echo '<div class="detail-grid">';
                                if ($fermentation !== null) echo '<div class="detail-item"><strong>発酵食品:</strong> ' . ($fermentation ? 'あり' : 'なし') . '</div>';
                                if ($gochujang_level) echo '<div class="detail-item"><strong>コチュジャンレベル:</strong> ' . esc_html($gochujang_level) . '</div>';
                                if ($meal_type) echo '<div class="detail-item"><strong>食事タイプ:</strong> ' . esc_html($meal_type) . '</div>';
                                if ($kimchi_pairing) echo '<div class="detail-item"><strong>キムチとの相性:</strong> ' . esc_html($kimchi_pairing) . '</div>';
                                echo '</div>';
                                break;
                        }
                        
                        echo '</section>';
                    }
                }
                
                // 共通の詳細情報
                $prep_time = get_field('prep_time');
                $difficulty = get_field('difficulty');
                $servings = get_field('servings');
                $cooking_steps = get_field('cooking_steps');
                
                if ($prep_time || $difficulty || $servings) {
                    echo '<section class="common-details">';
                    echo '<h2>基本情報</h2>';
                    echo '<div class="detail-grid">';
                    if ($prep_time) echo '<div class="detail-item"><strong>調理時間:</strong> ' . esc_html($prep_time) . '分</div>';
                    if ($difficulty) echo '<div class="detail-item"><strong>難易度:</strong> ' . esc_html($difficulty) . '</div>';
                    if ($servings) echo '<div class="detail-item"><strong>人数:</strong> ' . esc_html($servings) . '人分</div>';
                    echo '</div>';
                    echo '</section>';
                }
                
                if ($cooking_steps) {
                    echo '<section class="cooking-steps">';
                    echo '<h2>作り方</h2>';
                    echo '<ol>';
                    foreach ($cooking_steps as $index => $step) {
                        echo '<li><div class="step-content">' . esc_html($step['step_description']) . '</div></li>';
                    }
                    echo '</ol>';
                    echo '</section>';
                }
                ?>
            </article>
        <?php endwhile; endif; ?>
        
        <div class="navigation-links">
            <a href="<?php echo get_post_type_archive_link('food'); ?>">← レシピ一覧に戻る</a>
        </div>
    </div>
    <?php wp_footer(); ?>
</body>
</html>

<?php
// ===========================================
// 4. taxonomy-cuisine_type.php - ジャンル別一覧ページ
// ===========================================
?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
    <meta charset="<?php bloginfo('charset'); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title><?php single_term_title(); ?> のレシピ | <?php bloginfo('name'); ?></title>
    <?php wp_head(); ?>
</head>
<body>
    <div class="container">
        <nav class="breadcrumb">
            <a href="<?php echo home_url(); ?>">ホーム</a> &gt; 
            <a href="<?php echo get_post_type_archive_link('food'); ?>">レシピ一覧</a> &gt; 
            <span><?php single_term_title(); ?></span>
        </nav>
        
        <header class="taxonomy-header">
            <h1><?php single_term_title(); ?> のレシピ</h1>
            <?php if (term_description()) : ?>
                <div class="taxonomy-description">
                    <?php echo term_description(); ?>
                </div>
            <?php endif; ?>
            <p class="recipe-count">
                <strong><?php echo $wp_query->found_posts; ?></strong> 件のレシピがあります
            </p>
        </header>
        
        <main class="recipes-list">
            <?php if (have_posts()) : ?>
                <div class="recipes-grid">
                    <?php while (have_posts()) : the_post(); ?>
                        <article class="recipe-card">
                            <?php if (has_post_thumbnail()) : ?>
                                <div class="card-image">
                                    <a href="<?php the_permalink(); ?>">
                                        <?php the_post_thumbnail('medium'); ?>
                                    </a>
                                </div>
                            <?php endif; ?>
                            
                            <div class="card-content">
                                <h2 class="card-title">
                                    <a href="<?php the_permalink(); ?>">
                                        <?php the_title(); ?>
                                    </a>
                                </h2>
                                
                                <div class="card-meta">
                                    <span class="date"><?php echo get_the_date('Y.m.d'); ?></span>
                                    <span class="author">by <?php the_author(); ?></span>
                                </div>
                                
                                <div class="card-excerpt">
                                    <?php 
                                    if (has_excerpt()) {
                                        the_excerpt();
                                    } else {
                                        echo wp_trim_words(get_the_content(), 20, '...');
                                    }
                                    ?>
                                </div>
                                
                                <?php
                                // 現在のタクソノミーターム情報を取得
                                $current_term = get_queried_object();
                                
                                // ジャンル別の簡易情報表示
                                echo '<div class="card-details">';
                                switch ($current_term->slug) {
                                    case 'japanese':
                                        $cooking_method = get_field('cooking_method');
                                        $dashi_type = get_field('dashi_type');
                                        if ($cooking_method) echo '<span class="detail-tag">' . esc_html($cooking_method) . '</span>';
                                        if ($dashi_type) echo '<span class="detail-tag">' . esc_html($dashi_type) . '</span>';
                                        break;
                                        
                                    case 'western':
                                        $course_type = get_field('course_type');
                                        $origin_country = get_field('origin_country');
                                        if ($course_type) echo '<span class="detail-tag">' . esc_html($course_type) . '</span>';
                                        if ($origin_country) echo '<span class="detail-tag">' . esc_html($origin_country) . '</span>';
                                        break;
                                        
                                    case 'chinese':
                                        $cooking_style = get_field('cooking_style');
                                        $spice_level = get_field('spice_level');
                                        if ($cooking_style) echo '<span class="detail-tag">' . esc_html($cooking_style) . '</span>';
                                        if ($spice_level) echo '<span class="detail-tag">辛さ: ' . esc_html($spice_level) . '</span>';
                                        break;
                                        
                                    case 'italian':
                                        $pasta_type = get_field('pasta_type');
                                        $region_italy = get_field('region_italy');
                                        if ($pasta_type) echo '<span class="detail-tag">' . esc_html($pasta_type) . '</span>';
                                        if ($region_italy) echo '<span class="detail-tag">' . esc_html($region_italy) . '</span>';
                                        break;
                                        
                                    case 'korean':
                                        $meal_type = get_field('meal_type');
                                        $gochujang_level = get_field('gochujang_level');
                                        if ($meal_type) echo '<span class="detail-tag">' . esc_html($meal_type) . '</span>';
                                        if ($gochujang_level) echo '<span class="detail-tag">' . esc_html($gochujang_level) . '</span>';
                                        break;
                                }
                                
                                // 共通フィールド
                                $prep_time = get_field('prep_time');
                                $difficulty = get_field('difficulty');
                                if ($prep_time) echo '<span class="detail-tag">' . esc_html($prep_time) . '分</span>';
                                if ($difficulty) echo '<span class="detail-tag">' . esc_html($difficulty) . '</span>';
                                
                                echo '</div>';
                                ?>
                                
                                <a href="<?php the_permalink(); ?>" class="read-more">
                                    レシピを見る →
                                </a>
                            </div>
                        </article>
                    <?php endwhile; ?>
                </div>
            <?php else : ?>
                <div class="no-recipes">
                    <h2>レシピがまだありません</h2>
                    <p>この<?php single_term_title(); ?>ジャンルにはまだレシピが投稿されていません。</p>
                </div>
            <?php endif; ?>
        </main>
        
        <!-- ページネーション -->
        <nav class="pagination">
            <?php
            echo paginate_links(array(
                'prev_text' => '← 前のページ',
                'next_text' => '次のページ →',
            ));
            ?>
        </nav>
        
        <div class="navigation-links">
            <a href="<?php echo get_post_type_archive_link('food'); ?>">← レシピ一覧に戻る</a>
        </div>
    </div>
    <?php wp_footer(); ?>
</body>
</html>

<?php
// ===========================================
// ACF Pro プラグイン設定内容
// ===========================================
/*

【フィールドグループ設定】

■ 共通フィールドグループ
フィールドグループ名: レシピ基本情報
位置ルール: 投稿タイプ が次と等しい food

フィールド:
1. 調理時間 (prep_time) - 数値
2. 難易度 (difficulty) - セレクト(簡単/普通/難しい/上級者向け)
3. 人数 (servings) - 数値
4. 作り方 (cooking_steps) - リピーター
   - 手順説明 (step_description) - テキストエリア

■ 和食専用フィールドグループ
フィールドグループ名: 和食詳細情報
位置ルール: 
- 投稿タイプ が次と等しい food
- かつ タクソノミー が次と等しい 和食 (cuisine_type)

フィールド:
1. 調理法 (cooking_method) - セレクト(煮る/焼く/蒸す/炒める/揚げる/生/その他)
2. だしの種類 (dashi_type) - セレクト(昆布/かつお/煮干し/あご/複合/なし)
3. 郷土料理 (regional_style) - テキスト
4. 旬の季節 (seasonality) - セレクト(春/夏/秋/冬/通年)
5. 材料 (ingredients_japanese) - リピーター
   - 材料名 (ingredient_name) - テキスト
   - 分量 (amount) - テキスト

■ 洋食専用フィールドグループ
フィールドグループ名: 洋食詳細情報
位置ルール:
- 投稿タイプ が次と等しい food
- かつ タクソノミー が次と等しい 洋食 (cuisine_type)

フィールド:
1. コースタイプ (course_type) - セレクト(前菜/スープ/メイン/デザート/フルコース)
2. 発祥国 (origin_country) - テキスト
3. ワインペアリング (wine_pairing) - テキスト
4. 調理のコツ (cooking_tips) - テキストエリア
5. 材料 (ingredients_western) - リピーター
   - 材料名 (ingredient_name) - テキスト
   - 分量 (quantity) - テキスト

■ 中華専用フィールドグループ
フィールドグループ名: 中華詳細情報
位置ルール:
- 投稿タイプ が次と等しい food
- かつ タクソノミー が次と等しい 中華 (cuisine_type)

フィールド:
1. 調理法 (cooking_style) - セレクト(炒/煮/蒸/揚/焼/涼拌)
2. 辛さレベル (spice_level) - セレクト(なし/微辛/中辛/激辛)
3. 中国地方 (region_china) - セレクト(北京/上海/四川/広東/湖南/その他)
4. 調味料 (seasonings_chinese) - リピーター
   - 調味料名 (seasoning_name) - テキスト
   - 使用法 (usage) - テキスト

■ イタリアン専用フィールドグループ
フィールドグループ名: イタリアン詳細情報
位置ルール:
- 投稿タイプ が次と等しい food
- かつ タクソノミー が次と等しい イタリアン (cuisine_type)

フィールド:
1. パスタの種類 (pasta_type) - セレクト(ロングパスタ/ショートパスタ/リゾット/ニョッキ/パスタなし)
2. チーズの種類 (cheese_type) - テキスト
3. イタリア地方 (region_italy) - セレクト(北部/中部/南部/シチリア/サルデーニャ)
4. オリーブオイル (olive_oil_type) - セレクト(エクストラバージン/ピュア/使用なし)

■ 韓国料理専用フィールドグループ
フィールドグループ名: 韓国料理詳細情報
位置ルール:
- 投稿タイプ が次と等しい food
- かつ タクソノミー が次と等しい 韓国料理 (cuisine_type)

フィールド:
1. 発酵食品 (fermentation) - 真偽値
2. コチュジャンレベル (gochujang_level) - セレクト(なし/少し/普通/たっぷり)
3. 食事タイプ (meal_type) - セレクト(ご飯/麺/鍋/おかず/おつまみ/デザート)
4. キムチとの相性 (kimchi_pairing) - セレクト(とても良い/良い/普通/合わない)

【設定手順】
1. ACF Pro管理画面で各フィールドグループを作成
2. 位置ルールで「投稿タイプ = food」かつ「タクソノミー = 該当ジャンル」を設定
3. 各ジャンルに応じた専用フィールドを追加
4. 共通フィールドグループは全てのfood投稿に適用

【タクソノミーターム作成】
WordPress管理画面 > レシピ > 料理ジャンル で以下を作成:
- 和食 (slug: japanese)
- 洋食 (slug: western)  
- 中華 (slug: chinese)
- イタリアン (slug: italian)
- 韓国料理 (slug: korean)

*/
?>

説明が欲しい方へ

# WordPress Food テンプレート 詳細解説

## 全体概要

このテンプレートはレシピサイト用のWordPressカスタム投稿タイプシステムです各料理ジャンルに特化したカスタムフィールドを持ちジャンル別に最適化された情報表示を行います

## 1. functions.php の詳細解説

### カスタム投稿タイプ「food」登録
```php
function register_food_post_type() {
    register_post_type('food', array(
  • register_food_post_typeという関数を定義
  • WordPressに新しい投稿タイプを登録する
        'label' => 'レシピ',
  • 管理画面での表示名を「レシピ」に設定
        'public' => true,
  • 一般公開する投稿タイプとして設定(フロントエンドで表示可能)
        'has_archive' => true,
  • アーカイブページ(一覧ページ)を作成可能にする
        'supports' => array('title', 'editor', 'thumbnail', 'author'),
  • 投稿で使用可能な機能を指定
  • title: タイトル、editor: 本文エディタ、thumbnail: アイキャッチ画像、author: 投稿者
        'menu_icon' => 'dashicons-carrot',
  • 管理画面メニューのアイコンを人参マークに設定
        'rewrite' => array('slug' => 'recipe'),
  • URLのスラッグを「recipe」に設定(例: /recipe/post-name/)

カスタムタクソノミー「cuisine_type」登録

function register_cuisine_taxonomy() {
    register_taxonomy('cuisine_type', 'food', array(
  • cuisine_typeというタクソノミーをfood投稿タイプに関連付けて登録
        'hierarchical' => true,
  • 階層構造を持つタクソノミーとして設定(カテゴリーのような親子関係が可能)
        'show_admin_column' => true,
  • 管理画面の投稿一覧にタクソノミーの列を表示

デフォルトターム作成

function create_default_cuisine_terms() {
    $terms = array(
        'japanese' => '和食',
        'western' => '洋食',
        'chinese' => '中華',
        'italian' => 'イタリアン',
        'korean' => '韓国料理'
    );
  • 作成するタクソノミータームを配列で定義
  • キー: スラッグ、値: 表示名
        if (!term_exists($name, 'cuisine_type')) {
            wp_insert_term($name, 'cuisine_type', array('slug' => $slug));
        }
  • term_exists()でタームが既に存在するかチェック
  • 存在しない場合のみwp_insert_term()で新規作成

2. archive-food.php の詳細解説

タクソノミータームの取得

        $terms = get_terms(array(
            'taxonomy' => 'cuisine_type',
            'hide_empty' => true,
            'orderby' => 'slug',
            'order' => 'ASC'
        ));
  • get_terms()で料理ジャンルの一覧を取得
  • hide_empty => true: 投稿が1件もないタームは除外
  • orderby => 'slug': スラッグ順で並び替え
  • order => 'ASC': 昇順で並び替え

ページ内ナビゲーション生成

            <?php foreach ($terms as $term) : ?>
                <li>
                    <a href="#<?php echo esc_attr($term->slug); ?>">
  • 各タームのスラッグをid属性として使用してページ内リンクを作成
  • esc_attr()でHTMLエスケープしてセキュリティ対策
                        <span>(<?php echo $term->count; ?>)</span>
  • $term->countでそのタームに属する投稿数を表示

各ジャンルの最新投稿取得

                        $recipe_query = new WP_Query(array(
                            'post_type' => 'food',
                            'post_status' => 'publish',
                            'posts_per_page' => 1,
                            'orderby' => 'date',
                            'order' => 'DESC',
  • WP_Queryでカスタムクエリを作成
  • post_type => 'food': foodタイプの投稿のみ
  • post_status => 'publish': 公開済みの投稿のみ
  • posts_per_page => 1: 1件のみ取得
  • orderby => 'date', order => 'DESC': 投稿日時の新しい順
                            'tax_query' => array(
                                array(
                                    'taxonomy' => 'cuisine_type',
                                    'field' => 'term_id',
                                    'terms' => $term->term_id,
                                ),
                            ),
  • tax_queryでタクソノミーによる絞り込み
  • 現在のタームに属する投稿のみを取得

ジャンル別カスタムフィールド表示

                        switch ($term->slug) {
                            case 'japanese':
                                $cooking_method = get_field('cooking_method');
                                $dashi_type = get_field('dashi_type');
                                $regional_style = get_field('regional_style');
  • switch文で現在のタームのスラッグに応じて処理を分岐
  • get_field()でACFのカスタムフィールド値を取得
                                if ($cooking_method) echo '<span class="detail-item"><strong>調理法:</strong> ' . esc_html($cooking_method) . '</span>';
  • フィールドに値が入っている場合のみ表示
  • esc_html()でHTMLエスケープしてセキュリティ対策

投稿データのリセット

                        <?php wp_reset_postdata(); ?>
  • カスタムクエリ後に必須の処理
  • グローバルな投稿データを元の状態に戻す

3. single-food.php の詳細解説

パンくずナビの作成

        <nav class="breadcrumb">
            <a href="<?php echo home_url(); ?>">ホーム</a> &gt; 
            <a href="<?php echo get_post_type_archive_link('food'); ?>">レシピ一覧</a> &gt; 
            <span><?php the_title(); ?></span>
        </nav>
  • get_post_type_archive_link('food')でfood投稿タイプのアーカイブページURLを取得
  • 現在のページ位置を視覚的に分かりやすく表示

投稿に紐づくタクソノミーターム取得

            $terms = get_the_terms(get_the_ID(), 'cuisine_type');
            if ($terms && !is_wp_error($terms)) {
  • get_the_terms()で現在の投稿に関連付けられたタームを取得
  • !is_wp_error()でエラーがないかチェック
                foreach ($terms as $term) {
                    $term_links[] = '<a href="' . get_term_link($term) . '">' . esc_html($term->name) . '</a>';
                }
                echo implode(', ', $term_links);
  • 各タームをリンク付きで表示
  • get_term_link()でタームのアーカイブページURLを取得
  • implode()で配列を文字列に結合(カンマ区切り)

ジャンル別詳細情報の表示

        if ($current_terms && !is_wp_error($current_terms)) {
            foreach ($current_terms as $current_term) {
                switch ($current_term->slug) {
  • 投稿に関連付けられた各タームに対してループ処理
  • タームのスラッグに応じて異なる情報を表示

リピーターフィールドの処理

                if ($ingredients_japanese) {
                    echo '<h3>材料</h3><ul>';
                    foreach ($ingredients_japanese as $ingredient) {
                        echo '<li>' . esc_html($ingredient['ingredient_name']) . ' - ' . esc_html($ingredient['amount']) . '</li>';
                    }
                    echo '</ul>';
                }
  • ACFのリピーターフィールドは配列として返される
  • foreachで各行をループ処理
  • $ingredient['field_name']でサブフィールドの値を取得

共通フィールドの表示

        $prep_time = get_field('prep_time');
        $difficulty = get_field('difficulty');
        $servings = get_field('servings');
        $cooking_steps = get_field('cooking_steps');
  • 全ジャンル共通のフィールドを取得
  • ジャンル固有の情報とは別セクションで表示

4. taxonomy-cuisine_type.php の詳細解説

現在のタクソノミー情報取得

        $current_term = get_queried_object();
  • get_queried_object()で現在表示中のタクソノミーターム情報を取得
  • アーカイブページで現在のタームを特定するために使用

ページネーション

            echo paginate_links(array(
                'prev_text' => '← 前のページ',
                'next_text' => '次のページ →',
            ));
  • paginate_links()でページネーション(ページ送り)を生成
  • 前後のページへのリンクテキストをカスタマイズ

投稿数の表示

            <p class="recipe-count">
                <strong><?php echo $wp_query->found_posts; ?></strong> 件のレシピがあります
            </p>
  • $wp_query->found_postsで現在のクエリに該当する投稿の総数を取得
  • ページング考慮済みの総件数

ACF設定のポイント

位置ルールの条件分岐

位置ルール: 
- 投稿タイプ が次と等しい food
- かつ タクソノミー が次と等しい 和食 (cuisine_type)
  • ACFの位置ルールで「かつ」条件を使用
  • 特定のタクソノミーが選択された時のみフィールドを表示

フィールドタイプの選択指針

  • テキスト: 短い文字列(材料名、地域名など)
  • テキストエリア: 長い文章(説明、コツなど)
  • セレクト: 決まった選択肢から選ぶ(難易度、調理法など)
  • 数値: 数字のみ(時間、人数など)
  • 真偽値: はい/いいえの選択(発酵食品かどうかなど)
  • リピーター: 可変長のリスト(材料、手順など)

セキュリティ対策

  • esc_html(): HTMLタグを無効化
  • esc_attr(): HTML属性値を安全に出力
  • esc_url(): URLを安全に出力

パフォーマンス考慮

  • wp_reset_postdata(): カスタムクエリ後の必須処理
  • hide_empty => true: 空のタームを除外してクエリ効率化
  • 条件分岐で不要な処理をスキップ

拡張可能な部分

  1. 追加ジャンル: 新しい料理ジャンルとそれ専用のフィールド
  2. 検索機能: カスタムフィールドでの絞り込み検索
  3. お気に入り機能: ユーザーごとのレシピ保存
  4. 評価システム: 星評価やレビュー機能
  5. 栄養情報: カロリー計算や栄養素表示
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?