Метод vc_mapping в кастомном блоке WPBakeryShortCode инициализируется на всех страницах?

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

Пришлось мне тут писать блок для Visual Composer как-то так:

add_action('init', function() {     class vcCatalogBlock extends WPBakeryShortCode     {         function __construct()         {             add_action('vc_before_init', [$this, 'vc_mapping']);             add_shortcode('vc_catalog_block', [$this, 'vc_catalog_block']);         }          public function vc_mapping()         {             vc_map(                 array(                     'name' => 'VC Catalog Block',                     'base' => 'vc_catalog_block',                     'description' => 'Каталог компаний',                     'category' => 'Блоки',                     'icon' => '',                     'params' => array(                         array(                             'type' => 'dropdown',                             'heading' => "Выберите конференцию",                             'param_name' => 'conference_id',                             'value' => $this->get_conferences(),                             'admin_label' => true,                         ),                     )                 )             );         }          public function get_conferences()         {             $result = wp_remote_post(CRM_SITE_URL . '/api/conference/list');         }      }      new vcCatalogBlock(); });

add_action('init', function() { class vcCatalogBlock extends WPBakeryShortCode { function __construct() { add_action('vc_before_init', [$this, 'vc_mapping']); add_shortcode('vc_catalog_block', [$this, 'vc_catalog_block']); } public function vc_mapping() { vc_map( array( 'name' => 'VC Catalog Block', 'base' => 'vc_catalog_block', 'description' => 'Каталог компаний', 'category' => 'Блоки', 'icon' => '', 'params' => array( array( 'type' => 'dropdown', 'heading' => "Выберите конференцию", 'param_name' => 'conference_id', 'value' => $this->get_conferences(), 'admin_label' => true, ), ) ) ); } public function get_conferences() { $result = wp_remote_post(CRM_SITE_URL . '/api/conference/list'); } } new vcCatalogBlock(); });

он получает данные по API с соседнего сайта - и что вы думаете?
эта зараза на всех страницах WordPress срабатывает а не только когда используется на сайте или редактируется в админке!

получается экшен vc_before_init срабатывает всегда и на всех страницах - но зачем?

может я что-то не учел? как-то не правильно сделал?

Дополнительно:

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

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

Заказать помощь
Лучший ответ
1
Роман IT Ответ

Да, код внутри vc_map() и подготовка массива параметров могут выполняться не только на странице, где реально используется блок. WPBakery регистрирует элементы при инициализации редактора/шорткодов, поэтому если в момент регистрации Вы вызываете внешний API, этот запрос может происходить слишком часто: в админке, на страницах редактирования и иногда на фронте при загрузке набора элементов.

Главная ошибка — вызывать get_conferences() прямо внутри массива params. Этот массив должен быть лёгким. Данные из API нужно кэшировать и получать только там, где они реально нужны.

function my_get_conference_options() {
    $cached = get_transient('my_conference_options');
    if ($cached !== false) {
        return $cached;
    }
 
    $items = my_remote_get_conferences();
    $options = [];
 
    foreach ($items as $item) {
        $options[$item['title']] = $item['id'];
    }
 
    set_transient('my_conference_options', $options, HOUR_IN_SECONDS);
    return $options;
}

function my_get_conference_options() { $cached = get_transient('my_conference_options'); if ($cached !== false) { return $cached; } $items = my_remote_get_conferences(); $options = []; foreach ($items as $item) { $options[$item['title']] = $item['id']; } set_transient('my_conference_options', $options, HOUR_IN_SECONDS); return $options; }

Если список нужен только в админке WPBakery, оберните регистрацию проверками is_admin() и наличия WPBakery. Если API тяжёлый, лучше сделать кнопку обновления списка или AJAX-загрузку поля, а не обращаться к API при каждом открытии страницы.

Для фронта храните в шорткоде выбранный ID, а не весь список. При выводе блока берите только нужную конференцию по ID и тоже кэшируйте ответ. Тогда страница не будет зависеть от внешнего API при каждом просмотре.

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

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

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

комментарий

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

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