自分だけのクイズ作成 - Quipha公開中

【WordPress】投稿記事(post_content)のブロック解析

Wordpress
スポンサーリンク

はじめに

WordPressの記事の投稿画面は、ブロックエディター Gutenberg(グーテンベルク)が採用されています。

最初は私自身も戸惑いましたが、慣れるととても便利ですね!🙂

今回は、ブロックエディターで編集された投稿本文を、PHPで解析するやり方を説明します。
これが出来ると、例えば記事の一覧から特定の文字を探してリスト化したり、色々と応用が利くようになります。

覚えておくととても便利です。

本記事は、functions.phpの修正を含みます。修正前にバックアップを行いましょう。
修正については、自己責任でお願いします。

WordPressの管理画面に機能追加

ただソースを紹介してもイメージが湧きにくいと思います。
テーマのfunctions.phpを編集して、コーディングと動作確認を行ってみたいと思います。

この作業は必須ではありません。コーディングだけ見たい場合は読み飛ばしてください。

テーマのfunctions.phpを編集します。
私はデフォルトのテーマを設定していましたので、以下のファイルを編集しました。

/wp-content/themes/twentytwentyone/functions.php

以下のコードを追加し、管理画面にメニューを追加します。
あくまで動作確認が目的ですので、簡易ではありますが、ボタンを一つ配置してクリックできるようにしました。
ボタンをクリックしたら、任意の処理を実行して簡単に動作確認することができます。

/**
 * 管理画面にメニューを追加
 */
add_action('admin_menu', 'wpdocs_register_my_custom_menu_page');
function wpdocs_register_my_custom_menu_page()
{
    add_menu_page(
        'サンプル確認',
        'サンプル確認',
        // 権限
        'manage_options',
        'custompage',
        'my_custom_menu_page',
        // アイコン
        'dashicons-admin-generic',
        // メニュー位置
        4
    );
}

/**
 * 管理画面にページを追加
 */
function my_custom_menu_page()
{
?>
    <form method="post" action="">
    <?php submit_button('動作確認'); ?>
    </form>
<?php

    if ($_SERVER['REQUEST_METHOD'] == 'POST') {
        // ボタンが押されたら、実行したい処理をここに記述します
        echo "処理を実行します。";
    }
}

管理画面にメニューが増え、画面にはボタンが一つ配置されています。

クリックしてみると、メッセージが表示されます。

管理画面のメニュー追加についての詳細は、公式のリファレンスを参考にしてください。

関数リファレンス/add menu page - WordPress Codex 日本語版

本文のブロックを解析

まずは投稿本文の記事を取得してみましょう。
例えば、ブロックエディタで以下のような記事を投稿したとします。

実際の投稿内容を表示してみましょう。
先程の処理の「ボタンが押されたら」の場所にコードを書いていきます。

$post_idはご自身のWordPressに存在する記事IDを指定してください。

        // 記事を取得
        $post_id = 2479;  // TODO: 適宜変更してください

        // 記事の詳細を取得
        $page = get_post($post_id);
        echo nl2br(esc_html($page->post_content));

先程の管理画面で確認してみます。
ブロックエディタで編集した内容は、以下のようにHTMLタグで保存されています。

<!-- wp:heading -->
<h2>はじめに</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>今回は、固定ページの子ページ一覧を表示するカスタマイズを行います。<br>ウィジェットで使用できるようにしてみました。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>例えばコーポレートサイトや、マニュアルサイトでも便利に使えると思います。<br>このように、サイドバーに固定ページの子ページの一覧を表示するようにしてみます。</p>
<!-- /wp:paragraph -->

上記のHTMLタグの状態では、処理する際に扱うのが面倒ですので、「parse_blocks」関数を使用して、ブロックを解析(配列に展開)することが出来ます。

        // 記事を取得
        $post_id = 2479;  // TODO: 適宜変更してください
        $page = get_post($post_id);
        
        // ブロックを解析
        $blocks = parse_blocks($page->post_content);
        
        // 解析結果を出力
        echo "<pre>";
        echo htmlspecialchars(print_r($blocks, true));
        echo "</pre>";

このように、配列で取得することが出来ました。

Array
(
    [0] => Array
        (
            [blockName] => core/heading
            [attrs] => Array()
            [innerBlocks] => Array()
            [innerHTML] => <h2>はじめに</h2>
            [innerContent] => Array
                (
                    [0] => <h2>はじめに</h2>
                )
        )
    [1] => Array
        (
            [blockName] => 
            [attrs] => Array()
            [innerBlocks] => Array()
            [innerHTML] => 
            [innerContent] => Array
                (
                    [0] => 
                )
        )
    [2] => Array
        (
            [blockName] => core/paragraph
            [attrs] => Array()
            [innerBlocks] => Array()
            [innerHTML] => <p>今回は、固定ページの子ページ一覧を表示するカスタマイズを行います。<br>ウィジェットで使用できるようにしてみました。</p>
            [innerContent] => Array
                (
                    [0] => <p>今回は、固定ページの子ページ一覧を表示するカスタマイズを行います。<br>ウィジェットで使用できるようにしてみました。</p>
                )
        )
...

「blockName」を参照することによって、ブロックの種類を特定できそうですね。

応用例

ブロックの解析を利用して、投稿されている記事の情報を取得するコードをまとめました。
プラグインを探さなくても簡単なリストアップなどに役立つでしょう。

記事内の見出し一覧を取得

        // 記事を取得
        $post_id = 2479;  // TODO: 適宜変更してください
        $page = get_post($post_id);

        // ブロックを解析
        $blocks = parse_blocks($page->post_content);
        foreach ($blocks as $key => $value) {
            // 見出しブロックを取得
            if ($value['blockName'] == 'core/heading') {
                echo htmlspecialchars($value['innerHTML']);
            }
        }

記事の中にある見出しの一覧を取得できました。

記事内の画像一覧を取得

        // 記事を取得
        $post_id = 2479;  // TODO: 適宜変更してください
        $page = get_post($post_id);

        // ブロックを解析
        $blocks = parse_blocks($page->post_content);
        foreach ($blocks as $key => $value) {
            // 画像ブロックを取得
            if ($value['blockName'] == 'core/image') {
                echo htmlspecialchars($value['innerHTML']) . '<br>';
            }
        }

記事の中にある画像の一覧を取得できました。

余談ですが、HTMLの中の画像のURLのみ取得したい場合は、以下のような関数を作成しました。

function get_img_src($html)
{
    $regex = '|<img src=\"(.*?)\".*?/>|mis';
    preg_match_all($regex, $html, $match);
    $url = $match[1][0];
    return $url;
}

以下のように呼び出して、画像のURLのみ取得することが出来ます。

        // 記事を取得
        $post_id = 2479;  // TODO: 適宜変更してください
        $page = get_post($post_id);

        // ブロックを解析
        $blocks = parse_blocks($page->post_content);
        foreach ($blocks as $key => $value) {
            // 画像ブロックを取得
            if ($value['blockName'] == 'core/image') {
                echo htmlspecialchars(get_img_src($value['innerHTML'])) . '<br>';
            }
        }

全記事の画像一覧を取得

これまでは特定の記事のIDを指定して、記事内の情報を取得しましたが、全記事の情報を取得することもできます。

        // 記事の一覧を取得
        $pages = get_posts(
            array(
                'post_type' => ['post'],
                'orderby' => 'post__in',
                'posts_per_page' => 200,
            )
        );

        foreach ($pages as $index => $page) {
            // 記事を取得
            $page = get_post($page->ID);

            // ブロックを解析
            $blocks = parse_blocks($page->post_content);
            foreach ($blocks as $key => $value) {
                // 画像ブロックを取得
                if ($value['blockName'] == 'core/image') {
                    echo htmlspecialchars(get_img_src($value['innerHTML'])) . '<br>';
                }
            }
        }

さいごに

今回は、WordPressの記事のブロックの解析を行いました。
是非活用してみてください~

コメント

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