Case:
I got a set of classes that build form fields based on data from an input array. The class can build the following types of form fields:
- input (basic, hidden, password)
- textarea
- radio
- checkbox
- select
- colorpicker
- datepicker
- file upload
EDIT: The class uses wp_register_script/_style
& wp_enqueue_script/_style
to load the scripts & styles. The functions containing the actions are hooked inside the class like this: add_action( 'admin_enqueue_scripts', array( &$this, 'enqueue' ) );
.
Example:
(Inside functions.php
)
// meta box callback function
function test_meta_box_cb()
{
$input_args = array(
'type' => 'color'
,'id' => 'color-id'
,'label' => 'Input Colorpicker Label'
,'opt_name' => 'abc_xyz'
,'value' => '009ee0'
);
new FormClass( $input_args, true );
}
// add the meta box
function add_test_meta_box()
{
add_meta_box( 'test_box', __('TestBox'), 'test_meta_box_cb', 'post', 'advanced', 'high' );
}
add_action( 'add_meta_boxes', 'add_test_meta_box' );
Problem:
This way, my call for wp_enqueue_script
& wp_enqueue_style
doesn’t work. I get the form fields rendered, but no scripts or styles.
Situation & Backtracing of the problem:
So far I could track down the problem to the wordpress core architecture:
- WP doesn’t question what happens inside the callback function until
do_action('add_meta_boxes', $post_type, $post)
get’s called (inside edit-form-advanced.php). - That call happens long after admin-header.php was called (which contains
do_action('admin_enqueue_scripts', $hook_suffix);
). - Therefore the script & style can’t get loaded (if I’m not wrong).
Question:
- How could i load styles before the meta box form fields get called?
- How could i avoid repeating the same stylesheet over and over again – i want to use
wp_enqueue_style
&wp_register_style
?
I’m open to any answers including those who force me to rewrite my class architecture.
Note: I need to use this class in a lot of different szenarios, so bundling it to close together with the add_meta_box
function is not good. I’m close to making an abstraction layer that divides the call for the meta box and the style/script part, but why would I want to add another layer above a core function?
Your problem is adding the scripts, styles inside the class, and because the class instance is created when the hook
add_meta_box
is fired, at that time thewp_enqueue_script/style
are already finished.A solution for you is adding the scripts, styles outside the function and the class. And because meta boxes are used only at editing pages, you can do as the following:
Actually, I wrote a meta box class for WP, that uses another approach. Instead of writing form class for form fields like you did, my class is a wrapper for meta boxes. If you interested in, it’s worth to take a look.
You should really hook you scripts to the
wp_enqueue_scripts
action and your styles to thewp_print_styles
action. Inside your functions, do a check to make sure you’re on the page using your meta boxes before actually usingwp_enqueue_script()
orwp_enqueue_style()
.For example, in one of my plugins I have:
And I hook that to
init
(which fires just before all the other scripts and styles are enqueued).In current form your code dumbs down object to kind of function call (get created, do something, die). Such usage won’t do if you want object to do something long before that object is created and destroyed.
Instead of creating object inside of metabox content I’d do following: