WordPress – Theme Options Page with Category List

I am trying to create an options page for my theme, where on the options page there is a dropdown list that displays all of the category names, with the option value as the ID number of the category, so that on the dropdown itself, it displays all of the category names, but then when you select your category, and echo this in the frontend, it echos the categories ID.

The code I have at the moment displays the list of category names, but also echos the name onto the frontend. I have tried to modify it for the ID number, but I’ve had no luck.

Read More

So just to summarize, on the options page, it needs to display the category names in the dropdown, but on the frontend it should echo the category’s ID number.

EDIT: This is the complete code I am using to create the options page – this all sits inside functions.php:

<?php
$themename = "TGH 2012";
$shortname = "tgh";

$categories = get_categories('hide_empty=0&orderby=name');
    $wp_cats = array();

    foreach ($categories as $category_list ) {
           $wp_cats[$category_list->cat_id] = $category_list->cat_name;
    }

    array_unshift($wp_cats, "Choose a category");


global $options;
$options = array (

    array(  "name" => "Homepage Options",
            "type" => "title"),

    array(  "type" => "open"),


array(  "name" => "Pick Categories",
        "desc" => "Choose a category from the list to do some interesting stuff.",
        "id" => $shortname."_categories",
        "type" => "select",
        "options" => $wp_cats,
        "std" => ""),

array(  "type" => "close")

);

function mytheme_add_admin() {

global $themename, $shortname, $options;

if ( $_GET['page'] == basename(__FILE__) ) {

    if ( 'save' == $_REQUEST['action'] ) {

            foreach ($options as $value) {
                update_option( $value['id'], $_REQUEST[ $value['id'] ] ); }

            foreach ($options as $value) {
                if( isset( $_REQUEST[ $value['id'] ] ) ) { update_option( $value['id'], $_REQUEST[ $value['id'] ]  ); } else { delete_option( $value['id'] ); } }

            header("Location: themes.php?page=functions.php&saved=true");
            die;

    } else if( 'reset' == $_REQUEST['action'] ) {

        foreach ($options as $value) {
            delete_option( $value['id'] ); }

        header("Location: themes.php?page=functions.php&reset=true");
        die;

    }
}

add_theme_page($themename." Options", "".$themename." Options", 'edit_themes', basename(__FILE__), 'mytheme_admin');

    }

    function mytheme_admin() {

    global $themename, $shortname, $options;

    if ( $_REQUEST['saved'] ) echo '<div id="message" class="updated fade"><p><strong>'.$themename.' settings saved.</strong></p></div>';
    if ( $_REQUEST['reset'] ) echo '<div id="message" class="updated fade"><p><strong>'.$themename.' settings reset.</strong></p></div>';

?>
<div class="wrap">
<h2><?php echo $themename; ?> settings</h2>
<form method="post">
  <?php foreach ($options as $value) { 

    switch ( $value['type'] ) {

        case "open":
        ?>
  <table width="100%" border="0" style="background-color:#eef5fb; padding:10px;">
    <?php break;

        case "close":
        ?>
  </table>
  <br />
  <?php break;

        case "title":
        ?>
  <table width="100%" border="0" style="background-color:#dceefc; padding:5px 10px;">
  <tr>
    <td colspan="2"><h3 style="font-family:Georgia,'Times New Roman',Times,serif;"><?php echo $value['name']; ?></h3></td>
  </tr>
  <?php break;

        case 'text':
        ?>
  <tr>
    <td width="20%" rowspan="2" valign="middle"><strong><?php echo $value['name']; ?></strong></td>
    <td width="80%"><input style="width:400px;" name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>" type="<?php echo $value['type']; ?>" value="<?php if ( get_settings( $value['id'] ) != "") { echo get_settings( $value['id'] ); } else { echo $value['std']; } ?>" /></td>
  </tr>
  <tr>
    <td><small><?php echo $value['desc']; ?></small></td>
  </tr>
  <tr>
    <td colspan="2" style="margin-bottom:5px;border-bottom:1px dotted #000000;">&nbsp;</td>
  </tr>
  <tr>
    <td colspan="2">&nbsp;</td>
  </tr>
  <?php 
        break;

        case 'textarea':
        ?>
  <tr>
    <td width="20%" rowspan="2" valign="middle"><strong><?php echo $value['name']; ?></strong></td>
    <td width="80%"><textarea name="<?php echo $value['id']; ?>" style="width:400px; height:200px;" type="<?php echo $value['type']; ?>" cols="" rows=""><?php if ( get_settings( $value['id'] ) != "") { echo get_settings( $value['id'] ); } else { echo $value['std']; } ?>
</textarea></td>
  </tr>
  <tr>
    <td><small><?php echo $value['desc']; ?></small></td>
  </tr>
  <tr>
    <td colspan="2" style="margin-bottom:5px;border-bottom:1px dotted #000000;">&nbsp;</td>
  </tr>
  <tr>
    <td colspan="2">&nbsp;</td>
  </tr>
  <?php 
        break;

        case 'select':
        ?>
  <tr>
    <td width="20%" rowspan="2" valign="middle"><strong><?php echo $value['name']; ?></strong></td>
    <td width="80%"><select style="width:240px;" name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>">
        <?php foreach ($value['options'] as $option) { ?>
        <option<?php if ( get_settings( $value['id'] ) == $option) { echo ' selected="selected"'; } elseif ($option == $value['std']) { echo ' selected="selected"'; } ?>><?php echo $option; ?></option>
        <?php } ?>
      </select></td>
  </tr>
  <tr>
    <td><small><?php echo $value['desc']; ?></small></td>
  </tr>
  <tr>
    <td colspan="2" style="margin-bottom:5px;border-bottom:1px dotted #000000;">&nbsp;</td>
  </tr>
  <tr>
    <td colspan="2">&nbsp;</td>
  </tr>
  <?php
        break;

        case "checkbox":
        ?>
  <tr>
    <td width="20%" rowspan="2" valign="middle"><strong><?php echo $value['name']; ?></strong></td>
    <td width="80%"><? if(get_settings($value['id'])){ $checked = "checked="checked""; }else{ $checked = ""; } ?>
      <input type="checkbox" name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>" value="true" <?php echo $checked; ?> /></td>
  </tr>
  <tr>
    <td><small><?php echo $value['desc']; ?></small></td>
  </tr>
  <tr>
    <td colspan="2" style="margin-bottom:5px;border-bottom:1px dotted #000000;">&nbsp;</td>
  </tr>
  <tr>
    <td colspan="2">&nbsp;</td>
  </tr>
  <?php         break;


} 
}
?>

  <!--</table>-->

  <p class="submit">
    <input name="save" type="submit" value="Save changes" />
    <input type="hidden" name="action" value="save" />
  </p>
</form>
<form method="post">
  <p class="submit">
    <input name="reset" type="submit" value="Reset" />
    <input type="hidden" name="action" value="reset" />
  </p>
</form>
<?php
}

add_action('admin_menu', 'mytheme_add_admin'); ?>
<?php
if ( function_exists('register_sidebar') )
    register_sidebar(array(
        'before_widget' => '<li id="%1$s" class="widget %2$s">',
        'after_widget' => '</li>',
        'before_title' => '',
        'after_title' => '',
    ));

?>

The following code is then placed at the bottom of “header.php”:

<?php global $options;
foreach ($options as $value) {
    if (get_settings( $value['id'] ) === FALSE) { $$value['id'] = $value['std']; } else { $$value['id'] = get_settings( $value['id'] ); }
}
?>

And then, this is the code I am using to show the saved variable on the front-end:

<?php echo $tgh_categories; ?>

Related posts

Leave a Reply

3 comments

  1. Is this how it really appears? If so, change cat_id to cat_ID

    foreach ($categories as $category_list ) {
           $wp_cats[$category_list->cat_id] = $category_list->cat_name;
    }
    

    EDIT

    After this:

        foreach ($categories as $category_list ) {
                   $wp_cats[$category_list->cat_ID] = $category_list->cat_name;
            }
    

    Add:

    $wp_ids = array();
    
    foreach ($categories as $category_list ) {
           $wp_ids[$category_list->cat_ID] = $category_list->cat_ID;
    }
    

    Change this:

        array(  "name" => "Pick Categories",
        "desc" => "Choose a category from the list to do some interesting stuff.",
        "id" => $shortname."_categories",
        "type" => "select",
        "options" => $wp_cats,
        "std" => ""),
    

    To this:

        array(  "name" => "Pick Categories",
        "desc" => "Choose a category from the list to do some interesting stuff.",
        "id" => $shortname."_categories",
        "cid" => wp_ids,
        "type" => "select",
        "options" => $wp_cats,
        "std" => ""),
    

    Also change this:

       case 'select':
        ?>
         <tr>
           <td width="20%" rowspan="2" valign="middle"><strong><?php echo $value['name']; ?></strong></td>
           <td width="80%"><select style="width:240px;" name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>">
               <?php foreach ($value['options'] as $option) { ?>
               <option<?php if ( get_settings( $value['id'] ) == $option) { echo ' selected="selected"'; } elseif ($option == $value['std']) { echo ' selected="selected"'; } ?>><?php echo $option; ?></option>
               <?php } ?>
             </select></td>
         </tr>
         <tr>
           <td><small><?php echo $value['desc']; ?></small></td>
         </tr>
         <tr>
           <td colspan="2" style="margin-bottom:5px;border-bottom:1px dotted #000000;">&nbsp;</td>
         </tr>
         <tr>
           <td colspan="2">&nbsp;</td>
         </tr>
         <?php
               break;
    

    To this:

       case 'select':
        ?>
         <tr>
           <td width="20%" rowspan="2" valign="middle"><strong><?php echo $value['name']; ?></strong></td>
           <td width="80%"><select style="width:240px;" name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>">
               <?php foreach ($value['options'] as $option) { ?>
               <option value="<?php echo $value['cid']; ?>" <?php if ( get_settings( $value['id'] ) == $option) { echo ' selected="selected"'; } elseif ($option == $value['std']) { echo ' selected="selected"'; } ?>><?php echo $option; ?></option>
               <?php } ?>
             </select></td>
         </tr>
         <tr>
           <td><small><?php echo $value['desc']; ?></small></td>
         </tr>
         <tr>
           <td colspan="2" style="margin-bottom:5px;border-bottom:1px dotted #000000;">&nbsp;</td>
         </tr>
         <tr>
           <td colspan="2">&nbsp;</td>
         </tr>
         <?php
               break;
    

    EDIT

    My bad, I forgot a $

    Change this:

    "cid" => wp_ids,
    

    To:

    "cid" => $wp_ids,
    

    NEW EDIT

    Change this:

     <tr>
       <td width="20%" rowspan="2" valign="middle"><strong><?php echo $value['name']; ?></strong></td>
       <td width="80%"><select style="width:240px;" name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>">
           <?php foreach ($value['options'] as $option) { ?>
           <option value="<?php echo $value['cid']; ?>" <?php if ( get_settings( $value['id'] ) == $option) { echo ' selected="selected"'; } elseif ($option == $value['std']) { echo ' selected="selected"'; } ?>><?php echo $option; ?></option>
           <?php } ?>
         </select></td>
     </tr>
    

    To this:

     <tr>
       <td width="20%" rowspan="2" valign="middle"><strong><?php echo $value['name']; ?></strong></td>
       <td width="80%"><select style="width:240px;" name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>">
           <?php 
    
    $categories = get_categories('hide_empty=0&orderby=name');
    
    foreach ($categories as $category_list ) {
    
      ?>
           <option value="<?php echo $category_list->cat_ID; ?>" <?php if ( get_settings( $value['id'] ) == $category_list->cat_name) { echo ' selected="selected"'; } elseif ($category_list->cat_name == $value['std']) { echo ' selected="selected"'; } ?>><?php echo $category_list->cat_name; ?></option>
           <?php } ?>
         </select></td>
     </tr>
    
  2. I’ve been looking for the same thing, and have found no where which actually answers what you’re trying to do, not even this thread. At least here they’re close, but they still break some functionality in your question code provided. However, I have been working on this for a few hours, and per usual, the longer you work at it, the simpler the solution turns out to be.

    I’ve made an assumption that you’re trying to us WP_Query to choose and display posts from a category chosen in your new them options page, like I am. I’ve discovered that WP_Query doesn’t like recursively sifting through categories if you are using a name, but will if you’re using cat_ID…not even when using get_cat_ID. So first, here is my WP_Query that appears in my front-page.php

    <?php
        $feat1= get_option('twp_feat_cat'); //this is the id of your option in the mega array you setup in functions.php
        $args=array('cat' => $feat1,'post_type' => 'post','post_status' => 'publish','posts_per_page' => 2,'caller_get_posts'=> 1);
        $my_query = null;
        $my_query = new WP_Query($args);
        $post_counter = 0; //so I can style last post differently with css
        if( $my_query->have_posts() ) {
            while ($my_query->have_posts()) : $my_query->the_post(); $post_counter++; ?>
                <article id="post-<?php the_ID(); ?>" <?php if ($post_counter == 1) post_class('fourcol first clearfix'); elseif ($post_counter  == count( $posts )) post_class('fourcol last clearfix'); else post_class('fourcol clearfix'); ?> role="article">
                <header class="article-header">
                <h2><a href="<?php the_permalink() ?>" rel="bookmark" title="<?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
                </header> <!-- end header section -->
                <section class="entry-content clearfix">
                     <?php $thumb = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'original' );
                     $url = $thumb['0'];
                     echo do_shortcode( '[rimg src="' . $url . '"]' );
                     ?>
                     <?php the_excerpt(); ?>
                </section> <!-- end article section -->
                <footer class="article-footer">
                     <p class="tags"><?php //the_tags('<span class="tags-title">' . __('Tags:', 'bonestheme') . '</span> ', ', ', ''); ?></p>
                </footer> <!-- end article footer -->
                </article>
                <?php
                endwhile;
                }
                wp_reset_query();  // Restore global post data stomped by the_post().
                ?>
    

    This snippet takes the cat_ID from my theme options page and puts it into $feat1

    The only two changes needed to your functions.php from the original are changing this:

    $wp_cats[$category_list->cat_id] = $category_list->cat_name;
    

    to this:

    $wp_cats[$category_list->cat_ID] = $category_list->cat_ID;
    

    and then modify your selection <option> tag from this:

    <option<?php if ( get_settings( $value['id'] ) == $option) { echo ' selected="selected"'; } elseif ($option == $value['std']) { echo ' selected="selected"'; } ?>><?php echo $option; ?></option>
    

    to this:

    <option value="<?php echo $option;?>" <?php if (get_settings( $value['id'] ) == $option) { echo 'selected="selected"'; } ?>><?php echo get_cat_name($option); ?></option>
    

    I didn’t have to put anything in my header.php to get this working. So what this does is instead of using the cat_name, it uses cat_ID, but fills in the user friendly cat_name in the drop down, while still associating each entry to the cat_ID, which I think it what you were looking for. I’m sorry if this was long, late, or not quite what you were looking for, but this is my very first time contributing to the site, and it was this post that got me started when I was looking for the solution.