Как получить список всех подключенных скриптов и стилей?

25 июл. 2016 г., 17:44:50
Просмотры: 41.9K
Голосов: 23

Я создаю плагин и хочу получить список всех скриптов и CSS, используемых другими плагинами.

Вот моя функция:

function crunchify_print_scripts_styles() {    
    $result = [];
    $result['scripts'] = [];
    $result['styles'] = [];

    // Выводим все загруженные скрипты
    global $wp_scripts;
    foreach( $wp_scripts->queue as $script ) :
       $result['scripts'][] =  $wp_scripts->registered[$script]->src . ";";
    endforeach;

    // Выводим все загруженные стили (CSS)
    global $wp_styles;
    foreach( $wp_styles->queue as $style ) :
       $result['styles'][] =  $wp_styles->registered[$style]->src . ";";
    endforeach;

    return $result;
}
add_action( 'wp_enqueue_scripts', 'crunchify_print_scripts_styles');

Я хочу получить возвращаемое значение внутри переменной.

Я пробовал это:

$toto = do_action( 'crunchify_print_scripts_styles' );
var_dump( $toto );

И вот мой результат:

NULL

Если я напишу echo внутри каждого цикла foreach, я получаю правильные результаты, но как сохранить эти значения внутри переменной?

[редактировать]

Мой код внутри плагина, который тоже не работает

/**
 *  Получить все скрипты и стили из WordPress
 */
function print_scripts_styles() {

    $result = [];
    $result['scripts'] = [];
    $result['styles'] = [];

    // Выводим все загруженные скрипты
    global $wp_scripts;
    foreach( $wp_scripts->queue as $script ) :
        $result['scripts'][] =  $wp_scripts->registered[$script]->src . ";";
    endforeach;

    // Выводим все загруженные стили (CSS)
    global $wp_styles;
    foreach( $wp_styles->queue as $style ) :
        $result['styles'][] =  $wp_styles->registered[$style]->src . ";";
    endforeach;

    return $result;
}

add_action( 'wp_head', 'wp_rest_assets_init');

/**
 * Инициализация маршрутов JSON REST API Assets.
 *
 * @since 1.0.0
 */
function wp_rest_assets_init() {

    $all_the_scripts_and_styles = print_scripts_styles();

    if ( ! defined( 'JSON_API_VERSION' ) &&
         ! in_array( 'json-rest-api/plugin.php', get_option( 'active_plugins' ) ) ) {
             $class = new WP_REST_Assets();
             $class::$scriptsAndStyles = $all_the_scripts_and_styles;
             add_filter( 'rest_api_init', array( $class, 'register_routes' ) );
    } else {
        $class = new WP_JSON_Menus();
        add_filter( 'json_endpoints', array( $class, 'register_routes' ) );
    }
}

add_action( 'init', 'wp_rest_assets_init' );
7
Комментарии

do_action не возвращает результат, и, кроме того, действие уже произошло на wp_enqueue_scripts ... проще просто создать глобальную переменную, например. global $crunchifyenqueued; $crunchifyenqueued = $result;, а затем снова вызвать глобальную переменную в вашей последующей функции для доступа к переменной.

majick majick
25 июл. 2016 г. 17:54:23

Спасибо за ваш ответ, но это не решило проблему, ответ для var_dump($crunchifyenqueued) - "NULL".

Edouard Kombo Edouard Kombo
25 июл. 2016 г. 18:09:16

так почему бы не использовать apply_filters тогда? вы можете легко получить возвращаемое значение из него.

majick majick
25 июл. 2016 г. 18:57:21

Я уже пробовал, не могу сохранить результат внутри переменной.

Edouard Kombo Edouard Kombo
27 июл. 2016 г. 11:04:31

Конечно можешь, используя global?

majick majick
27 июл. 2016 г. 11:49:11

Тоже не работает

Edouard Kombo Edouard Kombo
27 июл. 2016 г. 12:59:40

откуда вообще берется endforeach; в подобном коде??

T.Todua T.Todua
7 апр. 2020 г. 14:32:24
Показать остальные 2 комментариев
Все ответы на вопрос 5
13
22

do_action работает не совсем так. Когда вы вызываете do_action('crunchify_print_scripts_styles'), WordPress просматривает список зарегистрированных действий и фильтров для всех, которые прикреплены к хуку с именем crunchify_print_scripts_styles, а затем выполняет эти функции.

И, вероятно, вам стоит удалить это:

add_action( 'wp_enqueue_scripts', 'crunchify_print_scripts_styles');

... потому что вы не можете получить возвращаемый результат вашей функции.

Кроме того, при использовании этого конкретного хука вы не можете гарантировать, что другие функции не добавят больше скриптов или стилей после того, как вы сгенерировали свой список. Для удобства используйте хук, который срабатывает после того, как все скрипты и стили были добавлены в очередь, например wp_head, или еще лучше — просто вызывайте вашу функцию в теме, когда вам нужно отобразить результат.

Переработка вашего кода должна выглядеть так...

function crunchify_print_scripts_styles() {

    $result = [];
    $result['scripts'] = [];
    $result['styles'] = [];

    // Выводим все загруженные скрипты
    global $wp_scripts;
    foreach( $wp_scripts->queue as $script ) :
       $result['scripts'][] =  $wp_scripts->registered[$script]->src . ";";
    endforeach;

    // Выводим все загруженные стили (CSS)
    global $wp_styles;
    foreach( $wp_styles->queue as $style ) :
       $result['styles'][] =  $wp_styles->registered[$style]->src . ";";
    endforeach;

    return $result;
}

Затем в вашей теме:

print_r( crunchify_print_scripts_styles() );

... покажет вам результаты для отладки, или конечно же...

$all_the_scripts_and_styles = crunchify_print_scripts_styles();

... даст вам список для манипуляций.

Вызов функции в теме гарантирует, что она будет вызвана после того, как все скрипты и стили будут добавлены в очередь.

Чтобы вызвать её из вашего плагина, прикрепите её к любому хуку, который выполняется позже, чем wp_enqueue_scripts, например wp_head, как я упомянул выше:

add_action( 'wp_head', 'wpse_233142_process_list');

function wpse_233142_process_list() {

    $all_the_scripts_and_styles = crunchify_print_scripts_styles();
    // обрабатываем массив здесь

}
25 июл. 2016 г. 17:57:57
Комментарии

Спасибо @Andy, но я хочу получить эти значения внутри плагина. Мой плагин будет возвращать эти значения в формате json.

Edouard Kombo Edouard Kombo
25 июл. 2016 г. 18:03:37

Тогда поместите $all_the_scripts_and_styles = crunchify_print_scripts_styles(); в ваш плагин! Изменил ответ для вашего случая.

Andy Macaulay-Brook Andy Macaulay-Brook
25 июл. 2016 г. 18:06:41

Это не работает, оба массива scripts и styles пустые. Похоже, что global wp_scripts и global wp_styles полностью пустые. Но они работают с do_action или apply_filters

Edouard Kombo Edouard Kombo
25 июл. 2016 г. 18:15:58

Вызываете ли вы свою функцию позже действия wp_enqueue_scripts, как я изначально рекомендовал?

Andy Macaulay-Brook Andy Macaulay-Brook
25 июл. 2016 г. 18:17:36

Я расширил ответ, чтобы сделать это более понятным.

Andy Macaulay-Brook Andy Macaulay-Brook
25 июл. 2016 г. 18:21:00

ООООООООО? Большое спасибо, все работает ОТЛИЧНО !!!!!!!! Как я могу реализовать эту новую функцию wpse_233142_process_list внутри моего плагина? Должно ли у нее быть такое же имя?

Edouard Kombo Edouard Kombo
25 июл. 2016 г. 19:04:49

Переименуйте его как хотите, главное — не забудьте изменить название и в вызове фильтра. И не стесняйтесь принять ответ ;-)

Andy Macaulay-Brook Andy Macaulay-Brook
25 июл. 2016 г. 21:56:31

Хорошо, извините, но это работает корректно внутри темы, но не внутри плагина. Я ищу причину, как найду — поделюсь результатом.

Edouard Kombo Edouard Kombo
27 июл. 2016 г. 12:34:34

Если весь ваш код запускается через хуки, разницы быть не должно.

Andy Macaulay-Brook Andy Macaulay-Brook
27 июл. 2016 г. 12:37:29

Я обновил свой первоначальный пост основным кодом плагина, если вы хотите его просмотреть...

Edouard Kombo Edouard Kombo
27 июл. 2016 г. 12:58:24

Давайте продолжим обсуждение в чате.

Edouard Kombo Edouard Kombo
27 июл. 2016 г. 13:01:57

Не могу сейчас общаться в чате. Но похоже, что вы вызываете свою функцию на двух разных хуках, и когда вы вызываете её на init, то ни один скрипт или стиль ещё не будет зарегистрирован. Я не рассматривал REST API, так что тут я не компетентен, но вам нужно вызывать мой код как можно позже, как мы обсуждали. Также помните, что скрипты и стили не нужны и не требуются при API-вызове, поэтому возможно, что в этом контексте они не зарегистрированы и вам нечего будет выводить в списке.

Andy Macaulay-Brook Andy Macaulay-Brook
27 июл. 2016 г. 13:07:59

Сейчас я ищу способ заставить мои хуки выполняться последними, потому что не вижу другого решения

Edouard Kombo Edouard Kombo
27 июл. 2016 г. 13:26:23
Показать остальные 8 комментариев
0
17

Вы можете использовать действия wp_print_scripts и wp_print_styles для своевременного и правильного доступа к подключенным скриптам и стилям, так как эти действия являются последними событиями перед тем, как скрипты и стили будут включены в документ, и, следовательно, последними событиями, где изменения в $wp_styles или $wp_scripts могут повлиять на стили и скрипты, включенные в документ.

Таким образом, это те события, где вы можете быть наиболее уверены, что $wp_styles и $wp_scripts содержат скрипты и стили, которые действительно будут включены в документ.

add_action( 'wp_print_scripts', 'cyb_list_scripts' );
function cyb_list_scripts() {
    global $wp_scripts;
    $enqueued_scripts = array();
    foreach( $wp_scripts->queue as $handle ) {
        $enqueued_scripts[] = $wp_scripts->registered[$handle]->src;
    }
}
add_action( 'wp_print_styles', 'cyb_list_styles' );
function cyb_list_styles() {
    global $wp_styles;
    $enqueued_styles = array();
    foreach( $wp_styles->queue as $handle ) {
        $enqueued_styles[] = $wp_styles->registered[$handle]->src;
    }
}

Если вы объявите $enqueued_scripts и $enqueued_styles как глобальные переменные (или в любой другой допустимой области видимости, например, вы можете сохранить их в свойстве метода), вы сможете получить доступ к списку скриптов и стилей в последующем действии.

Например (просто быстрый пример):

global $enqueued_scripts;
global $enqueued_styles;

add_action( 'wp_print_scripts', 'cyb_list_scripts' );
function cyb_list_scripts() {
    global $wp_scripts;
    global $enqueued_scripts;
    $enqueued_scripts = array();
    foreach( $wp_scripts->queue as $handle ) {
        $enqueued_scripts[] = $wp_scripts->registered[$handle]->src;
    }
}
add_action( 'wp_print_styles', 'cyb_list_styles' );
function cyb_list_styles() {
    global $wp_styles;
    global $enqueued_styles;
    $enqueued_styles = array();
    foreach( $wp_styles->queue as $handle ) {
        $enqueued_styles[] = $wp_styles->registered[$handle]->src;
    }
}

add_action( 'wp_head', function() {
    global $enqueued_scripts;
    var_dump( $enqueued_scripts );
    global $enqueued_styles;
    var_dump( $enqueued_styles );
} );
25 июл. 2016 г. 19:15:41
2

Моё решение для этого:

  • создать поле опции в базе данных
  • активировать сессии и защитить их

Использованные функции

Я начал с двух функций пользователя cybmeta: просто добавил обработчик к результату.

function theme_list_scripts() {

    global $wp_scripts;
    global $enqueued_scripts;
    $enqueued_scripts = array();
    foreach( $wp_scripts->queue as $handle ) {
        $enqueued_scripts[] = $handle." | ".$wp_scripts->registered[$handle]->src;
    }
    return $enqueued_scripts;


}

function theme_list_styles() {

    global $wp_styles;
    global $enqueued_styles;
    $enqueued_styles = array();
    foreach( $wp_styles->queue as $handle ) {
        $enqueued_styles[] = $handle." | ".$wp_styles->registered[$handle]->src;
    }
    return $enqueued_styles;

}

add_action( 'wp_print_scripts', 'wpcustom_inspect_scripts_and_styles' );

function wpcustom_inspect_scripts_and_styles(){

    $loadet_list = array();

    $loadet_list["style"] = implode( " ; ",theme_list_styles() );

    $loadet_list["script"] = implode( " ; ",theme_list_scripts() );

    $_SESSION["front-end-list"] = implode("{}",$loadet_list);  


}

function front_loadet_files_list(){

    update_option( 'front_incl_list', $_SESSION["front-end-list"] );

} 

В файле header вызвать после wp_head() перед закрывающим тегом head:

front_loadet_files_list(); 

В админке в файле шаблона где нужно отобразить:

получить данные из поля опции в базе данных

$loadet_list = prep_front_list("front-end-list");

вызвать для отображения

display_front_list($loadet_list["styles"]);

display_front_list($loadet_list["scripts"]);

результатвид результата

9 апр. 2020 г. 13:51:18
Комментарии

это разрушает опыт использования Stackexchange. Научитесь, черт возьми, писать код с правильным форматированием. Вы можете создавать гораздо больше проблем, чем решений, просто вываливая совершенно неформатированный код.

Altin Altin
13 сент. 2020 г. 14:33:43

Похоже, это единственное рабочее решение среди всех ответов. Хотя было бы хорошо избавиться от использования переменной $_SESSION.

Serhiy Zaharchenko Serhiy Zaharchenko
24 дек. 2021 г. 11:00:21
2

Если вам действительно нужно получить список всех стилей, вы можете использовать новый фильтр 'script_loader_tag' (начиная с версии 4.1).

Действие "wp_print_scripts":

Вызывается через admin-header.php и хук ‘wp_head’.

То есть, оно не показывает скрипты в подвале (футере) сайта.

Ссылки:

Добавление атрибутов Defer и Async к скриптам WordPress

wp_print_scripts

18 янв. 2019 г. 11:26:22
Комментарии

Может быть, у вас есть пример, как это использовать?

lonix lonix
15 янв. 2020 г. 12:01:00

Привет :) Возможно, эта статья сможет помочь Ускорьте свой сайт с помощью Async и Deferred JavaScript: Обзор script_loader_tag

theuberdog theuberdog
18 февр. 2020 г. 19:18:33
0

Чтобы получить зарегистрированные скрипты, вам понадобится функция wp_scripts(), а для получения всех подключенных стилей можно использовать функцию wp_styles(). Установка правильного приоритета также важна, чтобы убедиться, что скрипты выводятся после их регистрации.

Примерно так:

<?php

/*
Название плагина: Мой плагин для вывода списка скриптов и стилей
*/


add_action( 'wp_enqueue_scripts', 'my_plugin_print_styles',  PHP_INT_MAX );

function my_plugin_print_styles(){
    $wp_scripts = wp_scripts();
    $wp_styles = wp_styles();
    var_dump($wp_scripts);
    var_dump($wp_styles);
}
30 сент. 2021 г. 19:14:30