REST API V2からWPナビゲーションメニューを取得する


14

WP REST API v2プラグインを使用して、JSON応答からナビゲーションメニューを取得しようとしています。

REST API v2用のナビゲーションメニュープラグイン拡張機能はありませんが、V1専用です。

コーデックスのWordPress投稿タイプから、ナビゲーションメニューが投稿タイプとして扱われることを学びました。

Rest API Docから、これがタイプの投稿を取得する方法です:

GET http://demo.wp-api.org/wp-json/wp/v2/types/<type>

私はそのようにしようとしました:

URL : http://localhost/wptest/wp-json/wp/v2/types/nav_menu_item

403エラーを受け取りました。

{"code":"rest_cannot_read_type","message":"Cannot view type.","data":{"status":403}}

サーバーは私の要求を理解しましたが、データの提供を拒否しました。

Q:どうすれば修正できますか?


これらの答えはすべてひどいものです。これをインストールし、拡張します。既に組み込まれているはずで、コミュニティはGitHubで問題を開く必要があります。
SacWebDeveloper

回答:



47

一番の答えが「プラグインXのインストール」であるとき、私はそれが好きではないので、ここに私がそれを解決した方法があります:

メニューは現在、WP Restでは使用できません。そのため、独自のカスタムエンドポイント登録し、必要なアプリケーションからそのルートを呼び出すだけです。

したがって、次のようなものを含めます(functions.php、プラグイン、どこでも):

function get_menu() {
    # Change 'menu' to your own navigation slug.
    return wp_get_nav_menu_items('menu');
}

add_action( 'rest_api_init', function () {
        register_rest_route( 'myroutes', '/menu', array(
        'methods' => 'GET',
        'callback' => 'get_menu',
    ) );
} );

上記の例では、次からデータにアクセスします。

http://your-domain.dev/wp-json/myroutes/menu

上記の方法を使用して、WP Restで使用できない任意のタイプのデータを取得するための任意のルートを作成できます。アプリケーションに送信する前にデータを処理する必要がある場合にも適しています。


4
プラグインリンクだけでなく、回避策を共有してくれてありがとう;-) get_menu()かなり一般的なように、名前の衝突を避けるために、関数名にプレフィックスを付けるか名前空間を使用することをお勧めします。
バージール

驚くべきことに、ほとんどの人が既に30〜70個のプラグインをインストールしていることに気付いていません。彼らは他の人を無効にしておくプラグインさえ持っています!クレイジーです。このスレッドを保持するためにプラグインをインストールするつもりです。
イグナシオブストス

出力のみfalse
moesphemie

1

@Lirenの回答はうまくいきます。ただし、ルートを調整できない初心者はほとんどいません。以下は、最小限の変更でWordPress Rest API v2動作するコードです

wp_get_nav_menu_items()関数でのみメニュー名を置き換えます。メニュー名とスラッグが機能しない場合(falseを返す)、メニューID(そのメニューの編集中にダッシュボードに表示される)を使用します。

function get_my_menu() {
    // Replace your menu name, slug or ID carefully
    return wp_get_nav_menu_items('Main Navigation');
}

add_action( 'rest_api_init', function () {
    register_rest_route( 'wp/v2', 'menu', array(
        'methods' => 'GET',
        'callback' => 'get_my_menu',
    ) );
} );

ルートURL:

https://website.com/wp-json/wp/v2/menu

詳細については、チュートリアル:WordPress Rest API –ナビゲーションメニュー項目の取得を ご覧ください。


これは、1つのルートのみ持っているために良い解決策だ
juanitourquizaを


0

この種のタスクにはプラグインを使用すべきではないと思います。また、hkcの答えは実際にはそれほど悪くはありません。nav_menu_item投稿タイプ(wpナビゲーションメニューに使用されるもの)でこの作業を行うには、さらに詳しい説明が必要です。

この投稿タイプは既に登録されているため、変更する必要がありregister_post_type_argsます。これは、フィルターにフックすることで簡単に実行できます。このフィルターにより、特定の投稿タイプの引数を変更できます。以下のコードは、nav_menu_item投稿タイプのコードを示しています。

add_filter('register_post_type_args', function ($args, $post_type) {
    if ($post_type == 'nav_menu_item' &&
        class_exists('WP_REST_Posts_Controller') &&
        !class_exists('WP_REST_NavMenuItem_Controller')) {

        class WP_REST_NavMenuItem_Controller extends WP_REST_Posts_Controller {
            public function get_items( $request ) {
                $args = wp_parse_args($request, [
                    'order' => 'ASC',
                    'orderby' => 'menu_order',
                ]);

                $output = [];

                if (empty($request['menu'])) {
                    $menus = get_registered_nav_menus();

                    foreach ( $menus as $location => $description ) {
                        $items = wp_get_nav_menu_items($location, $args);
                        $output = array_merge($output, is_array($items) ? $items : []);
                    }
                } else {
                    $items = wp_get_nav_menu_items($request['menu'], $args);
                    $output = array_merge($output, is_array($items) ? $items : []);
                }

                return rest_ensure_response($output);
            }

            public function get_collection_params() {
                $query_params = parent::get_collection_params();
                $query_params['menu'] = [
                    'description' => __( 'The name or also known as theme_location of the menu' ),
                    'type' => 'string',
                ];
                return $query_params;
            }
        }

        // Alter the post type arguments
        $args['show_in_rest'] = true;
        $args['rest_controller_class'] = 'WP_REST_NavMenuItem_Controller';
    }
    return $args;
}, 10, 2);

上記のコードからお気づきかもしれませんが、このコードはRESTで投稿タイプを表示するだけではありません。また、デフォルトのPosts RESTコントローラーを変更して、Lirenの回答で説明されているRESTに多少似た出力を表示します。その次には、すべての投稿タイプのRESTコントローラーが行うことも行うため、より多くの制御と機能を提供します。また、これは他のRESTルートと競合しないため、より安定したオプションであると考えてください。


0

@Lirensの回答に同意しますが、メニューはスラッグではなくIDで呼び出す必要があります。また、メニューパスの前のスラッシュは必要ありません。したがって、次のようになります。

function get_menu() {
    # Change '2' to your own navigation ID.
    return wp_get_nav_menu_items(2);
}

add_action( 'rest_api_init', function () {
    register_rest_route( 'myroutes', 'menu', array(
        'methods' => 'GET',
        'callback' => 'get_menu',
    ) );
} );

このようにそれは私のために働いた。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.