Nhận Menu điều hướng WP từ REST API V2


14

Tôi đang cố gắng để có được menu điều hướng từ phản hồi JSON bằng cách sử dụng plugin WP REST API v2 .

Không có phần mở rộng trình đơn điều hướng cho REST API v2 , nhưng chỉ dành cho V1.

Từ codex WordPress Post Type , tôi biết rằng menu điều hướng được coi là một loại bài đăng.

Từ Rest API Doc , đây là cách chúng tôi nhận các bài đăng thuộc loại:

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

Tôi đã cố gắng để có được nó như vậy:

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

Tôi đã nhận được 403 lỗi.

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

máy chủ hiểu yêu cầu của tôi nhưng nó từ chối cung cấp dữ liệu.

Q: Làm thế nào tôi có thể sửa lỗi này?


Tất cả những câu trả lời này chỉ là khủng khiếp. Cài đặt cái này, mở rộng cái kia. Nó đã được tích hợp sẵn, cộng đồng sẽ mở một vấn đề trên GitHub.
SacWebDeveloper

Câu trả lời:



47

Vì tôi không thích bản thân mình khi câu trả lời hàng đầu là "Cài đặt plugin X", đây là cách tôi giải quyết nó:

Menu hiện không có sẵn trong WP Rest. Vì vậy, những gì bạn cần làm là đăng ký điểm cuối tùy chỉnh của riêng bạn và sau đó chỉ cần gọi tuyến đường đó từ ứng dụng của bạn cần nó.

Vì vậy, bạn sẽ bao gồm một cái gì đó như thế này (trong hàm.php, plugin, bất cứ nơi nào):

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

Đối với ví dụ trên, bạn sẽ truy cập dữ liệu từ:

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

Bạn có thể sử dụng phương pháp trên để tạo bất kỳ tuyến đường nào bạn muốn để nhận bất kỳ loại dữ liệu nào không có sẵn trong WP Rest. Cũng tốt nếu bạn cần xử lý một số dữ liệu trước khi gửi nó đến ứng dụng của bạn.


4
cảm ơn vì đã chia sẻ cách giải quyết của bạn, không chỉ là một liên kết plugin ;-) Sẽ tốt hơn nếu bạn thêm tiền tố vào tên hàm hoặc sử dụng không gian tên, để tránh xung đột tên có thể xảy ra, như get_menu()là chung chung.
bạch dương

Thật tuyệt vời, mọi người không nhận ra rằng hầu hết mọi người đã cài đặt từ 30 đến 70 plugin. Họ thậm chí còn có plugin để giữ cho người khác vô hiệu hóa! thật là điên rồ Tôi nghĩ rằng tôi sẽ cài đặt một plugin để giữ chủ đề này.
Ignacio Bustos

nó chỉ xuất rafalse
moesphemie 16/11/18

1

@Liren trả lời hoạt động tốt. Tuy nhiên, rất ít người mới bắt đầu có thể không thể điều chỉnh tuyến đường. Đây là mã hoạt động tốt với WordPress Rest API v2 với sửa đổi tối thiểu.

Chỉ thay thế tên menu của bạn trong hàm wp_get_nav_menu_items () . Nếu tên menu và sên không hoạt động (Trả về sai), hãy sử dụng ID Menu (hiển thị trong Bảng điều khiển trong khi chỉnh sửa Menu đó).

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 tuyến đường:

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

Thêm chi tiết được đề cập trong Hướng dẫn: API nghỉ ngơi WordPress - Nhận các mục menu điều hướng


Đó là giải pháp tốt cho chỉ có một tuyến đường
juanitourquiza


0

Tôi không nghĩ rằng một plugin nên được sử dụng cho các loại nhiệm vụ này. Ngoài ra câu trả lời của hkc thực sự không tệ, nó chỉ cần một số giải thích thêm để làm cho công việc này với nav_menu_itemloại bài đăng (loại được sử dụng cho các menu điều hướng wp).

Loại bài đăng này đã được đăng ký và do đó chúng tôi cần thay đổi nó, điều này được thực hiện dễ dàng bằng cách móc vào register_post_type_argsbộ lọc. Bộ lọc này cho phép chúng tôi thay đổi các đối số cho một loại bài đăng cụ thể. Mã dưới đây chỉ hiển thị cho nav_menu_itemloại bài đăng.

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);

Như bạn có thể nhận thấy từ đoạn mã trên, mã thực hiện nhiều hơn một chút so với việc chỉ hiển thị loại bài đăng trong REST. Nó cũng thay đổi trình điều khiển Post REST mặc định để hiển thị đầu ra hơi giống trong REST như được mô tả trong câu trả lời của Liren . Mặc dù bên cạnh đó, nó cũng thực hiện những gì tất cả các bộ điều khiển REST loại bài làm và do đó cung cấp cho bạn nhiều quyền kiểm soát và chức năng hơn. Cũng xem xét điều này như một tùy chọn ổn định hơn vì nó sẽ không xung đột với các tuyến REST khác và cuối cùng nhưng không kém phần quan trọng, nó cũng thuận tiện hơn khi làm việc với.


0

Tôi đồng ý với câu trả lời của @Lirens, nhưng các menu nên được gọi bằng ID, không phải sên. Ngoài ra, dấu gạch chéo trước đường dẫn menu là không cần thiết. Vì vậy, nó trở thành một cái gì đó như thế này:

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

Như thế này nó làm việc cho tôi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.