Как в WordPress сделать REST API запрос для чтения произвольных полей постов?

Ссылка скопирована
1 ответ

На клиентской части сайта я организовал Яндекс карты, на которых отображаются маркеры, загружаемые из json файла фетч запросом (моки). Все отлично работает.
Теперь мне надо через тот же фетч обратиться к серверу, чтобы он вернул мне произвольные поля (у меня в них хранятся координаты и даные для балунов) из базы данных, из которых я соберу объект с маркерами. На чистом php я бы смог это реализовать, но для этого в php файле нужно прописать логин и пароль к БД.
Поскольку у меня WP, сделать это можно через его api, но я не пойму, как. Прочитал много инфы в интернете, и нашел несколько возможных способов. Один из них это подключить wp-api, другой установить плагин acf. Но пока ни с одним не ничего не получилось.
Подскажите, пожалуйста, рабочий способ получить вменяемый ответ от сервера))

Дополнительные вопросы

Один из них это подключить wp-api, другой установить плагин acf. Но пока ни с одним не ничего не получилось.

Показывайте код. Что и где именно не получилось?

Ответы:

Если уж с acf ничего не получилось значит не пробовал ничего сделать.

acf rest api

  • В том то и дело, что после запроса по ссылке /wp-json/wp/v2/posts, сервер возвращает всего 10 постов, причем в каждом объекте поста есть ключ content на полный текст (из-за него размер ответа составляет 6 Мб). Мне из этого поста нужны всего его название, ссылка и категории, а из произвольных полей координаты. Произвольные поля я настраивал через плагин MetaBox, к счастью я нашел расширение для него MB REST API, и теперь все мои метаполя доступны по фетч запросу.
    P.S. Получилось загрузить нужные поля ссылкой, размер ответа уменьшился с 6 Мб до 500 Кб.
    /wp-json/wp/v2/posts?_fields[]=excerpt&_fields[]=id&_fields[]=link&_fields[]=meta_box&_fields[]=title

    /wp-json/wp/v2/posts?_fields[]=excerpt&_fields[]=id&_fields[]=link&_fields[]=meta_box&_fields[]=title

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Алексей Денисов Ответ

Для чтения произвольных полей через REST API не нужно подключаться к базе напрямую и хранить логин/пароль в отдельном PHP-файле. В WordPress правильный путь — зарегистрировать meta-поля для REST или сделать свой REST endpoint, который вернёт подготовленный JSON для карты.

Если поля обычные post meta, их можно открыть в REST:

add_action('init', function () {
    register_post_meta('post', 'map_lat', [
        'type'         => 'string',
        'single'       => true,
        'show_in_rest' => true,
    ]);
 
    register_post_meta('post', 'map_lng', [
        'type'         => 'string',
        'single'       => true,
        'show_in_rest' => true,
    ]);
});

add_action('init', function () { register_post_meta('post', 'map_lat', [ 'type' => 'string', 'single' => true, 'show_in_rest' => true, ]); register_post_meta('post', 'map_lng', [ 'type' => 'string', 'single' => true, 'show_in_rest' => true, ]); });

После этого в ответе /wp-json/wp/v2/posts появится meta, если post type поддерживает custom-fields и поле зарегистрировано корректно.

Но для карты часто лучше сделать отдельный endpoint, чтобы не отдавать лишние данные:

add_action('rest_api_init', function () {
    register_rest_route('site/v1', '/markers', [
        'methods'  => 'GET',
        'permission_callback' => '__return_true',
        'callback' => function () {
            $query = new WP_Query([
                'post_type'      => 'post',
                'posts_per_page' => -1,
                'meta_query'     => [
                    ['key' => 'map_lat', 'compare' => 'EXISTS'],
                    ['key' => 'map_lng', 'compare' => 'EXISTS'],
                ],
            ]);
 
            $items = [];
            foreach ($query->posts as $post) {
                $items[] = [
                    'title' => get_the_title($post),
                    'lat'   => get_post_meta($post->ID, 'map_lat', true),
                    'lng'   => get_post_meta($post->ID, 'map_lng', true),
                    'url'   => get_permalink($post),
                ];
            }
 
            return $items;
        },
    ]);
});

add_action('rest_api_init', function () { register_rest_route('site/v1', '/markers', [ 'methods' => 'GET', 'permission_callback' => '__return_true', 'callback' => function () { $query = new WP_Query([ 'post_type' => 'post', 'posts_per_page' => -1, 'meta_query' => [ ['key' => 'map_lat', 'compare' => 'EXISTS'], ['key' => 'map_lng', 'compare' => 'EXISTS'], ], ]); $items = []; foreach ($query->posts as $post) { $items[] = [ 'title' => get_the_title($post), 'lat' => get_post_meta($post->ID, 'map_lat', true), 'lng' => get_post_meta($post->ID, 'map_lng', true), 'url' => get_permalink($post), ]; } return $items; }, ]); });

На фронте:

fetch('/wp-json/site/v1/markers')
  .then(function (res) { return res.json(); })
  .then(function (markers) {
    console.log(markers);
  });

fetch('/wp-json/site/v1/markers') .then(function (res) { return res.json(); }) .then(function (markers) { console.log(markers); });

Если данные публичные, endpoint можно оставить открытым. Если там закрытая информация, добавляйте permission callback, nonce или проверку прав.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно