Программное добавление иконок Font-Awesome к виджету категорий

1 янв. 2014 г., 22:22:10
Просмотры: 14.2K
Голосов: 1

Я использую виджет "Категории" в сайдбаре(ах) и хотел бы отображать иконку Font Awesome рядом с каждой категорией в виджете. Пока иконка будет одинаковой для всех категорий, но в будущем я хочу назначить каждой категории свою уникальную иконку.

Я хочу модифицировать виджет "Категории" с помощью кода в файле functions.php, добавив иконку путем вставки разметки типа <i class="fa fa-chevron-right"></i> в элемент ссылки/якоря категории после названия категории. Я мог бы сделать это через CSS, но тогда потеряю возможность программно определять, какую иконку отображать, а также гибкость для других улучшений/изменений, которые я могу захотеть сделать в будущем.


По сути, я хочу добиться такого эффекта:

Кат 1          >

Кат 2          >

Кат 3          >

(Символ '>' обозначает расположение иконки относительно названия категории)


Я подключил Font Awesome в файле functions.php с помощью хука wp_enqueue_scripts следующим образом, и он загружается и отображает иконки идеально. Обратите внимание, что я не использую никаких плагинов Font Awesome для WordPress.

/* Подключение скриптов
-----------------------------------------------------------------*/
add_action( 'wp_enqueue_scripts', 'essentials_enqueue_scripts' );
function essentials_enqueue_scripts() {
    /* jQuery */
    wp_enqueue_script('jquery');
    wp_enqueue_script( 'jquery_ui', "http" . ($_SERVER['SERVER_PORT'] == 443 ? "s" : "") . "://ajax.googleapis.com/ajax/libs/jqueryui/2.0.3/jquery-ui.min.js", false, null);
    wp_enqueue_script( 'waypoints', get_template_directory_uri() . '/js/waypoints.min.js');
    wp_enqueue_script( 'essentials_main', get_template_directory_uri() . '/js/essentials_main.js', array(), '1.0.0', true );
    wp_enqueue_script( 'essentials_show_stuff', get_template_directory_uri() . '/js/essentials_show_stuff.js', array(), '1.0.0', true );
    /* Google Fonts */
    wp_register_style('GoogleFonts','http://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700,800|Bad+Script');
    wp_enqueue_style( 'GoogleFonts');
    /* Font Awesome Fonts */
    wp_register_style('Font Awesome','//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css');
    wp_enqueue_style( 'Font Awesome'); 
}

Несмотря на все мои усилия в поисках решения, мне не удалось найти способ модификации виджета категорий.

16
Комментарии

Пожалуйста, уточните ваш вопрос, объяснив, чем он специфичен для WordPress, а не просто относится к CSS. Также, пожалуйста, отредактируйте вопрос, добавив информацию о том, что вы уже сделали/попробовали. Как вы подключаете/добавляете шрифт FontAwesome?

Chip Bennett Chip Bennett
4 янв. 2014 г. 16:05:42

Добавлено редактирование для ответа на ваши вопросы.

MrJustin MrJustin
6 янв. 2014 г. 22:52:00

"Это специфично для WordPress, потому что я хочу настроить категории WordPress через файл FUNCTIONS.PHP" - учитывая, что окончательное решение всё равно полностью основано на CSS, вопрос всё ещё не является специфичным для WordPress. Он просто возникает в контексте WordPress. Ваше ограничение, заключающееся в желании добавить функцию в functions.php, которое исключает наиболее правдоподобные ответы, также делает этот вопрос слишком узконаправленным. Возможно, если бы вы отредактировали вопрос, сосредоточившись на том, как добавить пользовательский CSS, он был бы уместен для WPSE?

Chip Bennett Chip Bennett
6 янв. 2014 г. 23:04:04

Еще раз, мне не нужно решение на CSS. Мои ограничения также расширяют будущие возможности для этой задачи. Мне нравятся иконки, и другим они тоже могут понравиться. В будущем я, возможно, создам страницу настроек для себя, чтобы добавлять КОНКРЕТНЫЕ иконки, а не просто одну. У меня абсолютно нет намерения использовать CSS для этого, я не хотел background-image, и я действительно похвалил кого-то за использование :after {content}, но опять же, это не то, что мне нужно. Это КОНКРЕТНО для WordPress, я знаю, как сделать это в CSS и как сделать в HTML. Я не знал, как сделать это в WordPress, редактируя виджет через пользовательскую функцию.

MrJustin MrJustin
6 янв. 2014 г. 23:15:03

Атрибут CSS content не является фоновым изображением, это контент. И решение на CSS — это лучший способ реализации, даже если вы хотите предоставить конечному пользователю настройки. Я пытаюсь вам показать, что ваши ненужные и произвольные ограничения делают задачу излишне сложной.

Chip Bennett Chip Bennett
7 янв. 2014 г. 02:53:27

Как отмечает @Chip, ваш вопрос в текущей формулировке строго касается реализации на CSS — вы совершенно явно спрашиваете, как отобразить один символ из шрифта с иконками. Это достигается путем размещения этого символа в HTML и применения шрифта к символу (или контейнеру) с помощью CSS. Ни одна часть этого процесса не имеет отношения к WordPress. В вашем вопросе нигде не сказано, что вы хотите добавить этот символ, изменяя вывод WordPress. Делать так — избыточно и, скорее всего, не нужно, если ваш вопрос точен.

bosco bosco
7 янв. 2014 г. 04:38:47

Развивая мой предыдущий комментарий, ответ birgire, который вы приняли ниже, является реализацией на CSS — единственное отличие в том, что он добавляет стилизованный CSS-элемент с использованием PHP и регулярных выражений, вместо того чтобы просто вставить его напрямую в разметку вашего шаблона. Это создаёт избыточную нагрузку на ресурсы для загрузки и выполнения PHP-кода, в чём нет абсолютно никакой необходимости. Пожалуйста, переформулируйте ваш вопрос, чтобы было ясно, что вы хотите добавить этот символ программно и на стороне сервера, если это действительно так. Также было бы очень полезно, если бы вы указали, почему у вас такие требования.

bosco bosco
7 янв. 2014 г. 05:04:20

Не хочу вас отталкивать или что-то в этом роде — просто пытаюсь помочь вам лучше сформулировать вопрос и привести его в соответствие с стандартами нашего сообщества. Вам стоит убрать фразу "Я действительно не хочу изобретать велосипед, поэтому было бы здорово, если бы я мог просто вставить что-то в файл functions.php моей темы" и добавить информацию о том, что вы уже пробовали сделать. В текущем виде ваш вопрос очень явно просит сообщество просто дать вам код без демонстрации ваших собственных усилий, что противоречит нашим стандартам. Пожалуйста, ознакомьтесь с [ask] для получения дополнительной информации о наших стандартах.

bosco bosco
7 янв. 2014 г. 05:13:03

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

MrJustin MrJustin
7 янв. 2014 г. 16:04:24

"Мне не очень хочется добавлять 25 строк кода в CSS, чтобы отображать разные иконки." — настоящая проблема в том, что это делает ваш вопрос слишком узкоспециализированным, потому что вы исключаете самое лучшее и очевидное решение: CSS. Я просто не могу понять, почему 25 строк CSS менее предпочтительны, чем несколько фильтров и 50 строк PHP-кода для замены строк.

Chip Bennett Chip Bennett
7 янв. 2014 г. 16:54:57

Ну что ж, возможно, CSS-решение очевидно для вас. Для меня оно неочевидно, я смотрю на это в другом масштабе, поэтому моя интерпретация шагов для достижения цели будет отличаться. Так что, если бы вопрос не был узкоспециализированным, он бы не относился к WordPress Specific. У меня проблема, которая касается меня, она может не касаться вас, но не каждая проблема должна быть универсальной. Я пришёл сюда за решением для WordPress, и я его получил. Не понимаю, почему мы до сих пор спорим о том, на что уже дан ответ. Я удовлетворён ответом... оставьте всё как есть.

MrJustin MrJustin
7 янв. 2014 г. 17:33:07

"Не понимаю, почему мы до сих пор спорим о том, на что уже дан ответ." — потому что сайты Stack Exchange — это не форумы поддержки, а сайты вопросов и ответов, предназначенные для создания базы знаний общего/универсального применения. Ваше произвольное ограничение делает вопрос бесполезным для широкой аудитории, поэтому он считается слишком узкоспециализированным. И хотя вы вольны принять любой ответ, который лично вам подходит, принятый ответ, откровенно говоря, ужасен для подавляющего большинства людей, которым нужно использовать иконки в виде шрифтов.

Chip Bennett Chip Bennett
7 янв. 2014 г. 18:35:20

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

MrJustin MrJustin
7 янв. 2014 г. 18:54:46

@MrJustin, я считаю, что ваши правки не только сделали ваш вопрос соответствующим теме, но и добавили необходимые ограничения, которые сделали выбор решения без CSS логичным. Я изменил свой минус на плюс. Я очень ценю ваше терпение во всём этом и готовность дорабатывать вопрос для пользы нашего сообщества!

bosco bosco
9 янв. 2014 г. 01:55:30

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

bosco bosco
9 янв. 2014 г. 03:08:00

@bosco Я ценю вашу правку, и хотя я не принял её, я считаю её более чем удовлетворительной. Спасибо за плюс. У меня действительно не было намерения и не нравится спорить. Я рад, что мы смогли прийти к разумному решению. Я приложу больше усилий при формулировке своих вопросов, чтобы точнее описать, что именно я пытаюсь сделать. Ещё раз большое спасибо.

MrJustin MrJustin
9 янв. 2014 г. 03:32:13
Показать остальные 11 комментариев
Все ответы на вопрос 4
12

Предположения:

Вы не объясняете, как именно хотите установить пакет Font Awesome, поэтому я предполагаю, что вы используете плагин Font Awesome Icons.

Вы написали:

Прежде чем кто-то предложит использовать фоновое изображение, я не хочу этого делать. Мне нужно физическое отображение.

поэтому я предполагаю, что вы хотите использовать тег <i> напрямую, например:

<i class="fa icon-caret-right"></i>

после каждой ссылки на категорию в виджете списка категорий.

Идея:

Вы можете использовать фильтр wp_list_categories для изменения вывода виджета списка категорий.

Пример:

Вот простой пример, как вставить его в список категорий через фильтр wp_list_categories:

/**
 * Добавляет тег Font Awesome <i> после каждой ссылки в виджете категорий
 *
 * @param string $output
 * @return string $output
 */

 function custom_wp_list_categories( $output )
 {  
     remove_filter( current_filter(), __FUNCTION__ ); 
     return str_ireplace( '</li>', '<i class="fa icon-caret-right"></i></li>', $output);
 }

 add_action( 'widgets_init', function(){
     add_filter( 'wp_list_categories', 'custom_wp_list_categories' );
 });

Это даст вам вывод, похожий на этот:

Список категорий с иконками Font Awesome

4 янв. 2014 г. 16:03:57
Комментарии

Отличный фрагмент кода, я проверю его, когда вернусь чуть позже. Я опубликую результаты.

MrJustin MrJustin
5 янв. 2014 г. 01:36:13

Просто не забудьте изменить имя класса в соответствии с вашими потребностями ;-) Я использовал icon-caret-right, потому что это правило именования классов согласно плагину. В других случаях это может быть fa-caret-right.

birgire birgire
5 янв. 2014 г. 01:42:33

return str_ireplace( '</li>', '<i class="fa fa-chevron-right"></i></li>', $output); сработало, а return str_ireplace( '</a></li>', '<i class="fa fa-chevron-right"></i></a></li>', $output); — нет.

MrJustin MrJustin
5 янв. 2014 г. 11:31:42

хорошо, вы хотите добавить это внутри тега <a></a>, тогда попробуйте это: return preg_replace( '/<\/a>\s*<\/li>/i', ' <i class="fa fa-chevron-right"></i></a></li>', $output );

birgire birgire
5 янв. 2014 г. 14:22:45

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

MrJustin MrJustin
6 янв. 2014 г. 22:33:44

Не буду ставить минус за законное решение/попытку помочь автору вопроса, но честно: использование замены строк в PHP, когда простое CSS-правило справилось бы, кажется излишним.

Chip Bennett Chip Bennett
6 янв. 2014 г. 23:05:12

Извините, что не был более конкретным в моем исходном 'Вопросе', но это не ограничится чем-то настолько малым, как просто добавление иконки. В будущем это будет расширено, и CSS не удовлетворил мои потребности, поэтому я и разместил вопрос здесь ;).

MrJustin MrJustin
6 янв. 2014 г. 23:17:22

@MrJustin спасибо за голосование, я также впечатлен гениальными ответами, предоставленными другими пользователями. PS: \s* соответствует любому пробельному символу, такому как пробел, табуляция и новая строка.

birgire birgire
7 янв. 2014 г. 00:53:12

@MrJustin не могли бы вы, пожалуйста, расширить ваш вопрос, детализировав эти "будущие потребности", для которых CSS недостаточен? В текущем виде ваш вопрос касается исключительно CSS и не связан с WordPress, поэтому находится на шаткой почве для закрытия как не по теме.

bosco bosco
7 янв. 2014 г. 04:43:14

Я также могу добавить, что фильтр WordPress был избыточным, учитывая масштаб вопроса MrJustin. Вряд ли стоит направлять его к регулярным выражениям... Не могу избавиться от ощущения, что регулярные выражения находятся на противоположном полюсе от простоты статической CSS-реализации. Я переживаю за любого будущего посетителя WPSE, который придет сюда, чтобы отобразить один символ из шрифта иконок, а в итоге получит кучу регулярных выражений в своем бэкенде. Пощадите новичков!

bosco bosco
7 янв. 2014 г. 04:47:57

также можно использовать: return str_ireplace( '</a>', ' <i class="fa fa-chevron-right"></i></a>', $output);

birgire birgire
7 янв. 2014 г. 07:40:53

@birgire, благодарю за это дополнение!

bosco bosco
9 янв. 2014 г. 01:48:11
Показать остальные 7 комментариев
3

Этот ответ содержит довольно простое CSS-решение.

По сути, вам нужно добавить следующее в вашу таблицу стилей:

.cat-item cat-item-7 {
     list-style-image: url('my-epic-news-icon');
}


cat-item cat-item-11 {
     list-style-image: url('my-epic-jquery-icon');
}

и так далее

Да, это не самое динамичное решение, но ваши категории, вероятно, не будут часто меняться.

4 янв. 2014 г. 14:49:26
Комментарии

То, что ответ предполагает использование чистого CSS, говорит о том, что исходный вопрос не соответствует тематике WPSE. Тем не менее: я думаю, что в ваших CSS-селекторах неправильный синтаксис. Вам следует использовать .cat-item.cat-item-7 — или, поскольку предполагается использование одного и того же иконки-шрифта для всех элементов списка, просто .cat-item. Кроме того: иконка-шрифт использует атрибут content и применяется к псевдоклассу :after, например: .cat-item:after { content: '\f18d'; }.

Chip Bennett Chip Bennett
4 янв. 2014 г. 16:25:33

Справедливые замечания. Да, я допустил ошибку в синтаксисе. Мы уверены, что автор вопроса хочет одну и ту же иконку, а не разные для каждой категории? (Я понял вопрос именно так). Я просто хотел предложить самое простое решение, хотя это действительно выводит вопрос/ответ за рамки тематики.

JMB JMB
4 янв. 2014 г. 16:32:51

Это не то решение, которое я искал, так как я уже говорил, что не хочу использовать background и что мне нужно, чтобы иконка была после текста. Хотя это может и не быть background, но это всё равно изображение, а не Font Awesome. Хорошее решение, но не подходящее для меня.

MrJustin MrJustin
5 янв. 2014 г. 01:35:53
6

Предположим, вы хотите использовать иконку fa-chevron-right, вам просто нужно стилизовать элемент списка через CSS. Используйте псевдокласс :after:

.list-item:after {
    font-family: FontAwesome; // или другое имя шрифта FontAwesome, если оно было изменено
    content: '\f054';
}

Редактирование

Чтобы показать, как можно передавать динамический CSS (который легко адаптируется под настройки плагина) через callback, вот пример:

(Примечание: термины "плагин" и "тема" взаимозаменяемы ниже.)

Сначала модифицируем CSS, чтобы стилизовать элементы списка внутри виджета. WordPress добавляет класс .widget к контейнеру виджета. Можно использовать его:

.widget .list-item:after {}

Или, если это будет частью плагина, который регистрирует пользовательский виджет, можно использовать CSS-класс, определённый в вашем виджете через массив $widget_ops:

$widget_ops = array( 
    'classname' => 'custom-widget-classname', 
    'description' => __( 'Описание пользовательского виджета', 'namespace' ) 
);

Теперь можно стилизовать по этому классу:

.custom-widget-classname .list-item:after {}

Если нужно стилизовать стандартный виджет "Категории", используйте класс .widget_categories. Для примера воспользуемся этим подходом.

Поместим стили в callback, подключённый к wp_head, хотя можно также использовать wp_print_styles:

function pluginslug_fontawesome_styles() {
    // Код будет здесь
}
add_action( 'wp_head', 'pluginslug_fontawesome_styles' );

Внутри просто выведем стили с нашим правилом:

function pluginslug_fontawesome_styles() {
    ?>
<script type="text/css">
.widget_categories .list-item:after {
    font-family: FontAwesome; // или другое имя шрифта FontAwesome, если оно было изменено
    content: '\f054';
}
</script>
    <?php
}
add_action( 'wp_head', 'pluginslug_fontawesome_styles' );

На этом всё. Но, раз мы уже внутри PHP-функции, можно легко сделать эти стили динамическими, используя переменную:

function pluginslug_fontawesome_styles() {

    // Определяем переменную для иконки списка
    $list_item_icon = '\f054';

    // ...пропуск:
    content: <?php echo $list_item_icon; ?>;

Теперь можно использовать значение из настроек плагина, просто передав его в переменную:

function pluginslug_fontawesome_styles() {

    // Получаем настройки плагина (предполагается, что это массив)
    $plugin_options = get_option( 'pluginslug_plugin_options' );

    // Определяем переменную для иконки списка
    $list_item_icon = $plugin_options['list_item_icon'];

    // Выводим стили
    ?>
<script type="text/css">
.widget_categories .list-item:after {
    font-family: FontAwesome; // или другое имя шрифта FontAwesome, если оно было изменено
    content: <?php echo $list_item_icon; ?>;
}
</script>
    <?php
}
add_action( 'wp_head', 'pluginslug_fontawesome_styles' );

Вот и всё! Динамический CSS, выводящий реальную иконку (не фоновое изображение), берущий значение из настроек плагина.

Так как это просто CSS, метод легко расширяется на любые селекторы — не только на элементы списка внутри виджетов.

4 янв. 2014 г. 16:32:31
Комментарии

Очень хороший вариант, но мне нужна была функция. :)

MrJustin MrJustin
6 янв. 2014 г. 22:42:37

Вы знаете, что можно обернуть CSS-правила в колбэк и добавить их через wp_head или wp_print_styles, верно? Но эта часть реализации — отдельный вопрос и выходит за рамки заданного.

Chip Bennett Chip Bennett
6 янв. 2014 г. 23:01:21

Да, я знаю, как добавлять стили. Однако я не хочу использовать CSS. Я понимаю, что это быстрый и эффективный способ, и я действительно ценю ваш подход... но, возможно, мне следовало сказать «мне нужна» вместо «хотелось бы», когда речь идет о функции.

MrJustin MrJustin
6 янв. 2014 г. 23:19:39

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

Chip Bennett Chip Bennett
7 янв. 2014 г. 03:16:16

Хорошо, но что, если я хочу, чтобы иконка всплывала справа? В моем обычном CSS я прикрепил ее к li a:after {content} и попробовал: text-align: right, но это не сработало. Чтобы уточнить, я имею в виду, что если я хочу, чтобы все иконки были справа от LI, а текст — слева. Допустим, ul/li установлен на 250px, текст всегда является ссылкой, но я задал ему display: block. Затем я добавил 'иконку' и хочу, чтобы она располагалась справа от li. С помощью <i...></i> я могу легко сделать это через float.

MrJustin MrJustin
7 янв. 2014 г. 03:30:12

Чтобы ответить на этот конкретный вопрос: вместо li a:after используйте li a:before. Но вопросы стилизации/позиционирования элементов: помимо знания разметки, предоставляемой WordPress (включая конкретные CSS-классы и HTML-разметку списка), это вопросы CSS/HTML. Интересно, что в ответе, который вы отметили как принятый, используется только CSS. (Подключенный таблица стилей Font Awesome, который использует класс, добавленный через замену строки, применяет псевдокласс :after и атрибут content для вывода иконки.)

Chip Bennett Chip Bennett
7 янв. 2014 г. 04:17:25
Показать остальные 1 комментариев
3

Я бы сделал это так:

// Если виджет используется только на определённых страницах,
// здесь можно добавить соответствующие условия
add_action('wp_enqueue_scripts', function() {
    wp_enqueue_style('font-awesome',
        '//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css');
});

function wpse_128247_font_awesome_categories($cat_name) {
    // Определите желаемую иконку здесь
    $icon = ' <i class="fa fa-smile-o"></i>';

    return $cat_name.$icon;
} // function wpse_128247_font_awesome_categories

function wpse_128247_add_filter($cat_args) {
    add_filter('list_cats', 'wpse_128247_font_awesome_categories');

    // Поскольку мы перехватываем этот фильтр, просто передаём его данные дальше
    return $cat_args;
} // function wpse_128247_add_filter
add_filter('widget_categories_args', 'wpse_128247_add_filter');

function wpse_128247_remove_filter($output) {
    remove_filter('list_cats', 'wpse_128247_font_awesome_categories');

    // Поскольку мы перехватываем этот фильтр, просто передаём его данные дальше
    return $output;
} // function wpse_128247_remove_filter
add_filter('wp_list_categories', 'wpse_128247_remove_filter');

Сначала мы подключаем стили Font Awesome. Затем перехватываем некоторые фильтры, чтобы добавить/удалить наш собственный фильтр для списка категорий. Вот и всё.


// РЕДАКТИРОВАНИЕ:
Без комментариев, с учётом того, что Font Awesome уже подключён, используя замыкания и позволяя фильтру удалить себя, код выглядит следующим образом:

function wpse_128247_font_awesome_categories($cat_name) {
    remove_filter(current_filter(), __FUNCTION__);
    return $cat_name.' <i class="fa fa-smile-o"></i>';
} // function wpse_128247_font_awesome_categories

function wpse_128247_add_filter($cat_args) {
    add_filter('list_cats', 'wpse_128247_font_awesome_categories');
    return $cat_args;
} // function wpse_128247_add_filter
add_filter('widget_categories_args', 'wpse_128247_add_filter');

Я бы не назвал это избыточным. Но да, мой код содержит больше строк, чем текущее решение birgire.

4 янв. 2014 г. 16:13:38
Комментарии

Ваше решение было неплохим, но избыточным по сравнению с вариантом birgire. У меня уже подключен Font-Awesome, извините, что не уточнил.

MrJustin MrJustin
6 янв. 2014 г. 22:41:00

Да, этот код нельзя назвать избыточным, я согласен. Возможно, он просто выглядел объемнее из-за 4 функций вместо 2 и количества комментариев. Я ценю комментарии, я не против них. Просто визуально казалось, что кода больше :).

MrJustin MrJustin
7 янв. 2014 г. 03:26:38

Поскольку вы используете remove_filter для функции, добавляющей иконку, она выполнится только один раз. Это означает, что иконка будет добавлена только к первому элементу в списке widget_categories.

WPExplorer WPExplorer
12 мая 2020 г. 09:49:37