web-dev-qa-db-ja.com

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

WP REST AP​​I v2 pluginを使用してJSONレスポンスからナビゲーションメニューを取得しようとしています。

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

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

From 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:どうすれば解決できますか?

12
Murhaf Sousli

REST AP​​I v2のナビゲーションメニュープラグイン拡張機能があります。 https://wordpress.org/plugins/wp-api-menus/

6
Yan Takushevich

一番上の答えが「プラグイン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で使用できない任意の種類のデータを取得するための任意のルートを作成できます。アプリケーションに送信する前にデータを処理する必要がある場合にも役立ちます。

34
Liren

この種の作業にはプラグインを使用するべきではないと思います。また、 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で投稿タイプを表示するだけではありません。また、 Lirenの答え で説明されているように、デフォルトのPosts RESTコントローラを変更して、RESTにも似たような出力を表示します。それの隣にそれはまたすべてのポストタイプRESTコントローラーがすることをし、そしてそれ故にあなたにより多くのコントロールと機能性を与えます。また、これは他のRESTルートと競合しないことから、より安定したオプションであると考えてください。

0
Fleuv

@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 –ナビゲーションメニュー項目の取得

0
Deepak Rajpal

私は@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',
    ) );
} );

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

0
Sjoerd Oudman

投稿タイプを登録するときに'show_in_rest' => true,を追加する必要があります。

詳細はこちら http://v2.wp-api.org/extending/custom-content-types/ /

0
hkc