Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I am at my first Settings API application and I hit a snag.

In a submenu page, I need to generate a number of fields (say color picker) for each of the values retrieved from another setting.

To be more precise, I created in another menu page a list of category checkboxes:

function bcio_fp_special_cats_display(){
$options = (array)get_option('bcio_options');
$categories = bcio_get_categories();

echo '<ul>';

foreach($categories as $category){
    $selected = ( isset( $options['fp_sp_category_'.$category->cat_ID] ) ) ? $options['fp_sp_category_'.$category->cat_ID] : '';    

    if($selected){  
        echo '<li><input type="checkbox" value="'.$category->cat_ID.'" name="bcio_options[fp_sp_category_'.$category->cat_ID.']" checked/>'.$category->name.'</li>';

    } else {
        echo '<li><input type="checkbox" value="'.$category->cat_ID.'" name="bcio_options[fp_sp_category_'.$category->cat_ID.']"/>'.$category->name.'</li>';            
    }       

}

echo '</ul>';}

In my second options page, I use the option values to generate the appropriate fields in another settings section:

function bcio_special_section_settings_display(){
echo "These settings fields are generated based on your selection of Special Front Page Categories";
$options = (array)get_option('bcio_options');
$categories = bcio_get_categories();

foreach($categories as $category){
    $selected = ( isset( $options['fp_sp_category_'.$category->cat_ID] ) ) ? $options['fp_sp_category_'.$category->cat_ID] : '';    
    $cat_id = $category->cat_ID;    
    if($selected){  
    add_settings_field( 
        'bcio_special_cat_'.$category->cat_ID,                  
        'Special Section:<br />'.$category->name,           
        'bcio_special_section_display("'.$cat_id.'")',      
        'business-cover-special-sections', 
        'bcio_special_sections_options'                 
    );


    }           
}}
//The field itself 
function bcio_special_section_display($cat_id){

        $special_options = (array)get_option('bcio_special_options');
        $color =  ( isset( $special_options['color'] ) ) ? $special_options['color'] : '';
        echo '<input type="text" name="bcio_options[color]" value="' . $color . '" class="bc-color-field" >';   
    }

This successfully generates the appropriate number of fields, applies the name of the category in the field label, but when I try to use the callback it messes up as the parameter $cat_id I pass in the field callback doesn't quite work as I thought it would.

Warning: call_user_func() expects parameter 1 to be a valid callback, function 'bcio_special_section_display("12285")' not found or invalid function name in /nas/wp/www/cluster-2598/businesscover/wp-admin/includes/template.php on line 1237

I tried poking it in a few ways, but no luck and I really need to figure out a way to store options in association with category IDs without hardcoding the IDs themselves.

Getting this to work the right way with the Settings API or some non-plugin solution is paramount. I have a version based on ACF by Elliot Condon but would rather not make the theme dependent on a 3rd party plugin. The settings in these fields would define LESS vars, logos and so on for the site's special sections. Any hints in the right direction would be much appreciated.

share|improve this question
    
What are the PHP files you are putting function definitions into and how are they loaded? –  Rarst Jun 25 at 12:04
    
I added an options.php file in a lib/utils dir, included via functions.php. All settings fields and sections, callbacks and supporting functions (get cats, get menus, etc) are in this options.php file. –  Anca Jun 25 at 15:22

1 Answer 1

up vote 0 down vote accepted

This issue is now resolved. I am posting the solution, in case someone else finds it useful.

I have modified my callback for adding the checkbox list of categories so that the selected categories are saved in an array instead of separate options. It will make it much easier to find said special category and matching it with queried_object in the front end.

function bcio_fp_special_cats_display(){
$options = (array)get_option('bcio_options');
$categories = bcio_get_categories();

echo '<ul>';

foreach($categories as $category){
    $selected = ( isset( $options['fp_sp_category'] ) ) ? $options['fp_sp_category'] : '';  

    if(in_array($category->cat_ID, $selected)){ 
        echo '<li><input type="checkbox" value="'.$category->cat_ID.'" name="bcio_options[fp_sp_category][]" checked/>'.$category->name.'</li>';

    } else {
        echo '<li><input type="checkbox" value="'.$category->cat_ID.'" name="bcio_options[fp_sp_category][]"/>'.$category->name.'</li>';            
    }       

}

echo '</ul>';


}

Based on the values contained in this new array (category ids), I then generate the setting fields, with the category ID as an argument to the field:

function bcio_special_section_settings_display(){
echo "These settings fields are generated based on your selection of Special Front Page Categories";
$options = (array)get_option('bcio_options');
$selected = ( isset( $options['fp_sp_category'] ) ) ? $options['fp_sp_category'] : '';  

      if($selected){    
      foreach($selected as $cat_id){
        add_settings_field( 
             'section_'.$cat_id,                    
             'Special Section:<br />'.get_cat_name( $cat_id ),          
             'bcio_special_section_display',        
             'business-cover-special-sections', 
             'bcio_special_sections_options', 
             $cat_id                
      );  
      }             
}
}

I then used the argument to give my field a unique ID, and to save the color option as color_$mycatid.

function bcio_special_section_display($args){
$special_options = (array)get_option('bcio_special_options');
$color =  ( isset( $special_options['color_'.$args] ) ) ? $special_options['color_'.$args] : '';
echo '<input type="text" id="color-'.$args.'" name="bcio_special_options[color_'.$args.']" value="' . $color . '" class="bc-color-field" >';                                    
}

I have tested the solution with per-category color fields. The colors are saved correctly and, if set, display as previously configured.

I hope someone else finds the solution helpful. If I discover any problems, I will post an update to this thread.

Happy coding!

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.