エントリーカードにリボン表示を追加する方法

Cocoonカスタマイズ集
この記事は約9分で読めます。
記事内に広告が含まれています。

記事に記載したコードは、スキンに追加されています。

はじめに

「ナビカード」ではカードにリボンを追加することで、視覚的に注目を集めることができます。

そこで、エントリーカードにも注目してほしい記事にリボンを追加して、視覚的に強調します。

この記事では、この方法について説明します。

完成イメージ

実装手順

以下の手順で実装します。

  • ラベル
    Gutenbergエディターでの設定
    Gutenbergエディター

    リボンを追加する記事の「メモ」欄にmy-ribbon1~my-ribbon5と入力します。
    「ナビカード」と同じリボンを表示します。

  • ラベル
    PHPを追加

    以下のコードをfunctions.phpに追加します。

    add_filter('cocoon_part__tmp/entry-card', function ($content) {
      $memo = get_post_meta(get_the_ID(), 'the_page_memo', true);
    
      preg_match('/\bmy-ribbon([1-5])\b/', $memo, $match);
    
      if (!empty($match[0])) {
        // リボンタグを取得
        $no  = $match[1];
        $tag = get_navi_card_ribbon_tag($no);
    
        // リボンタグを追加
        $content = preg_replace('/(<figure[^>]*>)/', $tag . " $1", $content);
      }
    
      return $content;
    });

拡張:投稿一覧にリボン選択を追加する方法

投稿一覧にリボン選択を追加し、編集画面を開かずに投稿の状態を切り替えられるようにします。

完成イメージ

実装手順

以下のコードをfunctions.phpに追加します。

// 管理画面一覧にカラムを追加
add_filter('manage_posts_columns', function ($columns) {
  $columns['ribbon_toggle'] = 'リボン';

  return $columns;
});


// カラムをソート可能にする
add_filter('manage_edit-post_sortable_columns', function ($columns) {
  $columns['ribbon_toggle'] = 'ribbon_sort';

  return $columns;
});


// 投稿クエリの取得条件を変更
add_action('pre_get_posts', function ($query) {
  if (!is_admin() || !$query->is_main_query() || 'ribbon_sort' !== $query->get('orderby')) {
    return;
  }

  $order = strtoupper($query->get('order')) === 'ASC' ? 'ASC' : 'DESC';

  add_filter('posts_orderby', function () use ($order) {
    global $wpdb;
    return "COALESCE((
      SELECT IF(LOCATE('my-ribbon', meta_value) > 0,
                CAST(SUBSTRING(meta_value, LOCATE('my-ribbon', meta_value) + 9, 1) AS UNSIGNED), 0)
      FROM {$wpdb->postmeta}
      WHERE post_id = {$wpdb->posts}.ID AND meta_key = 'the_page_memo'
      LIMIT 1
    ), 0) {$order}, {$wpdb->posts}.post_date DESC";
  });
});


// 管理画面一覧のカラムにデータを表示
add_action('manage_posts_custom_column', function ($column, $post_id) {
  if ($column !== 'ribbon_toggle') {
    return;
  }

  $memo = get_post_meta($post_id, 'the_page_memo', true);

  // 現在の my-ribbon1 〜 my-ribbon5 を抽出
  $selected_ribbon = '';
  if (preg_match('/\b(my-ribbon[1-5])\b/', $memo, $matches)) {
    $selected_ribbon = $matches[1];
  }

  $options = ['' => '-'];

  for ($i = 1; $i <= 5; $i++) {
    $ribbon_no = (string) $i;
    $label = 'リボン ' . $ribbon_no;

    // 既存のCocoon関数を呼び出してHTMLタグを取得し、中の文言を抽出
    $tag_html = get_navi_card_ribbon_tag($ribbon_no);
    if (!empty($tag_html) && preg_match('/<span>(.*?)<\/span>/u', $tag_html, $m)) {
      $label = strip_tags($m[1]);
    }

    $options['my-ribbon' . $ribbon_no] = $label;
  }
  ?>
  <select class="ribbon-select" data-post-id="<?php echo (int) $post_id; ?>">
    <?php foreach ($options as $value => $label) : ?>
      <option value="<?php echo esc_attr($value); ?>" <?php selected($selected_ribbon, $value); ?>>
        <?php echo esc_html($label); ?>
      </option>
    <?php endforeach; ?>
  </select>
  <?php
}, 10, 2);


// Ajaxアクションを追加
add_action('wp_ajax_ribbon_toggle_callback', function () {
  // nonceチェック
  check_ajax_referer('ribbon_toggle_action', 'ribbon_toggle_nonce');

  $post_id = intval($_POST['post_id']);
  $ribbon  = isset($_POST['ribbon']) ? sanitize_text_field($_POST['ribbon']) : '';

  // 許可されたリボン名かチェック
  if ($ribbon !== '' && !preg_match('/^my-ribbon[1-5]$/', $ribbon)) {
    wp_send_json_error(['message' => 'invalid ribbon']);
  }

  // 権限チェック
  if (!current_user_can('edit_post', $post_id)) {
    wp_send_json_error(['message' => 'permission denied']);
  }

  $memo = get_post_meta($post_id, 'the_page_memo', true);

  // 既存の my-ribbon1〜5 をすべて削除
  $memo = preg_replace('/\bmy-ribbon[1-5]\b/', '', $memo);
  $memo = trim(preg_replace('/\s+/', ' ', $memo));

  // 選択されたリボンがある場合は設定
  if ($ribbon !== '') {
    $memo = trim($memo . ' ' . $ribbon);
  }

  update_post_meta($post_id, 'the_page_memo', $memo);

  wp_send_json_success();
});


// 管理画面用JSを追加
add_action('admin_enqueue_scripts', function ($hook_suffix) {
  $screen = get_current_screen();
  if ($hook_suffix !== 'edit.php' || !$screen || $screen->post_type !== 'post') {
    return;
  }

  $ajax_url = admin_url('admin-ajax.php');
  $nonce = wp_create_nonce('ribbon_toggle_action');

  ob_start();
  ?>
  jQuery(function ($) {
    $(document).on('change', 'select.ribbon-select', function () {
      var $select = $(this);
      var postId = $select.data('post-id');
      var ribbon = $select.val();

      $select.prop('disabled', true);

      $.ajax({
        url: '<?php echo esc_url($ajax_url); ?>',
        type: 'POST',
        data: {
          action: 'ribbon_toggle_callback',
          post_id: postId,
          ribbon: ribbon,
          ribbon_toggle_nonce: '<?php echo esc_js($nonce); ?>'
        },
        success: function (res) {
          $select.prop('disabled', false);
          if (!res.success) {
            alert('保存に失敗しました。');
          }
        },
        error: function () {
          $select.prop('disabled', false);
          alert('通信エラーが発生しました。');
        }
      });
    });
  });
  <?php
  wp_add_inline_script('jquery', ob_get_clean());
});

さいごに

今回紹介した方法を使えば、エントリーカードに簡単にリボンを追加することができ、記事の注目ポイントを視覚的に強調することができます。
これにより、訪問者により効果的にアピールできます。

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