J'ai un plugin qui est construit avec de nombreux widgets. Un bundle de widget. Chaque widget crée son propre code CSS personnalisé.
Au lieu d'avoir un code source malpropre dans lequel j'affiche 15 ensembles différents de code CSS intégré, j'aimerais transmettre le code CSS généré personnalisé de chaque widget à un fichier CSS personnalisé principal que j'ai créé via WordPress AJAX.
Je vais afficher les fonctions que j'ai configurées pour rendre cela possible.
Le fichier CSS ci-dessous est créé via WordPress AJAX. Cela me permet de placer des instructions CSS personnalisées dans le fichier. Il contient également un filtre dans lequel j'espère pouvoir transmettre le CSS supplémentaire généré par les widgets à cette fonction (fichier).
/**
* Echo the CSS for the custom widgets style
*/
public function advanced_widget_pack_css() {
if(empty($_GET['action']) || $_GET['action'] != 'advanced_widget_pack_gen_css') return;
if(!isset($_GET['ver'])) return;
$css_text = '';
/* ============================= */
/* Archives Widget */
/* ============================= */
$css_text .= ".awp_archives_colour { color:".awp_option('awp_archives_dropdown_inst_colour')." !important }\n";
/**
* Filter for any incoming CSS
*/
$css_text = apply_filters('advanced_widget_pack_css', $css_text);
header("Content-type: text/css");
echo $css_text;
exit();
}
Le code ci-dessous est un extrait d'un des nombreux widgets utilisés dans le plugin. Le widget crée un code CSS personnalisé et le stocke dans la variable $sc_css
. Ce que je veux faire ici est de transmettre le contenu de la variable $sc_css
ou d’ajouter le contenu à la fonction advanced_widget_pack_css()
que j’avais créée précédemment.
class Advanced_Widget_Pack_Widget_Archives extends WP_Widget {
public function __construct(){
// This filter hooks the custom genrated css code to the advanced_widget_pack_css function
add_filter('advanced_widget_pack_css', array(&$this,'awp_pass_css_code'));
}
public function form($instance) {}
public function widget($args, $instance){
extract($args);
// All the widget code is contained here....
// Styling for the shortcode
if($is_awp_sc == 'true'){
/* Generate unique id if shortcode - used for styling */
$sc_id = mt_Rand(1, 100000);
$sc_css = ".awp_archive_widget_sc".$sc_id." { border:".$awp_archives_border_width.' '.$awp_archives_border_style.' '.$awp_archives_border_color." !important }\n";
$sc_css .= $awp_archives_border_radius == 'round' ? '.awp_archive_widget_sc'.$sc_id.' { -moz-border-radius:5px; -webkit-border-radius:5px; border-radius:5px }' : ''.''." \n";
$sc_css .= ".awp_archive_widget_sc".$sc_id." li a, .awp_archive_widget_sc".$sc_id." li { font-size:".$awp_archives_font_size." !important }\n";
$sc_css .= ".awp_archive_widget_sc".$sc_id." li a { color:".$awp_archives_link_std." !important }\n";
$sc_css .= ".awp_archive_widget_sc".$sc_id." li a:hover { color:".$awp_archives_link_hover." !important }\n";
// This should pass the variable
echo $this->awp_pass_css_code($sc_css);
}
// The widget code gets outputted here
}
// This function is created to pass the content of the variable $sc_css to the advanced_widget_pack_css function
function awp_pass_css_code( $sc_css ) {
return $sc_css;
}
}
J'ai essayé d'y parvenir en transmettant le contenu de la variable $sc_css
à une fonction du widget, puis en l'accrochant à la fonction advanced_widget_pack_css()
via un filtre WordPress.
Le problème qui se pose est que le contenu de la variable est toujours vide lorsque vous les transmettez à la feuille de style générée AJAX.
Tout d’abord, je peux dire pourquoi votre code ne fonctionne pas.
Le css personnalisé est créé dans la fonction widget
appelée par WordPress au moment où le widget est affiché.
Je suppose que vous êtes prêt à envoyer une demande ajax pour appeler la fonction advanced_widget_pack_css()
sur le document prêt. Mais chaque demande ajax est une toute nouvelle requête http indiquant que la seule portée exécute une fonction, certainement pas un widget incorporé.
Pour cette raison, la nouvelle requête via ajax n’appelle jamais la méthode widget()
dans votre classe de widgets et, bien entendu, aucun css n’est ajouté.
Dit ça, réfléchis une minute à ce que tu fais.
En supposant que votre flux de travail fonctionne, il échouera si aucun utilisateur n'a activé js. Et même si les js sont activés, la page est chargée avec votre css personnalisé, elle devrait être chargée sur une requête ajax (et Ajax dans WordPress ne sont pas très rapides ...) alors:
Donc, votre code ne fonctionne pas (je vous ai expliqué pourquoi) mais même si vous trouvez un moyen de le faire fonctionner, ce n’est pas une bonne solution.
Que peut être une solution?
Tout d'abord dans le widget , isolez la fonction qui génère le css personnalisé.
Après cela, vous devez appeler la fonction non pas sur la méthode widget()
mais sur la méthode update
. De cette façon, le css est généré à chaque fois que le widget est mis à jour et vous pouvez enregistrer le css nouvellement généré pour le stocker dans un fichier css .
Il est préférable de sauvegarder ce fichier dans le dossier uploads, car vous êtes certain que ce dossier est accessible en écriture depuis WP.
Pseudo code:
class Advanced_Widget_Pack_Widget_Archives extends WP_Widget {
function generate_css( $instance ) {
// some code here to generate css from instance arguments...
return $sc_css;
}
function update( $new_instance, $old_instance ) {
// some code here to update the widget instance...
$css = $this->generate_css( $new_instance );
$upload_dir = wp_upload_dir();
$path = $upload_dir['basedir'] . '/myplugin/myplugin-customwidget.css';
if ( ! file_exists($upload_dir['basedir'] . '/myplugin') )
mkdir($upload_dir['basedir'] . '/myplugin');
file_put_contents($path, $css);
}
}
Ensuite, vous pouvez mettre en file d'attente le fichier que vous venez de créer à l'aide de la méthode standard de WordPress ...
Une alternative à cette méthode est de générer le css dans la méthode widget()
(comme vous le faites déjà) et de ne générer que le style en ligne dans le balisage.
Une solution rapide pour vous est de stocker toutes vos données CSS générées dans un tableau sérialisé dans la base de données WordPress, et de les obtenir/définir avec get_option/set_option