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
/* 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">
<title><?php wp_title('|', true, 'right'); ?></title>
<?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>© <?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");
カスタムフィールド
-
基本
シンプルなカスタム投稿タイプの登録方法 -
タクソノミー
階層型カスタムタクソノミー(カテゴリー型)
非階層型カスタムタクソノミー(タグ型) -
カスタムフィールド
シンプルなメタボックスの追加方法
データの保存方法 -
実務例
事例紹介(Case Study)
イベント情報(Event)- 日時、場所などのカスタムフィールド付き
よくある質問(FAQ)
製品カタログ(Product)- 価格、製品コードなどのカスタムフィールド付き -
応用
カスタム投稿タイプの投稿一覧を表示するショートコード
<?php
/**
* WordPress実務で使えるカスタム投稿タイプサンプル集
* 機能別にサンプルを分類しています。必要な部分だけを抽出して使用できます。
*/
// ------------------------------------------------------------
// 【基本】シンプルなカスタム投稿タイプの登録
// ------------------------------------------------------------
function register_simple_custom_post_type() {
$labels = array(
'name' => 'カスタム投稿',
'singular_name' => 'カスタム投稿',
'add_new' => '新規追加',
'add_new_item' => '新規投稿を追加',
'edit_item' => '投稿を編集',
'view_item' => '投稿を表示',
'search_items' => '投稿を検索',
'not_found' => '投稿が見つかりませんでした',
'menu_name' => 'カスタム投稿'
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => array( 'slug' => 'custom-post' ),
'capability_type' => 'post',
'has_archive' => true,
'menu_position' => 5,
'menu_icon' => 'dashicons-admin-post',
'supports' => array( 'title', 'editor', 'thumbnail' )
);
register_post_type( 'custom_post', $args );
}
add_action( 'init', 'register_simple_custom_post_type' );
// ------------------------------------------------------------
// 【タクソノミー】カスタムタクソノミーの追加
// ------------------------------------------------------------
// 階層型カスタムタクソノミーの追加(カテゴリー型)
function register_hierarchical_taxonomy() {
$labels = array(
'name' => 'カスタムカテゴリー',
'singular_name' => 'カスタムカテゴリー',
'search_items' => 'カテゴリーを検索',
'all_items' => 'すべてのカテゴリー',
'parent_item' => '親カテゴリー',
'parent_item_colon' => '親カテゴリー:',
'edit_item' => 'カテゴリーを編集',
'update_item' => 'カテゴリーを更新',
'add_new_item' => '新しいカテゴリーを追加',
'new_item_name' => '新しいカテゴリー名',
'menu_name' => 'カスタムカテゴリー'
);
register_taxonomy( 'custom_category', array( 'custom_post' ), array(
'hierarchical' => true,
'labels' => $labels,
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
'rewrite' => array( 'slug' => 'custom-category' )
) );
}
add_action( 'init', 'register_hierarchical_taxonomy' );
// 非階層型カスタムタクソノミーの追加(タグ型)
function register_non_hierarchical_taxonomy() {
$labels = array(
'name' => 'カスタムタグ',
'singular_name' => 'カスタムタグ',
'search_items' => 'タグを検索',
'all_items' => 'すべてのタグ',
'edit_item' => 'タグを編集',
'update_item' => 'タグを更新',
'add_new_item' => '新しいタグを追加',
'new_item_name' => '新しいタグ名',
'menu_name' => 'カスタムタグ'
);
register_taxonomy( 'custom_tag', array( 'custom_post' ), array(
'hierarchical' => false,
'labels' => $labels,
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
'rewrite' => array( 'slug' => 'custom-tag' )
) );
}
add_action( 'init', 'register_non_hierarchical_taxonomy' );
// ------------------------------------------------------------
// 【カスタムフィールド】メタボックスの追加
// ------------------------------------------------------------
// シンプルなメタボックスの追加
function add_simple_meta_box() {
add_meta_box(
'simple_meta_box', // メタボックスID
'カスタムフィールド', // タイトル
'simple_meta_box_callback', // コールバック関数
'custom_post', // 投稿タイプ
'normal', // コンテキスト(normal, side, advanced)
'high' // 優先度(high, default, low)
);
}
add_action( 'add_meta_boxes', 'add_simple_meta_box' );
// メタボックスのコールバック関数
function simple_meta_box_callback( $post ) {
// nonceフィールドを追加
wp_nonce_field( 'simple_meta_box_nonce', 'simple_meta_box_nonce' );
// 保存されている値を取得
$value = get_post_meta( $post->ID, '_custom_field_value', true );
// 入力フィールドを表示
echo '<p>';
echo '<label for="custom_field">カスタムフィールド:</label> ';
echo '<input type="text" id="custom_field" name="custom_field" value="' . esc_attr( $value ) . '" size="50" />';
echo '</p>';
}
// メタボックスのデータを保存
function save_simple_meta_box_data( $post_id ) {
// nonceの確認
if ( ! isset( $_POST['simple_meta_box_nonce'] ) || ! wp_verify_nonce( $_POST['simple_meta_box_nonce'], 'simple_meta_box_nonce' ) ) {
return;
}
// 自動保存の場合は処理しない
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
// 権限の確認
if ( isset( $_POST['post_type'] ) && 'custom_post' == $_POST['post_type'] ) {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
}
// データの保存
if ( isset( $_POST['custom_field'] ) ) {
update_post_meta( $post_id, '_custom_field_value', sanitize_text_field( $_POST['custom_field'] ) );
}
}
add_action( 'save_post', 'save_simple_meta_box_data' );
// ------------------------------------------------------------
// 【実務例】事例紹介(Case Study)
// ------------------------------------------------------------
function register_case_study_post_type() {
$labels = array(
'name' => '事例紹介',
'singular_name' => '事例',
'add_new' => '新規追加',
'add_new_item' => '新しい事例を追加',
'edit_item' => '事例を編集',
'menu_name' => '事例紹介'
);
$args = array(
'labels' => $labels,
'public' => true,
'has_archive' => true,
'menu_icon' => 'dashicons-portfolio',
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt' )
);
register_post_type( 'case_study', $args );
// 業種タクソノミーを追加
register_taxonomy( 'industry', array( 'case_study' ), array(
'hierarchical' => true,
'labels' => array(
'name' => '業種',
'singular_name' => '業種',
'menu_name' => '業種'
),
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
'rewrite' => array( 'slug' => 'industry' ),
) );
}
add_action( 'init', 'register_case_study_post_type' );
// ------------------------------------------------------------
// 【実務例】イベント情報(Event)
// ------------------------------------------------------------
function register_event_post_type() {
$labels = array(
'name' => 'イベント',
'singular_name' => 'イベント',
'add_new' => '新規追加',
'add_new_item' => '新しいイベントを追加',
'edit_item' => 'イベントを編集',
'menu_name' => 'イベント'
);
$args = array(
'labels' => $labels,
'public' => true,
'has_archive' => true,
'menu_icon' => 'dashicons-calendar-alt',
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt' )
);
register_post_type( 'event', $args );
}
add_action( 'init', 'register_event_post_type' );
// イベント詳細のメタボックス
function event_meta_box() {
add_meta_box(
'event_details',
'イベント詳細',
'event_details_callback',
'event',
'normal',
'high'
);
}
add_action( 'add_meta_boxes', 'event_meta_box' );
// イベント詳細メタボックスのコールバック関数
function event_details_callback( $post ) {
wp_nonce_field( 'event_details_nonce', 'event_details_nonce' );
$event_date = get_post_meta( $post->ID, '_event_date', true );
$event_time = get_post_meta( $post->ID, '_event_time', true );
$event_location = get_post_meta( $post->ID, '_event_location', true );
echo '<p>';
echo '<label for="event_date">開催日:</label> ';
echo '<input type="date" id="event_date" name="event_date" value="' . esc_attr( $event_date ) . '" />';
echo '</p>';
echo '<p>';
echo '<label for="event_time">時間:</label> ';
echo '<input type="text" id="event_time" name="event_time" value="' . esc_attr( $event_time ) . '" placeholder="例: 14:00-16:00" />';
echo '</p>';
echo '<p>';
echo '<label for="event_location">開催場所:</label> ';
echo '<input type="text" id="event_location" name="event_location" value="' . esc_attr( $event_location ) . '" size="50" />';
echo '</p>';
}
// イベント詳細の保存
function save_event_details( $post_id ) {
if ( ! isset( $_POST['event_details_nonce'] ) || ! wp_verify_nonce( $_POST['event_details_nonce'], 'event_details_nonce' ) ) {
return;
}
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
if ( isset( $_POST['post_type'] ) && 'event' == $_POST['post_type'] ) {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
}
if ( isset( $_POST['event_date'] ) ) {
update_post_meta( $post_id, '_event_date', sanitize_text_field( $_POST['event_date'] ) );
}
if ( isset( $_POST['event_time'] ) ) {
update_post_meta( $post_id, '_event_time', sanitize_text_field( $_POST['event_time'] ) );
}
if ( isset( $_POST['event_location'] ) ) {
update_post_meta( $post_id, '_event_location', sanitize_text_field( $_POST['event_location'] ) );
}
}
add_action( 'save_post', 'save_event_details' );
// ------------------------------------------------------------
// 【実務例】よくある質問(FAQ)
// ------------------------------------------------------------
function register_faq_post_type() {
$labels = array(
'name' => 'よくある質問',
'singular_name' => 'FAQ',
'add_new' => '新規追加',
'add_new_item' => '新しい質問を追加',
'edit_item' => '質問を編集',
'menu_name' => 'よくある質問'
);
$args = array(
'labels' => $labels,
'public' => true,
'has_archive' => true,
'menu_icon' => 'dashicons-format-chat',
'supports' => array( 'title', 'editor' )
);
register_post_type( 'faq', $args );
// FAQ用カテゴリーを追加
register_taxonomy( 'faq_category', array( 'faq' ), array(
'hierarchical' => true,
'labels' => array(
'name' => 'FAQカテゴリー',
'singular_name' => 'FAQカテゴリー',
'menu_name' => 'FAQカテゴリー'
),
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
'rewrite' => array( 'slug' => 'faq-category' ),
) );
}
add_action( 'init', 'register_faq_post_type' );
// ------------------------------------------------------------
// 【実務例】製品カタログ(Product)
// ------------------------------------------------------------
function register_product_post_type() {
$labels = array(
'name' => '製品',
'singular_name' => '製品',
'add_new' => '新規追加',
'add_new_item' => '新しい製品を追加',
'edit_item' => '製品を編集',
'menu_name' => '製品カタログ'
);
$args = array(
'labels' => $labels,
'public' => true,
'has_archive' => true,
'menu_icon' => 'dashicons-cart',
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt' )
);
register_post_type( 'product', $args );
// 製品カテゴリーを追加
register_taxonomy( 'product_category', array( 'product' ), array(
'hierarchical' => true,
'labels' => array(
'name' => '製品カテゴリー',
'singular_name' => '製品カテゴリー',
'menu_name' => '製品カテゴリー'
),
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
'rewrite' => array( 'slug' => 'product-category' ),
) );
}
add_action( 'init', 'register_product_post_type' );
// 製品詳細のメタボックス
function product_meta_box() {
add_meta_box(
'product_details',
'製品詳細',
'product_details_callback',
'product',
'normal',
'high'
);
}
add_action( 'add_meta_boxes', 'product_meta_box' );
// 製品詳細メタボックスのコールバック関数
function product_details_callback( $post ) {
wp_nonce_field( 'product_details_nonce', 'product_details_nonce' );
$product_price = get_post_meta( $post->ID, '_product_price', true );
$product_code = get_post_meta( $post->ID, '_product_code', true );
$product_url = get_post_meta( $post->ID, '_product_url', true );
echo '<p>';
echo '<label for="product_price">価格:</label> ';
echo '<input type="text" id="product_price" name="product_price" value="' . esc_attr( $product_price ) . '" />';
echo '</p>';
echo '<p>';
echo '<label for="product_code">製品コード:</label> ';
echo '<input type="text" id="product_code" name="product_code" value="' . esc_attr( $product_code ) . '" />';
echo '</p>';
echo '<p>';
echo '<label for="product_url">購入URL:</label> ';
echo '<input type="url" id="product_url" name="product_url" value="' . esc_url( $product_url ) . '" size="50" />';
echo '</p>';
}
// 製品詳細の保存
function save_product_details( $post_id ) {
if ( ! isset( $_POST['product_details_nonce'] ) || ! wp_verify_nonce( $_POST['product_details_nonce'], 'product_details_nonce' ) ) {
return;
}
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
if ( isset( $_POST['post_type'] ) && 'product' == $_POST['post_type'] ) {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
}
if ( isset( $_POST['product_price'] ) ) {
update_post_meta( $post_id, '_product_price', sanitize_text_field( $_POST['product_price'] ) );
}
if ( isset( $_POST['product_code'] ) ) {
update_post_meta( $post_id, '_product_code', sanitize_text_field( $_POST['product_code'] ) );
}
if ( isset( $_POST['product_url'] ) ) {
update_post_meta( $post_id, '_product_url', esc_url_raw( $_POST['product_url'] ) );
}
}
add_action( 'save_post', 'save_product_details' );
// ------------------------------------------------------------
// 【応用】カスタム投稿タイプの投稿一覧を表示するショートコード
// ------------------------------------------------------------
function custom_post_type_list_shortcode( $atts ) {
$atts = shortcode_atts( array(
'type' => 'post',
'posts_per_page' => 5,
'orderby' => 'date',
'order' => 'DESC',
'category' => '',
), $atts );
$args = array(
'post_type' => $atts['type'],
'posts_per_page' => $atts['posts_per_page'],
'orderby' => $atts['orderby'],
'order' => $atts['order'],
);
// カテゴリーが指定されている場合
if ( !empty( $atts['category'] ) ) {
if ( $atts['type'] == 'post' ) {
$args['category_name'] = $atts['category'];
} else {
// カスタム投稿タイプの場合はタクソノミー名を調整
$taxonomy = $atts['type'] . '_category';
$args['tax_query'] = array(
array(
'taxonomy' => $taxonomy,
'field' => 'slug',
'terms' => $atts['category'],
),
);
}
}
$query = new WP_Query( $args );
$output = '<ul class="custom-post-list">';
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
$output .= '<li>';
$output .= '<a href="' . get_permalink() . '">' . get_the_title() . '</a>';
$output .= '<span class="post-date">' . get_the_date() . '</span>';
$output .= '</li>';
}
} else {
$output .= '<li>投稿がありません。</li>';
}
$output .= '</ul>';
wp_reset_postdata();
return $output;
}
add_shortcode( 'custom_post_list', 'custom_post_type_list_shortcode' );
/**
* 使用例:
* [custom_post_list type="product" posts_per_page="3" category="featured"]
*/
基本バージョン: カテゴリー別・年別イベント一覧
特徴:
固定ページのテンプレートとして設定可能
カテゴリーごとにイベントを表示
年ごとにタブ分け(ページ遷移方式)
各カテゴリーのイベントを開催日順にソート
年タブは自動的に利用可能なすべての年を検出して表示
カテゴリーごとのセクションに分けて表示
使用方法:
テンプレートファイル page-events-by-category-year.php をテーマフォルダに追加
管理画面で固定ページを作成し、テンプレートとして「カテゴリー別・年別イベント一覧」を選択
このテンプレートでは、タブをクリックすると実際にページが遷移して、URLパラメータ(?year=2023 など)で選択された年を管理します。これにより、ブラウザの「戻る」ボタンでも正しく前の年に戻るなどの基本的なナビゲーションが可能です。
<?php
/**
* Template Name: カテゴリー別・年別イベント一覧
*
* カテゴリーごとにイベントを表示し、年ごとにタブ分けするテンプレート
* テーマフォルダに「page-events-by-category-year.php」として保存
*/
get_header(); ?>
<div class="container">
<h1><?php the_title(); ?></h1>
<?php
// 固定ページの本文を表示
if (have_posts()) : while (have_posts()) : the_post();
the_content();
endwhile; endif;
?>
<?php
// イベントカテゴリーの一覧を取得
$event_categories = get_terms([
'taxonomy' => 'event_category',
'hide_empty' => true,
]);
// イベントの投稿年を取得
$years = array();
$year_args = array(
'post_type' => 'event',
'posts_per_page' => -1,
'orderby' => 'date',
'order' => 'DESC',
);
$year_query = new WP_Query($year_args);
if ($year_query->have_posts()) {
while ($year_query->have_posts()) {
$year_query->the_post();
// 開催日をもとに年を取得
$event_date = get_post_meta(get_the_ID(), '_event_date', true);
if ($event_date) {
$year = date('Y', strtotime($event_date));
if (!in_array($year, $years)) {
$years[] = $year;
}
} else {
// 開催日が設定されていない場合は投稿日から年を取得
$post_year = get_the_date('Y');
if (!in_array($post_year, $years)) {
$years[] = $post_year;
}
}
}
}
wp_reset_postdata();
// 年を降順に並べ替え
rsort($years);
// 現在選択されている年(デフォルトは最新の年)
$current_year = isset($_GET['year']) ? intval($_GET['year']) : (empty($years) ? date('Y') : $years[0]);
if (!empty($event_categories) && !is_wp_error($event_categories)) :
?>
<!-- 年別タブ -->
<div class="year-tabs">
<ul>
<?php foreach ($years as $year) : ?>
<li class="<?php echo ($year == $current_year) ? 'active' : ''; ?>">
<a href="<?php echo add_query_arg('year', $year); ?>"><?php echo $year; ?>年</a>
</li>
<?php endforeach; ?>
</ul>
</div>
<!-- 各カテゴリーごとのイベント一覧 -->
<?php foreach ($event_categories as $category) : ?>
<?php
// カテゴリーに属する選択された年のイベントを取得
$args = array(
'post_type' => 'event',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'event_category',
'field' => 'term_id',
'terms' => $category->term_id,
),
),
'meta_query' => array(
array(
'key' => '_event_date',
'value' => array($current_year . '-01-01', $current_year . '-12-31'),
'compare' => 'BETWEEN',
'type' => 'DATE',
),
),
'orderby' => 'meta_value',
'meta_key' => '_event_date',
'order' => 'ASC', // 日付順
);
$category_events = new WP_Query($args);
// このカテゴリーに選択した年のイベントがある場合のみ表示
if ($category_events->have_posts()) :
?>
<section class="category-events">
<h2><?php echo $category->name; ?> (<?php echo $current_year; ?>年)</h2>
<?php if (!empty($category->description)) : ?>
<div class="category-description">
<?php echo $category->description; ?>
</div>
<?php endif; ?>
<div class="event-list">
<?php while ($category_events->have_posts()) : $category_events->the_post();
$event_date = get_post_meta(get_the_ID(), '_event_date', true);
$event_location = get_post_meta(get_the_ID(), '_event_location', true);
?>
<div class="event-item">
<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
<?php if ($event_date) : ?>
<div class="event-date">開催日:<?php echo date_i18n('Y年n月j日', strtotime($event_date)); ?></div>
<?php endif; ?>
<?php if ($event_location) : ?>
<div class="event-location">開催場所:<?php echo esc_html($event_location); ?></div>
<?php endif; ?>
<div class="event-excerpt"><?php the_excerpt(); ?></div>
<a href="<?php the_permalink(); ?>" class="event-more">詳細を見る</a>
</div>
<?php endwhile; ?>
</div>
</section>
<?php
wp_reset_postdata();
endif; // カテゴリーのイベントの有無チェック終了
?>
<?php endforeach; // カテゴリーのループ終了 ?>
<?php else : ?>
<p>イベントカテゴリーがありません。</p>
<?php endif; ?>
<!-- イベントが見つからない場合のメッセージ -->
<?php
$found_events = false;
foreach ($event_categories as $category) {
$check_args = array(
'post_type' => 'event',
'posts_per_page' => 1,
'tax_query' => array(
array(
'taxonomy' => 'event_category',
'field' => 'term_id',
'terms' => $category->term_id,
),
),
'meta_query' => array(
array(
'key' => '_event_date',
'value' => array($current_year . '-01-01', $current_year . '-12-31'),
'compare' => 'BETWEEN',
'type' => 'DATE',
),
),
);
$check_query = new WP_Query($check_args);
if ($check_query->have_posts()) {
$found_events = true;
break;
}
}
if (!$found_events) :
?>
<div class="no-events-message">
<p><?php echo $current_year; ?>年のイベントはありません。</p>
</div>
<?php endif; ?>
</div>
<!-- 年別タブのスタイルとJavaScript -->
<script>
document.addEventListener('DOMContentLoaded', function() {
// タブがクリックされたときの処理
var tabs = document.querySelectorAll('.year-tabs li a');
tabs.forEach(function(tab) {
tab.addEventListener('click', function(e) {
// 必要に応じてカスタム処理を追加
});
});
});
</script>
<?php get_footer(); ?>