web-dev-qa-db-ja.com

グーテンベルクの動的ブロックが404を返す

動的ブロックを作成しようとしていますが、ドキュメントに記載されている手順に従いましたが、何らかの理由で/wp-json/wp/v2/block-renderer/plugin-blocks/frontpage-releases?context=edit&_locale=userから返されているコンテンツはError loading block: No route was found matching the URL and request methodであり、実際のブロックではなく{"code":"rest_no_route","message":"No route was found matching the URL and request method","data":{"status":404}}を示すJSON応答が含まれています。これが私のレビュー用のコードです。何か足りない場合はお知らせください。ありがとう!

実装に関するメモ:

  • すべてのブロックは、Reactを介してlaravel-mixを介してWebpackでassets/js/blocks.jsにコンパイルされます。

これまでのデバッグ結果:

  • showBlock()メソッドは、ページを保存するときに呼び出されますが、エディターでページのコンテンツに追加したときや、ページ自体からは呼び出されません。
  • 現在、分類法またはカスタムブロックグループが原因であるかどうかをテストしています。
  • ob_start()/ob_get_clean()を使用しないようにコードを変更し、それを$value変数に追加して、それが問題の原因であるかどうかを確認しました。
  • xdebugデバッグでPhpStormヘルパー拡張に加えて使用するmonolog/monologを追加および削除し、handle()メソッドを呼び出しているが、showBlock()メソッドは保存時を除きます。

BlockFactory.php

namespace LibraryPlugin\Entities\Blocks;

use LibraryPlugin\Entities\Blocks\Dynamic\FrontpageReleases;
use LibraryPlugin\Traits\Helpers\LocationHelperTrait;

/**
 * Class BlockFactory
 *
 * Loads all of the blocks into the editor, so that we can use them.
 * This is called from the plugin file, within the main plugin file,
 * if we are in the admin panel.
 *
 * @package LibraryPlugin\Entities\Blocks
 */
class BlockFactory
{
    use LocationHelperTrait;

    /**
     * BlockFactory constructor.
     *
     * This is run as soon as the plugin is being loaded and allows
     * the plugin to add all of the blocks to the `init` action, before
     * the other stages.
     *
     * @throws \Exception
     */
    public function __construct()
    {
        $blocks = [
            ..., // Other non-dynamic blocks that work
            FrontpageReleases::class,
        ];

        add_filter(
            'block_categories',
            function ($categories, $post) {
                return array_merge(
                    [
                        [
                            'slug' => 'plugin-templates',
                            'title' => 'Plugin Page Templates'
                        ],
                        [
                            'slug'  => 'plugin-blocks',
                            'title' => 'Plugin Blocks',
                        ],
                    ],
                    $categories
                );
            },
            1,
            2
        );

        add_action('init', function () {
            wp_register_script(
                'plugin-blocks',
                $this->webAsset('js/blocks.js'),
                ['wp-blocks', 'wp-i18n', 'wp-element', 'wp-editor', 'lodash', 'wp-components'],
                PLUGIN_VERSION
            );

            // Ensure we have the location of any assets in plugin
            wp_localize_script('plugin-blocks', 'PLUGIN', [
                'pluginUrl' => PLUGIN_URI,
            ]);

            wp_register_style(
                'plugin-blocks',
                $this->webAsset('css/blocks.css'),
                [],
                PLUGIN_VERSION
            );
        });

        foreach ($blocks as $block) {
            add_action('init', [$block, 'handle']);
        }
    }
}

FrontpageReleases.php

namespace LibraryPlugin\Entities\Blocks\Dynamic;

use LibraryPlugin\Traits\Helpers\LocationHelperTrait;

/**
 * Class FrontpageReleases
 *
 * This class is called during `init` action. Uses `plugin-blocks` JS
 * and CSS declared in `BlockFactory.php`. Passes a render callback to
 * make it a dynamic block.
 *
 * @package LibraryPlugin\Entities\Blocks
 */
class FrontpageReleases
{
    use LocationHelperTrait;

    /**
     * Register the release note blocks
     *
     * @return void
     */
    public static function handle(): void
    {
        register_block_type(
            'plugin-blocks/frontpage-releases',
            [
                'render_callback' => [__CLASS__, 'showBlock']
            ]
        );
    }

    /**
     * Render the value of the releases
     *
     * @param mixed $attributes
     *
     * @return mixed
     */
    public static function showBlock($attributes = null)
    {
        $classCount = 0;
        $value = '';
        try {
            $allReleases = new \WP_Query([
                'post_type' => 'page',
                'posts_per_page' => 3,
                'tax_query' => [
                    'relation' => 'AND',
                    [
                        'taxonomy' => 'release',
                        'field' => 'term_id',
                        'terms' => get_terms('release', ['fields' => 'ids'])
                    ],
                    [
                        'taxonomy' => 'solutions',
                        'field' => 'term_id',
                        'terms' => get_terms('solutions', ['fields' => 'ids']),
                        'operator' => 'NOT IN'
                    ]
                ],
                'order'          => 'DESC',
                'orderby'        => 'release', // Sort by custom taxonomy
            ]);

            if ($allReleases->have_posts()) {
                while ($allReleases->have_posts()) {
                    $allReleases->the_post();
                    $isReleased = function_exists('types_render_field')
                        ? types_render_field('is-released')
                        : get_post_meta(get_the_ID(), 'wpcf-is-released');
                    $value .= '<div class="release-version"><a href="' . get_the_permalink() . '" title="'
                        . get_the_title() . '"><h2>' . get_the_title() . '</h2><p>';
                    if (!$isReleased && $count === 0) {
                        $value .= 'Upcoming Release';
                    }
                    if ($isReleased && $count === 0) {
                        $value .= 'Current Release';
                        $count++;
                    } elseif ($isReleased && $count > 0) {
                        $value .= 'Previous Release';
                        $count++;
                    }
                    $count++;
                    $value .= '</p></a></div>';
                }
            }

            $value .= '<div class="solution-resources">
                <a href="/resources/">
                    <h2>Helpful Information</h2>
                    <p>Recommended Browser, Product Timeline, Maintentance Changes, Cloud Report,
                        Training Videos, etc.</p>
                </a>
            </div>';
        } catch (\Exception $e) {
            // TODO: Figure out how to handle any exceptions
        }

        return $value;
    }
}

frontpage-releases.jsxblocks.jsにコンパイルされます。

import { PluginIcon } from './plugin-icon';
const { ServerSideRender } = window.wp.components;
const { registerBlockType } = window.wp.blocks;
const { __ } = window.wp.i18n;

registerBlockType('plugin-blocks/frontpage-releases', {
  title: __('Frontpage Releases', 'library-plugin'),

  icon: PluginIcon,

  category: 'plugin-blocks',

  edit: function ({ attributes }) {
    return (
      <ServerSideRender
        block="plugin-blocks/frontpage-releases"
        attributes={attributes}
      />
    );
  },

  save() {
    return null;
  },
});
4
OpensaurusRex

Handle()メソッドは、他のすべてのブロックとともに、add_action( 'enqueue_block_editor_assets、[$ block、' handle '])メソッドによって呼び出されています。

ここに問題があります。 register_block_typeの呼び出しが遅すぎます。 initアクションフック内の関数を呼び出してみてください。

コアの shortcode block で例を確認できます。

1
Alvaro