WordPressでトップページスライダーを「記事投稿」と連動して管理する方法【ACF+カスタム投稿タイプ+JS対応】

WordPressサイトのトップページにスライダーを設置して、注目記事を効果的に見せたい──。
この記事では、すでに登録されている投稿タイプ「article」の記事を活用して、管理画面からスライダーをコントロールできる方法を紹介します。
ACFでの紐付けから、表示順の管理、スライダーJSの実装まで網羅します。


■ カスタム投稿タイプ「slider」を追加

まずは、functions.php に以下のコードを追加して、スライダー用のカスタム投稿タイプ slider を作成します。

function create_post_type_slider() {
    $labels = array(
        'name' => _x('スライダー', 'post type general name'),
        'singular_name' => _x('スライダー', 'post type singular name'),
        'add_new' => _x('新規追加', 'slider'),
        'add_new_item' => __('新しいスライドを追加'),
        'edit_item' => __('スライドを編集'),
        'view_item' => __('スライドを見る'),
        'search_items' => __('スライドを検索'),
        'not_found' => __('スライドが見つかりません'),
        'menu_name' => 'スライダー',
    );

    $args = array(
        'labels' => $labels,
        'public' => false,
        'show_ui' => true,
        'menu_icon' => 'dashicons-images-alt2',
        'supports' => array('title', 'thumbnail', 'editor'),
    );

    register_post_type('slider', $args);
}
add_action('init', 'create_post_type_slider');

■ ACFで「表示する記事」を紐付け

管理画面からスライドに表示する記事を選べるよう、Advanced Custom Fields(ACF)プラグインでフィールドを作成します。

  • フィールド名:slider_article
  • フィールドタイプ:投稿オブジェクト
  • 対象投稿タイプ:article(※事前に追加済み)

これにより、スライダーと記事を1対1で紐付け可能になります。


■ スライドの並び順を変更するには?

投稿タイプ slider の表示順は、WordPress標準機能だけでは変更が難しいため、以下のプラグインを使うと便利です。

Intuitive Custom Post Order
→ 投稿一覧画面でドラッグ&ドロップによる並び替えが可能になります。

設定画面で slider を並び替え対象に追加することをお忘れなく。


■ スライダー画像サイズを登録(任意)

以下を functions.php に追加して、スライド表示用の画像サイズを登録します。

add_image_size('article-slider', 600, 400, true);

■ スライダーのHTML出力コード(テンプレート内)

例えば front-page.php に以下のようなコードを記述します。

<?php
$args = array(
    'post_type' => 'slider',
    'posts_per_page' => 6,
    'orderby' => 'menu_order',
    'order' => 'ASC'
);
$slider_query = new WP_Query($args);
?>

<?php if ($slider_query->have_posts()): ?>
<div class="slider">
    <div class="slides">
        <?php while ($slider_query->have_posts()): $slider_query->the_post(); ?>
            <?php
            $linked_article = get_field('slider_article');
            if ($linked_article):
                $title = get_the_title($linked_article->ID);
                $link = get_permalink($linked_article->ID);
                $thumb = get_the_post_thumbnail($linked_article->ID, 'article-slider');
            ?>
            <div class="slide">
                <a href="<?php echo esc_url($link); ?>">
                    <?php echo $thumb; ?>
                    <div class="slide-title"><?php echo esc_html($title); ?></div>
                </a>
            </div>
            <?php endif; ?>
        <?php endwhile; wp_reset_postdata(); ?>
    </div>
    <div class="dots">
        <?php for ($i = 0; $i < $slider_query->post_count; $i++): ?>
            <span class="dot"></span>
        <?php endfor; ?>
    </div>
</div>
<?php endif; ?>

■ スライダー用JavaScript(スワイプ・自動再生付き)

以下のJavaScriptは、スライドの切り替え・自動再生・スワイプ操作に対応しています。

let slideIndex = 0;
let startX = 0;
let isDragging = false;
let slidesContainer = document.querySelector(".slides");
let slides = document.querySelectorAll(".slide");
let dots = document.querySelectorAll(".dot");
let slideWidth = slides[0].clientWidth;

showSlides(slideIndex);

function showSlides(n) {
    if (n >= slides.length) { slideIndex = 0; }
    if (n < 0) { slideIndex = slides.length - 1; }
    let offset = -slideIndex * slideWidth;
    slidesContainer.style.transform = `translateX(${offset}px)`;
    dots.forEach(dot => dot.classList.remove("active"));
    dots[slideIndex].classList.add("active");
}

function currentSlide(n) {
    showSlides(slideIndex = n);
}

slidesContainer.addEventListener("touchstart", (e) => {
    startX = e.touches[0].clientX;
    isDragging = true;
});

slidesContainer.addEventListener("touchmove", (e) => {
    if (!isDragging) return;
    let diff = startX - e.touches[0].clientX;
    if (diff > 50) {
        slideIndex++;
        isDragging = false;
    } else if (diff < -50) {
        slideIndex--;
        isDragging = false;
    }
    showSlides(slideIndex);
});

slidesContainer.addEventListener("touchend", () => {
    isDragging = false;
});

setInterval(() => {
    slideIndex++;
    showSlides(slideIndex);
}, 5000);

window.addEventListener("resize", () => {
    slideWidth = slides[0].clientWidth;
    showSlides(slideIndex);
});

テンプレートで読み込む場合:

<script src="<?php echo get_template_directory_uri(); ?>/js/slider.js" defer></script>

■ まとめ

この構成により、以下が実現できます:

  • すでに存在する投稿(article)を再利用してスライダーに表示
  • ACFでリンク先や画像を自動取得
  • 表示順はドラッグで直感的に操作
  • 自動再生・スワイプ対応のスライダー動作

管理のしやすさと表示の自由度を両立できる構成です。
クライアント案件や運用サイトにもおすすめです。

コメント

タイトルとURLをコピーしました