it-swarm.xyz

Решения для генерации динамического JavaScript/CSS

Допустим, вам нужно сгенерировать JavaScript или код CSS, который зависит от текущего контекста.

Например, у вас есть форма на главной странице, которая запускает ajax-запрос при отправке, и другая форма на одной странице. Или, в случае с CSS, вы хотите создать тему, которая позволит пользователям создавать собственные макеты, менять цвета и т.д.

Решения, которые я вижу до сих пор:

  1. Включите код в раздел заголовка документа (или в конце в случае JS)

  2. Сделайте специальный запрос, который выводит код, например site.com?get_assets, Это медленно, потому что WP загружается дважды.

  3. Храните его во временных файлах в течение определенного времени и загружайте оттуда. Не очень надежно для публичных тем или плагинов.

  4. Только для Javascript - сделайте его статичным, поместив его в обычный файл, который загружается каждый раз. В этом случае вам придется заставить свой код обрабатывать любую ситуацию

Вы знаете других? По какому пути вы пойдете?

14
onetrickpony

Одна дополнительная опция, в зависимости от типа параметров, которые вам нужно передать. Давайте назовем это (2a). Вы также можете создавать сценарии PHP, которые выводят динамически сгенерированные text/css или text/javascript вместо text/html и предоставлять им необходимые данные, используя параметры GET, а не загружая WordPress. Конечно, это работает, только если вам нужно передать относительно небольшое количество относительно компактных параметров. Так, например, допустим, что вам нужно передать только URL-адрес сообщения или каталог файла или чего-либо подобного, вы можете сделать что-то вроде этого:

В header.php:

 <script type="text/javascript" src="<?php print get_stylesheet_directory_uri(); 
 ?>/fancy-js.php?foo=bar&amp;url=<?php print urlencode(get_permalink($post->ID)); ?>"></script>

В fancy-js.php:

 <?php
 header("Content-type: text/javascript");
 ?>
 foo = <?php print json_encode($_GET['foo']); ?>;
 url = <?php print json_encode($_GET['url']); ?>;

и т.п.

Но это только позволяет вам получить доступ к данным, непосредственно переданным в параметрах GET; и это сработает только в том случае, если количество вещей, которые вам нужно передать, относительно мало, а представление этих вещей относительно компактно. (В основном горстка строковых или числовых значений - имя пользователя, скажем, или каталог; не список всех последних сообщений пользователя или что-то в этом роде.)

Что касается того, какой из этих вариантов является лучшим - я не знаю; это зависит от вашего варианта использования. Вариант (1) имеет преимущество простоты и однозначного предоставления вам доступа к любым данным WordPress, которые вам могут понадобиться, без снижения производительности при двойной загрузке WordPress. Это почти наверняка то, что вы должны делать, если у вас нет веских причин не делать этого (например, из-за размера таблицы стилей или сценария, которые вам нужно использовать).

Если размер становится достаточно большим, чтобы вызвать проблемы с точки зрения веса одной страницы, то вы можете попробовать (2) или (2a).

Или - возможно, это лучшая идея - вы можете попытаться отделить части скрипта или таблицы стилей, которые фактически используют динамические данные, от частей, которые могут быть заданы статически. Скажем, у вас есть таблица стилей, которой нужно передать каталог из WordPress, чтобы установить параметр фона для элемента # my-fancy. Вы можете поместить все это в элемент head:

 <style type="text/css">
 #my-fancy-element {
      background-image: url(<?php print get_stylesheet_directory_uri(); ?>images/fancy.png);
      padding: 20px;
      margin: 20px;
      font-weight: bold;
      text-transform: uppercase;
      font-size: 12pt;
      /* ... KB and KB of additional styles ... */
 }
 #another-fancy-element {
     /* ... KB and KB of additional styles ... */
 }
 /* ... KB and KB of additional styles ... */
 </style>

Но зачем вам это делать? Здесь есть только одна строка, которая зависит от данных из WordPress. Лучше выделить только те строки, которые зависят от WordPress:

 <style type="text/css">
 #my-fancy-element {
      background-image: url(<?php print get_stylesheet_directory_uri(); ?>images/fancy.png);
 }
 </style>

Поместите все остальное в статическую таблицу стилей, в которую вы загружаете стандартный элемент ссылки (style.css или любой другой):

 #my-fancy-element {
      /* background-image provided dynamically */
      padding: 20px;
      margin: 20px;
      font-weight: bold;
      text-transform: uppercase;
      font-size: 12pt;
      /* ... KB and KB of additional styles ... */
 }
 #another-fancy-element {
     /* ... KB and KB of additional styles ... */
 }
 /* ... KB and KB of additional styles ... */

И пусть каскад сделает всю работу.

То же самое касается JavaScript: вместо того, чтобы делать это:

 <script type="text/javascript">
 // Here comes a huge function that uses WordPress data:
 function my_huge_function () {
     // Do a million things ...

     jQuery('#my-fancy').append('<a href="'+<?php json_encode(get_permalink($GLOBALS['post']->ID)); ?>+'">foo</a>);

     // Do a million more things ...

     my_other_function(<?php print json_encode(get_userdata($GLOBALS['post']->post_author); ?>);
 }

 function my_other_function (user) {
     // Do a million things ...
 }
 </script>

Вместо этого поместите что-то вроде этого в элемент head:

 <script type="text/javascript">
 var WordPressPostData = {
 url: <?php print json_encode(get_permalink($GLOBALS['post']->ID)); ?>,
 author: <?php print json_encode(get_userdata($GLOBALS['post']->post_author)); ?>
 }
 </script>

А затем поместите остальные в статический файл JavaScript, переписав my_huge_function () и my_other_function (), чтобы использовать глобальные переменные WordPressPostData.url и WordPressPostData.author.

40 КБ CSS или 40 КБ JS почти всегда можно разбить на <1 КБ, что на самом деле зависит от динамических данных, а остальные - могут быть указаны в статическом внешнем файле и затем рекомбинированы с использованием каскада (для CSS) или глобально доступного переменные (глобальные переменные, элементы DOM или любые другие предпочтительные места для JS).

8
radgeek

Динамический случай CSS довольно прост.

Просто создайте функцию, которая выводит динамические определения CSS внутри тегов <style type="text/css"></style>, а затем подключите эту функцию к wp_print_styles. например.

<?php
function mytheme_dynamic_css() {
    $options = get_option( 'mytheme_options' );
    ?>
    <style type="text/css">
    /* Dynamic H1 font family */
    h1 { font-family: <?php echo $options['h1_font_family']; ?>;
    </style>
    <?php
}
add_action( 'wp_print_styles', 'mytheme_dynamic_css' );
?>

Или, скажем, у вас есть предварительно настроенные цветовые схемы; Вы можете поставить в очередь соответствующую таблицу стилей в соответствии с текущими настройками пользователя:

<?php
function mytheme_enqueue_colorscheme_stylesheet() {
    $options = get_option( 'mytheme_options' );
    $color_scheme = $options['color_scheme'];
    wp_enqueue_style( $colorscheme, get_template_directory_uri() . '/css/' . $color_scheme . '.css' );
}
add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_colorscheme_stylesheet' );
?>

Обратите внимание, что в этом случае функция подключается к wp_enqueue_scripts, так как WordPress не имеет ловушки действия wp_enqueue_styles.

5
Chip Bennett

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

Что если i записать файл javascript/css через php при сохранении данных администратором. Это будет однократная запись, пока пользователь не изменит макет снова (что пользователь может делать не слишком часто). Таким образом, мы получаем доступ к базе данных для пользовательских настроек только один раз, когда пользователь сохраняет данные.

После записи файла это будут обычные файлы javascript/css, поэтому нам не нужно вызывать базу данных каждый раз при загрузке темы.

Один вопрос, на который нужно ответить: Что произойдет, если посетитель попытается получить доступ к сайту в тот момент, когда php пишет файл?

Дайте мне знать, что вы думаете.

2
Sisir

Для небольших фрагментов скриптов, которые вы, возможно, не захотите включать в отдельный файл, например, потому что они генерируются динамически, WordPress 4.5 и другие предложения wp_add_inline_script . Эта функция в основном привязывает скрипт к другому скрипту. Допустим, например, что вы разрабатываете тему и хотите, чтобы ваш клиент мог вставлять свои собственные скрипты (например, Google Analytics или AddThis) через страницу параметров. Пример .

Для стилей есть wp_add_inline_style , который в основном работает так же. Вы могли бы использовать его, например, для циклического прохождения всех ваших модификаторов-модификаторов и собрать их в строку с именем $all_mods, которую затем добавили бы так в свою основную таблицу стилей:

if (!empty($all_mods)) wp_add_inline_style ('main-style', $all_mods);
1
cjbj