Aggiungere Icone Font-Awesome al Widget Categorie in Modo Programmato
Utilizzo il widget Categorie nella mia sidebar e vorrei mostrare un'icona Font Awesome accanto a ogni categoria elencata nel widget. Per ora l'icona sarebbe la stessa per tutte le categorie, ma in futuro vorrei assegnare a ogni categoria un'icona unica.
Vorrei modificare il widget Categorie utilizzando del codice nel mio file functions.php per aggiungere l'icona inserendo un markup come <i class="fa fa-chevron-right"></i>
nell'elemento link/ancora della categoria dopo il titolo della categoria. Potrei farlo via CSS, ma in questo modo perderei la possibilità di determinare programmaticamente quale icona mostrare, insieme alla flessibilità per altri miglioramenti/modifiche che potrei voler apportare in futuro.
In sostanza, voglio ottenere questo effetto:
Cat 1 > Cat 2 > Cat 3 >
(Il simbolo di maggiore '>' rappresenta il posizionamento dell'icona rispetto al titolo della categoria)
Ho incluso Font Awesome nel file functions.php usando l'hook wp_enqueue_scripts
come segue, e carica e mostra le icone perfettamente. Nota che non utilizzo nessun plugin Font Awesome costruito per WordPress.
/* Includi Scripts
-----------------------------------------------------------------*/
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');
}
Nonostante le mie ricerche, non sono riuscito a trovare una soluzione per modificare il widget delle categorie.
Presupposti:
Non spieghi come intendi installare il pacchetto Font Awesome, quindi per il momento assumo che tu stia utilizzando il plugin Font Awesome Icons.
Hai scritto:
Prima che qualcuno dica di usare un'immagine di sfondo, non voglio farlo. Preferirei che fosse fisico.
quindi presumo che tu voglia utilizzare direttamente il tag <i>
, ad esempio:
<i class="fa icon-caret-right"></i>
dopo ogni link di categoria nell'elenco delle categorie del widget.
Idea:
Puoi utilizzare il filtro wp_list_categories
per modificare l'output dell'elenco delle categorie del widget.
Esempio:
Ecco un semplice esempio di come iniettarlo nell'elenco delle categorie tramite il filtro wp_list_categories
:
/**
* Inietta il tag Font Awesome <i> dopo ogni link della categoria del widget
*
* @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' );
});
Questo ti darà un output simile a questo:

Ottimo pezzo di codice, lo controllerò quando tornerò tra poco. Pubblicherò i risultati.

ricorda solo di adattare il nome della classe alle tue esigenze ;-) Ho usato icon-caret-right
perché è la regola di denominazione delle classi secondo il plugin. In altri casi potrebbe essere fa-caret-right
.

return str_ireplace( '</li>', '<i class="fa fa-chevron-right"></i></li>', $output);
ha funzionato, ma return str_ireplace( '</a></li>', '<i class="fa fa-chevron-right"></i></a></li>', $output);
no.

ok, vuoi aggiungerlo all'interno del tag <a></a>
, allora prova questo: return preg_replace( '/<\/a>\s*<\/li>/i', ' <i class="fa fa-chevron-right"></i></a></li>', $output );

Ok, ora sono perso sulla nuova parte... come funziona esattamente? Capisco l'ultima parte, ma non la prima.

Non voterò negativamente una soluzione legittima/tentativo di aiutare l'OP, ma davvero: usare la sostituzione di stringhe PHP quando una semplice regola CSS sarebbe sufficiente sembra eccessivo.

Mi dispiace di non essere stato più specifico nella mia 'Domanda' originale, ma questo non sarà limitato a qualcosa di piccolo come inserire l'icona. In futuro sarà ampliato, e il CSS non ha soddisfatto le mie esigenze, ecco perché ho postato qui ;).

@MrJustin grazie per il voto, sono anche impressionato dalle risposte ingegnose fornite dagli altri utenti. ps: \s*
corrisponde a qualsiasi carattere di spazio vuoto, come spazio, tabulazione e nuova riga.

@MrJustin potresti per favore ampliare la tua domanda per dettagliare queste "esigenze future" per cui il CSS è insufficiente? Nella forma attuale la tua domanda riguarda specificamente il CSS e non è legata a WordPress, e quindi si trova su un terreno instabile per essere chiusa come fuori tema.

Potrei anche aggiungere che un filtro WordPress fosse eccessivo data la portata della domanda di MrJustin. Difficilmente penso che indirizzarlo verso le espressioni regolari sia una buona idea... Non posso fare a meno di sentire che le espressioni regolari siano agli antipodi rispetto alla semplicità di un'implementazione CSS statica. Temo per ogni futuro WPSEpediano che venga qui cercando di visualizzare un singolo carattere da un font-icona e finisca con un blocco di espressioni regolari nel backend. Abbiate pietà dei n00bs!

si potrebbe anche usare: return str_ireplace( '</a>', ' <i class="fa fa-chevron-right"></i></a>', $output);

Questa risposta contiene una soluzione CSS abbastanza semplice.
In sostanza, dovresti aggiungere quanto segue al tuo foglio di stile:
.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');
}
ecc.
Sì, non è una soluzione molto dinamica, ma suppongo che le tue categorie non cambieranno facilmente.

Il fatto che la risposta sia CSS puro indica che la domanda sottostante sia fuori tema per WPSE. Detto questo: penso che i tuoi selettori CSS non abbiano una sintassi corretta. Dovresti usare .cat-item.cat-item-7
- oppure, dato che si intende usare la stessa icona font per tutti gli elementi della lista, puoi usare semplicemente .cat-item
. Inoltre: un'icona font utilizzerebbe l'attributo content
e mirerebbe alla pseudo-classe :after
, come ad esempio: .cat-item:after { content: '\f18d'; }
.

Osservazioni giuste. Sì, ho fatto un errore nella sintassi. Siamo sicuri che l'OP voglia la stessa immagine, o una diversa per categoria? (Così avevo capito io). Volevo solo proporre la soluzione più semplice, anche se questo porta la domanda/risposta fuori tema.

Supponendo che tu voglia utilizzare l'icona fa-chevron-right
, devi semplicemente puntare l'elemento della lista tramite CSS. Usa la pseudo-classe :after
:
.list-item:after {
font-family: FontAwesome; // o qualunque sia il nome della famiglia FontAwesome registrata
content: '\f054';
}
Modifica
Quindi, per dare un'idea su come potresti passare del CSS dinamico (che può essere facilmente adattato a un'opzione personalizzata del Plugin) tramite un callback, ecco un esempio:
(Nota: "plugin" e "theme" sono intercambiabili qui sotto.)
Per prima cosa, modificheremo il CSS per puntare specificamente agli elementi della lista all'interno di un Widget. WordPress aggiunge una classe, .widget
, al contenitore del Widget. Quindi puoi puntare a quella:
.widget .list-item:after {}
Oppure, se tutto questo sarà racchiuso in un Plugin che registra un Widget personalizzato, allora puoi puntare alla classe CSS che definisci nel tuo Widget personalizzato, tramite l'array $widget_ops
:
$widget_ops = array(
'classname' => 'custom-widget-classname',
'description' => __( 'Descrizione del Widget Personalizzato', 'namespace' )
);
Quindi, puoi puntare a quel nome di classe personalizzato:
.custom-widget-classname .list-item:after {}
Oppure, se vuoi puntare al Widget "Categorie" di base, puoi usare la classe .widget_categories
. Useremo questo approccio per l'esempio.
Lo inseriremo in un callback, agganciato a wp_head
, anche se puoi altrettanto facilmente usare wp_print_styles
:
function pluginslug_fontawesome_styles() {
// Il codice andrà qui
}
add_action( 'wp_head', 'pluginslug_fontawesome_styles' );
All'interno, stamperemo semplicemente un foglio di stile, con la nostra regola di cui sopra:
function pluginslug_fontawesome_styles() {
?>
<script type="text/css">
.widget_categories .list-item:after {
font-family: FontAwesome; // o qualunque sia il nome della famiglia FontAwesome registrata
content: '\f054';
}
</script>
<?php
}
add_action( 'wp_head', 'pluginslug_fontawesome_styles' );
A questo punto, hai finito. Facile facile. Ma, visto che sei già all'interno di una funzione PHP, puoi facilmente rendere questo foglio di stile dinamico, usando una variabile:
function pluginslug_fontawesome_styles() {
// Definisci la variabile per l'icona dello stile della lista
$list_item_icon = '\f054';
// ...snip:
content: <?php echo $list_item_icon; ?>;
Quindi ora, è semplice usare un valore personalizzato delle opzioni del Plugin, semplicemente passandolo alla variabile:
function pluginslug_fontawesome_styles() {
// Ottieni le opzioni del Plugin, assumendo sia un array
$plugin_options = get_option( 'pluginslug_plugin_options' );
// Definisci la variabile per l'icona dello stile della lista
$list_item_icon = $plugin_options['list_item_icon'];
// Stampa il foglio di stile
?>
<script type="text/css">
.widget_categories .list-item:after {
font-family: FontAwesome; // o qualunque sia il nome della famiglia FontAwesome registrata
content: <?php echo $list_item_icon; ?>;
}
</script>
<?php
}
add_action( 'wp_head', 'pluginslug_fontawesome_styles' );
Ecco fatto! CSS dinamico, che stampa un'icona reale (non un'immagine di sfondo), prendendo da un'opzione del Plugin.
E visto che è solo CSS, è facilmente estendibile a praticamente qualsiasi selettore tu possa immaginare - non solo limitato a un elemento della lista all'interno di un Widget.

Sai che puoi racchiudere le regole CSS in una callback e accodarle a wp_head
o wp_print_styles
, vero? Ma quella parte dell'implementazione è una questione separata e al di fuori dell'ambito della domanda così com'è formulata.

Sì, so come accodare. Tuttavia, non voglio usare CSS. So che è un modo rapido ed efficiente per farlo, e ti faccio i complimenti per questo.. ma forse dovrei usare le parole 'ho bisogno di' invece di 'voglio' quando si tratta della funzione.

Per favore vedi la domanda modificata. Ho aggiunto un esempio per mostrare come l'intera cosa possa essere gestita via CSS, in modo dinamico, estensibile e in grado di tenere conto delle opzioni personalizzate del Plugin.

Giusto, ma ora, cosa succederebbe se volessi avere l'icona float a destra? Nel mio CSS normale l'ho collegata a li a:after {content}
e ho provato: text-align: right
ma non ha funzionato. Per chiarire, intendo dire: cosa succederebbe se volessi tutte le icone a destra dell'LI con il testo a sinistra. Diciamo che l'ul/li è impostato a 250px, il testo è sempre un link, ma l'ho impostato a block. Poi ho aggiunto l'icona e volevo che l'icona si posizionasse a destra dell'li. Con il <i...></i> posso facilmente farlo fluttuare.

Per rispondere a quella specifica domanda: invece di li a:after
, usa li a:before
. Ma lo stile/posizionamento degli elementi: oltre a conoscere il markup fornito da WordPress (comprese le classi CSS specifiche e il markup HTML della lista), queste sono domande CSS/HTML. Curiosamente, la risposta che hai contrassegnato come accettata non usa nient'altro che CSS. (Il foglio di stile Font Awesome enqueued che fa uso della classe che aggiungi tramite la sostituzione della stringa usa il pseudo-classe :after
e l'attributo content
per mostrare l'icona.)

Lo farei così:
// Se stai usando il widget solo su pagine specifiche,
// potresti voler aggiungere delle condizioni appropriate qui
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) {
// Definisci l'icona desiderata qui
$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');
// Poiché stiamo intercettando questo filtro, passiamo semplicemente i dati
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');
// Poiché stiamo intercettando questo filtro, passiamo semplicemente i dati
return $output;
} // function wpse_128247_remove_filter
add_filter('wp_list_categories', 'wpse_128247_remove_filter');
Per prima cosa, carichiamo gli stili di Font Awesome. Poi, intercettiamo alcuni filtri per aggiungere/rimuovere il nostro filtro per l'elenco delle categorie. Tutto qui.
// MODIFICA:
Senza i commenti, adattato al fatto che hai già caricato Font Awesome, usando le closure e facendo in modo che il filtro si rimuova da solo, il codice diventa il seguente:
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');
Non la definirei una soluzione eccessiva. Ma sì, il mio codice consiste in più righe rispetto alla soluzione attuale di birgire.

La tua soluzione non era male, ma eccessiva rispetto a quella di birgire. Avevo già incluso Font-Awesome, scusa se non l'ho specificato.

Sì, quel codice non è eccessivo, sono d'accordo. Probabilmente sembrava di più con le 4 funzioni invece di 2, e la quantità di commenti. Apprezzo i commenti, non li sto criticando. Sembrava solo molto di più :).
