I have a plugin that is built with many widgets. A widget’s bundle. Each widget creates it’s own custom CSS code.
Instead of having messy source code where I display 15 different sets of inline CSS code I would like to pass the custom generated CSS code from each widget to a main custom CSS file that I created through WordPress AJAX.
I will display the functions that I have setup to make this possible.
The AJAX created CSS file
The below CSS file is created through WordPress AJAX. It allows me to place custom CSS statements in the file. It also contains a filter where I am hoping to pass the extra generated CSS from the widgets to this function (file).
/**
* 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();
}
One of the widget classes with custom genrated CSS code
The below code is a snippet of one of the many widgets used within the plugin. The widget creates custom CSS code and stores it in the variable $sc_css
. What I want to do from here is pass the contents of the variable $sc_css
or append the contents to the function advanced_widget_pack_css()
which I created earlier.
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;
}
}
The issues
I tried to achieve this by passing the contents of the $sc_css
variable to a function within the widget and then hooking it to the function advanced_widget_pack_css()
through a WordPress filter.
The problem that occurs is that the contents of the variable are always blank when passing them to the AJAX generated stylesheet.
First of all I can say why your code doesn’t work.
The custom css is created inside the
widget
function that is called by WordPress in the moment that the widget is displayed.I guess, that you on document ready send an ajax request that call
advanced_widget_pack_css()
function. But every ajax request is a completely new http request that the only scope is running a function, sure not embed widget.For this reason, the new request via ajax never call the
widget()
method in your widget class and so of course no css are added.Said that, think one minute for what you are doing.
Assuming your workflow will work, it fail if user has no js enabled. And even if the the js are enabled, the page is loaded withou custom css, that should be loaded on ajax request (and Ajax in WordPress are not very fast…) so:
second or more
So your code does’t work (an I explained yopu why) but even if you find a way to make it works is not a great solution.
What can be a solution?
First of all in the widget isolate the function that generates the custom css.
After that, you should call the function not on the
widget()
method but on theupdate
method. In this way the css is generated everytime the widget is updated, and you can save the newly generated css to store it in a css file.As a good practise is better saving this file in the uploads folder, because you are sure that folder is writable from WP.
Pseudo code:
After that, you can enqueue the file just created using WordPress standard way…
Alternative to this method is generate the css in the
widget()
method (as you are already doing) and just output as inline style in the markup.A quick solution for you is to store all your generated css data in a serialized array into the WordPress database, and get it/set it with
get_option/set_option