Как добавить CSS-опции в мой плагин без использования встроенных стилей?
Я недавно выпустил плагин WP Coda Slider, который использует шорткоды для добавления jQuery слайдера на любую запись или страницу. В следующей версии я добавляю страницу настроек и хотел бы включить некоторые CSS-опции, но не хочу, чтобы плагин добавлял стилевые параметры как встроенный CSS. Я хочу, чтобы выбранные стили динамически добавлялись в CSS-файл при его вызове.
Я также хотел бы избежать использования fopen или записи в файл из-за проблем с безопасностью.
Легко ли это реализовать, или будет лучше просто добавить стилевые параметры непосредственно на страницу?

Используйте wp_register_style
и wp_enqueue_style
для добавления таблицы стилей. НЕ добавляйте просто ссылку на таблицу стилей в wp_head
. Очередь стилей позволяет другим плагинам или темам при необходимости изменять таблицу стилей.
Ваша таблица стилей может быть файлом .php:
wp_register_style('myStyleSheet', 'my-stylesheet.php');
wp_enqueue_style( 'myStyleSheet');
my-stylesheet.php будет выглядеть так:
<?php
// Будем выводить CSS
header('Content-type: text/css');
include('my-plugin-data.php');
?>
body {
background: <?php echo $my_background_variable; ?>;
font-size: <?php echo $my_font_size; ?>;
}

Кроме того - так как значения меняются только при изменении значений на странице настроек - вы можете генерировать CSS файл при сохранении. Вы также можете хранить CSS файлы в директории плагина, что немного производительнее, чем запускать PHP файл при каждом запросе CSS с включениями и т.д.

Спасибо! Работает отлично. Но я получил фатальную ошибку get_option()... is undefined. Затем я загрузил файл wp-config.php и это исправило проблему.

Динамическое создание CSS-файла и его последующая загрузка создают ОГРОМНУЮ нагрузку на производительность, хотя добавление CSS-файла должно быть очень простой операцией с низким потреблением трафика. Особенно если в CSS есть переменные, которые будут обрабатываться через WordPress. Поскольку для одной загрузки страницы создаются два разных файла, WordPress запускается дважды и выполняет все запросы к базе данных дважды, что создаёт большой беспорядок.
Если ваш слайдер будет использоваться только на одной странице и вам нужно динамически задавать стили, то лучшим решением будет добавление блока стилей в заголовок страницы.
По возрастанию влияния на производительность:
- Добавить небольшой блок стилей в заголовок, динамически сгенерированный — Очень быстро
- Добавить статическую таблицу стилей через
wp_enqueue_style
— Средняя скорость - Добавить динамическую таблицу стилей через
wp_enqueue_style
— Очень медленно

@Dan-gayle Очень хорошее замечание. Плагин можно использовать на нескольких страницах, и некоторые пользователи применяют его на 2 или 3 страницах. Он подключает статические таблицы стилей и JS только на страницах, где есть шорткод.

Я согласен с Дэном Гейлом, хотя вы и проголосовали за мой ответ. Добавление небольшого блока CSS в wp_head было бы гораздо лучше с точки зрения производительности, чем необходимость загружать отдельную таблицу стилей при каждом просмотре страницы (даже если ограничиться несколькими записями/страницами со шорткодом). Единственная причина использовать отдельные таблицы стилей — это возможность их кэширования браузером. Динамические таблицы стилей не могут быть закэшированы.

Вот как я обычно это делаю:
function build_stylesheet_url() {
echo '<link rel="stylesheet" href="' . $url . 'stylesheetname.css?build=' . date( "Ymd", strtotime( '-24 days' ) ) . '" type="text/css" media="screen" />';
}
function build_stylesheet_content() {
if( isset( $_GET['build'] ) && addslashes( $_GET['build'] ) == date( "Ymd", strtotime( '-24 days' ) ) ) {
header("Content-type: text/css");
echo "/* Что-то */";
define( 'DONOTCACHEPAGE', 1 ); // не позволить wp-super-cache кешировать эту страницу
die();
}
}
add_action( 'init', 'build_stylesheet_content' );
add_action( 'wp_head', 'build_stylesheet_url' );

У меня были трудности со всеми рекомендациями подобного рода — возможно, я немного туповат, или, может быть, авторы утратили простоту изложения.
Я остановился на таком коде в PHP-файле плагина:
echo "<link href='http://www.brittany-gite-holidays.co.uk/wp-content/plugins/flexavailability/css/css.css' type='text/css' rel='stylesheet' />";
echo "<link href='http://www.brittany-gite-holidays.co.uk/wp-content/plugins/flexavailability/css/public.css' rel='stylesheet' type='text/css'/>";
Кажется, это работает. Стили загружаются только на тех страницах, где используется плагин. Они подгружаются после тега h1, что меня вполне устраивает. Я не вижу, как это можно сделать более эффективно или понятно.
...хотя, возможно, я ошибаюсь — я же говорил, что немного туповат.

Да. Это потому, что ваш CSS должен влиять на все элементы от верха страницы вниз. Мне же нужно, чтобы стили применялись только к тому, что идет после тега h1. Я не смог заставить работать ни один из примеров (думаю, они плохо объяснены). Попробуйте сами на тестовом HTML. Если я ошибаюсь, скажите :)

@chazza Это не единственная причина. Когда браузер обнаруживает стили после открытия тега body, он останавливает все текущие процессы, пока эти стили не загрузятся и не применятся, что плохо сказывается на производительности и приводит к перерисовке экрана и "миганию" нестилизованного текста.
Однако если это не критично, можно просто добавить CSS-файлы, как вы сказали. Я сам так часто делаю, и в конечном итоге все работает. Не оптимально, но работает.

Обновление начиная с WordPress 3.3
Существует функция под названием wp_add_inline_style, которую можно использовать для динамического добавления стилей на основе настроек темы/плагина. Это можно использовать для добавления небольшого CSS-файла в раздел head, что должно быть быстрым и эффективным.
<?php
function myprefix_scripts() {
wp_enqueue_style('name-of-style-css', plugin_dir_path(__FILE__) . '/css/ccsfilename.css');
$css = get_option( 'loader_css', 'значение CSS по умолчанию, если нет установленного значения' );
//или, например
$color = get_option( 'custom_plugin_color', 'red' ); //red - значение по умолчанию, если значение не установлено
$css = ".mycolor{
background: {$color};
}";
wp_add_inline_style('name-of-style-css', $css);
}
add_action( 'wp_enqueue_scripts', 'myprefix_scripts' );
