【WordPress】ACFで作ったブロックのデータを他のページで取得する

この記事は[インフォ・ラウンジAdvent Calendar 2023](https://qiita.com/advent-calendar/2023/info-lounge) 4日目の記事です

前回は @yuuya08110 くんの[RedwoodJSはいいぞおじさん「RedwoodJSはいいぞぉ」](https://qiita.com/yuuya08110/items/bc746cfd5f9e4f1f5c4a)でした。
２日連続の投稿すごい！

---

## この記事は？
今までやったことがなかった、他のページのブロックのデータを取得するのを
先日やったのでメモ:pencil:

## 前提
- WordPress:6.3.2
- Advanced Custom Fields PRO：6.2.4

### ブロック（カスタムフィールド）の作り

acf/anchor

- anchor：リピートフィールド
    - link：リンク（#を除いて指定する）
    - text：テキスト

### ページの関係
- aページ（slugをaとする）
    - anchorブロックを使う（ページ内アンカーとして使用）
- bページ
    - A#リンクという別ページのアンカーとして表示したい


aページにアンカーブロックを入れて保存
＊前後には段落があります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13242/3eb49484-8769-aaab-0035-7cb726a969f3.png)


## 実装！
### まずaページのIDを取得

```php
$a_page = get_page_by_path('a');
$a_id = $a_page->ID;
```

## ページIDからブロックの配列を取得

```php
$post_blocks = parse_blocks(get_the_content('', false, $a_id));
```

これをvar_dumpしてみると以下のようになります。

```php
array (size=5)
  0 => 
    array (size=5)
      'blockName' => string 'core/paragraph' (length=14)
      'attrs' => 
        array (size=0)
          empty
      'innerBlocks' => 
        array (size=0)
          empty
      'innerHTML' => string '
<p>テキスト</p>
' (length=40)
      'innerContent' => 
        array (size=1)
          0 => string '
<p>テキスト</p>
' (length=40)
  1 => 
    array (size=5)
      'blockName' => null
      'attrs' => 
        array (size=0)
          empty
      'innerBlocks' => 
        array (size=0)
          empty
      'innerHTML' => string '

' (length=2)
      'innerContent' => 
        array (size=1)
          0 => string '

' (length=2)
  2 => 
    array (size=5)
      'blockName' => string 'acf/anchor' (length=10)
      'attrs' => 
        array (size=3)
          'name' => string 'acf/anchor' (length=10)
          'data' => 
            array (size=10)
              ...
          'mode' => string 'edit' (length=4)
      'innerBlocks' => 
        array (size=0)
          empty
      'innerHTML' => string '' (length=0)
      'innerContent' => 
        array (size=0)
          empty
  3 => 
    array (size=5)
      'blockName' => null
      'attrs' => 
        array (size=0)
          empty
      'innerBlocks' => 
        array (size=0)
          empty
      'innerHTML' => string '

' (length=2)
      'innerContent' => 
        array (size=1)
          0 => string '

' (length=2)
  4 => 
    array (size=5)
      'blockName' => string 'core/paragraph' (length=14)
      'attrs' => 
        array (size=0)
          empty
      'innerBlocks' => 
        array (size=0)
          empty
      'innerHTML' => string '
<p>テキスト</p>
' (length=40)
      'innerContent' => 
        array (size=1)
          0 => string '
<p>テキスト</p>
' (length=40)
```

acf/anchorブロックだけ表示してみます。

```php
    foreach ($post_blocks as $block) {
        if ($block['blockName'] === 'acf/anchor') {
            var_dump($block);
        }
    }
```

これをvar_dumpしてみるとdataの中にanchor_【index番号】_textとanchor_【index番号】_linkとして、
取得したいデータがあることがわかります。

```php
array (size=5)
  'blockName' => string 'acf/anchor' (length=10)
  'attrs' => 
    array (size=3)
      'name' => string 'acf/anchor' (length=10)
      'data' => 
        array (size=10)
          'anchor_0_text' => string 'リンク01' (length=11)
          '_anchor_0_text' => string 'field_654c468b343e6' (length=19)
          'anchor_0_link' => string 'link01' (length=6)
          '_anchor_0_link' => string 'field_654c469a343e7' (length=19)
          'anchor_1_text' => string 'リンク02' (length=11)
          '_anchor_1_text' => string 'field_654c468b343e6' (length=19)
          'anchor_1_link' => string 'link02' (length=6)
          '_anchor_1_link' => string 'field_654c469a343e7' (length=19)
          'anchor' => int 2
          '_anchor' => string 'field_654c466b343e5' (length=19)
      'mode' => string 'edit' (length=4)
  'innerBlocks' => 
    array (size=0)
      empty
  'innerHTML' => string '' (length=0)
  'innerContent' => 
    array (size=0)
      empty
```

### アンカーブロックのデータを取得する

```php
<?php
    $anchor_list = []; //アンカーを配列として保存する用

    foreach ($post_blocks as $block) {
        if ($block['blockName'] === 'acf/anchor') {
            //anchorにアンカーリンクの個数が保存されているので、取得
            $count = $block['attrs']['data']['anchor'];
            for ($i = 0; $i < $count; $i++) {
                // テキストを配列$anchor_listの[index番号]['text']に保存
                $anchor_list[$i]['text'] = $block['attrs']['data']["anchor_{$i}_text"];
                // リンクを配列$anchor_listの[index番号]['link']に保存
                $anchor_list[$i]['link'] = $block['attrs']['data']["anchor_{$i}_link"];
            }
        }
    }
    // $anchor_listをforeachで出力
    if ($anchor_list):foreach ($anchor_list as $anchor):
    $a_page = get_page_by_path('a');
    $a_link = get_permalink($a_page->ID)
    ?>
      <?php echo $a_link . '#' . $anchor['link']; ?>
      <?php echo $anchor['text']; ?>
    <?php endforeach;endif; ?>
```

無事出力できた！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13242/00c0545c-d8b9-4e15-c726-adc419444b3e.png)

## まとめ
- ACFでできたブロックのデータを他のページで取得できる
- リピートフィールドやそれと似た作りのフィールドだとちょっと大変
- ブロックなので、もし何個も入ってる時はどうするの？という話もある

---

明日は @sakzw くんが[Zoomミーティングに参加中であるか判定する（Windows） \#PowerShell \- Qiita](https://qiita.com/sakzw/items/bf4f837bc6596f096e9f)を書いてくれるようです。
楽しみですね！