1

I am writing a set of classes to easily create options pages accessible via submenus of the standard WordPress menus and a way to easily create options for said menus. The way I am wiring it is via a settings class which you pass settings to and I intend to have it work along with a submenu class to create the menu, settings page and store the options neatly in a single option. The option is getting created in the database -- but nothing is being stored in the option. Can anyone lead me in the right direction? Here is my code:

Settings Class

class settings_page {
    public function __construct($args){
        foreach($args['sections'] as $section){
            $section_name = $section['section_name'];
            $section_id = $section['section_id'];
            if( false == get_option( $section_id ) ) {     
                add_option( $section_id );  
            } 
            $options = get_option($section_id);
            $section_text = $section['section_text'];
            $page = $section['page'];
            add_settings_section($section_id, $section_name, function(){return $section_text;}, $page);
            foreach($section['items'] as $item) {
                $type = $item['type'];
                $id = $item['id'];
                $description = $item['description'];
                $title = $item['title'];
                $choices = $item['choices'];
                if ($description) $title = $title . '<br /><small class="italic">' . $description . '</small>';
                switch($type){
                    case "checkbox":
                        add_settings_field($id, $title, 
                                function ($section) use ($options) {
                                    $id = $section[0];
                                    $html = '<input type="checkbox" id="' . $id . '" name="' . $id . '" value="1" ' . checked(1, $options[$id], false) . '/>';  
                                    echo $html;  
                                },
                        $page, $section_id, array($id));
                    break;
                    case "text":
                        add_settings_field($id, $title, 
                                function ($section) use ($options) {
                                    $id = $section[0];
                                    unset($html);
                                    $html .= '<input type="text" id="' . $id . '" name="' . $id . '" value="' . $options[$id] . '" />';  
                                    echo $html;  
                                },
                        $page, $section_id, array($id));
                    break;
                    case "textarea":
                        add_settings_field($id, $title, 
                                function ($section) use ($options) {
                                    $id = $section[0];
                                    unset($html);
                                    $html .= '<textarea class="large-text" cols="50" rows="10" type="text" id="' . $id . '" name="' . $id . '">' . $options[$id] . '</textarea>';  
                                    echo $html;  
                                },
                        $page, $section_id, array($id));
                    break;
                    case "pulldown":
                        add_settings_field($id, $title, 
                                function ($section) use ($options) {
                                    $id = $section[0];
                                    $choices = $section[1];
                                    $value = $options[$id];
                                    unset($html);
                                    $html = '<select id="' . $id . '" name="' . $id . '">';
                                    $html .= '<option value=""> - Select - </option>';
                                    foreach($choices as $key=>$val){
                                        $selected = '';
                                        if ($value== $key) $selected = ' selected="selected" ';
                                        $html .= '<option value="' . $key . '"' . $selected . '>'.$val.'</option>';
                                    }
                                    $html .= '</select>';

                                    echo $html;  
                                },
                        $page, $section_id, array($id, $choices));
                    break;                  
                }

            }
            register_setting($page, $section_id);
        }

        new submenu(array(
            "parent" => $args['parent'],
            "title"=>$args['title'],
            "text"=>$args['text'],
            "capability"=>$args['capability'],
            "slug"=>$args['slug']

        ));

    }
}

Submenu Class

<?php

class submenu {

    function __construct($args=""){
            $parent = strtolower($args['parent']);
            $title = $args['title'];
            $text = $args['text'];
            $capability = $args['capability'];
            $slug = $args['slug'];

            switch($parent){
                case 'dashboard': 
                    $name = "index.php";
                    break;
                case 'posts':
                    $name = 'edit.php';
                    break;
                case 'media':
                    $name='upload.php';
                    break;
                case 'links':
                    $name='link-manager.php';
                    break;
                case 'pages':
                    $name='edit.php?post_type=page';
                    break;
                case 'comments':
                    $name='edit-comments.php';
                    break;
                case 'appearance':
                    $name='themes.php';
                    break;
                case 'plugins':
                    $name='plugins.php';
                    break;  
                case 'users':
                    $name='users.php';
                    break;  
                case 'tools':
                    $name='tools.php';
                    break;  
                case 'settings':
                    $name='options-general.php';
                    break;  
                default:
                    $name='options-general.php';
                    break;  
            }
            add_action('admin_menu', function() use ($name, $title, $text, $capability, $slug) {

                    add_submenu_page(  
                        $name,                  
                        $title,          
                        $text,                  
                        $capability,            
                        $slug, function() use  ($name, $title, $text, $capability, $slug) {
                       ?>
                            <div class="wrap">  


                                <div id="icon-themes" class="icon32"></div>  
                                <h2><?php echo $title; ?></h2>  
                                <form method="post" action="options.php">  
                                    <?php settings_fields( $slug ); ?>  
                                    <?php do_settings_sections( $slug );?>    
                                    <?php submit_button(); ?>  
                                </form>  

                            </div>

                       <?php
                        }

                    );
                }
            );



        }
    }

Here is where I am actually calling the classes/methods

add_action('admin_menu', 
    function() {
        $options['parent'] = "settings";
        $options['title'] = "My Settings";
        $options['text'] = "My Settings";
        $options['capability'] = "manage_options";
        $options['slug'] = "my_settings";

        $settings['section_name'] = "General Section";
        $settings['section_id'] = "general_section";
        $settings['section_text'] = "This be General Section Test";
        $settings['page'] = "my_settings";
        $settings['items'] = array(
            array(
                'type' => 'checkbox',
                'id' => 'show_header',
                'title' => 'The title, to show header',
                'description' => 'show the header now please',
                ),
            array(
                'type' => 'textarea',
                'id' => 'show_footer',
                'title' => 'The title, to show footer',
                'description' => 'show the footer now please',
                ),  
            array(
                'type' => 'text',
                'id' => 'text_item',
                'title' => 'Enter anything here',
                'description' => '',
                ),          
            array(
                'type' => 'pulldown',
                'id' => 'which_one',
                'title'=>'Who\'s on First?',
                'description'=>'',
                'choices'=>array(
                        '1'=>'Who',
                        '2'=>'What',
                        '3'=>'Why',
                    )
                ),
            );
        $settings2['section_name'] = "Second Section";
        $settings2['section_id'] = "second_section";
        $settings2['section_text'] = "More Settings";
        $settings2['page'] = "my_settings";
        $settings2['items'] = array(
            array(
                'type' => 'checkbox',
                'id' => 'show_header_2',
                'description' => 'Show Second Header',
                'title' => 'Show the Second Header?',
                ),
            array(
                'type' => 'textarea',
                'id' => 'show_footer_2',
                'description' => 'Tell me a story',
                'title' => 'It can be about anything!',
                ),  
            );

        $options['sections'][] = $settings;
        $options['sections'][] = $settings2;
        new settings_page($options);
    }, 1);

What works:

It works if I change $options[$id] to get_option($id) but this saves each individual setting to its own individual setting in the database which is wildly inefficient. I've error_logged $page, $section_id right before the register_setting call and everything is as it should be which leaves me baffled.

What doesn't work: saving these settings to a serialized array :)

I'm happy to provide anything else that can help you help me.

Thanks.

1
  • What works? What doesn't work? What debugging/error feedback do you get? What have you already tried to do to resolve the issue? May 9, 2013 at 17:14

1 Answer 1

7

You have the name parameters set to "$id" which means that they'll be things like "show_header_2" and such. You actually want them to be "second_section[show_header_2]" and similar instead, so that the array of settings is what you get back from the form.

3
  • Are you referring to the HTML elements (e.g. update <input type="text" id="show_header_2" ... to <input type="text" id="show_section[show_header_2" ... ? May 9, 2013 at 17:53
  • 2
    Yes, but I meant the "name" attributes, not the "id" attributes. The name is what the key is of the key-value pair being sent back.
    – Otto
    May 9, 2013 at 18:00
  • Thanks for this! I was having issues with this and you led me to the promised land! Sep 24, 2014 at 21:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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