NOTE: The contents of this post may shift about a bit as time goes on. For some reason, the code-highlighting plugin I’m attempting to use isn’t working correctly. There may end up being some more code snippets that find their way into this post if I figure out what’s going wrong. Fixed it by moving to a different code-highlighting plugin. Dunno what the issue was, but it’s gone now.
For theme authors looking to customize their theme offerings with a fancy options/administration screen, functions.php
is the place to start. By default, WordPress loads it whenever your theme is active — on the front page or on the back end. A brief discussion on the wp-hackers mailing list today prodded me to post the following code from the functions.php
I’m including in Elbee Elgee (whenever I get around to releasing it, that is…). I took the guide offered by The Undersigned as a jumping-off point and added some nice tweaks. In particular, The Undersigned’s version only allowed for text and select form inputs — I wanted/needed more flexibility.
The file itself is fairly simple and almost self-documenting, but in the interests of full disclosure, I’ll comment upon it here:
1. I set the descriptive and short names of my theme at the head of the file.
$themename = "Elbee Elgee"; $shortname = "lblg";
2. Elbee Elgee looks for layouts and stylesheets in a couple of sub-directories in order to let end users drop custom stylesheets in and have them detected automatically. (Line 5)
if ( is_dir($layout_path) ) { if ($layout_dir = opendir($layout_path) ) { while ( ($file = readdir($layout_dir)) !== false ) { if(stristr($file, ".css") !== false) { array_push($layouts, $file); } } } } if ( is_dir($alt_stylesheet_path) ) { if ($alt_stylesheet_dir = opendir($alt_stylesheet_path) ) { while ( ($file = readdir($alt_stylesheet_dir)) !== false ) { if(stristr($file, ".css") !== false) { array_push($alt_stylesheets, $file); } } } } $layouts_tmp = asort($layouts); $layouts_tmp = array_unshift($layouts, "Select a layout:"); $alt_stylesheets_tmp = asort($alt_stylesheets); $alt_stylesheets_tmp = array_unshift($alt_stylesheets, "Select a stylesheet:");
3. I set all the options in an array. (Line 39)
$options = array ( array( "name" => "Use Custom Headers", "id" => $shortname."_use_custom_header", "std" => "false", "type" => "checkbox"), array( "name" => "Display \"About\" Text", "id" => $shortname."_display_about", "std" => "false", "type" => "checkbox"), array( "name" => "\"About\" Text", "id" => $shortname."_about_text", "std" => "This is a little blurb about your site.", "type" => "textarea", "options" => array( "rows" => "5", "cols" => "40") ), array( "name" => "Layout Stylesheet", "id" => $shortname."_layout_stylesheet", "std" => "Select a layout:", "type" => "select", "options" => $layouts), array( "name" => "Theme Stylesheet", "id" => $shortname."_alt_stylesheet", "std" => "Select a stylesheet:", "type" => "select", "options" => $alt_stylesheets), array( "name" => "Number of Previous Posts", "id" => $shortname."_previous_posts", "std" => "5", "type" => "text"), array( "name" => "Del.icio.us Username", "id" => $shortname."_delicious_username", "std" => "zamoose", "type" => "text") );
4. mytheme_add_admin()
is responsible for adding the theme options page to the admin bars in WordPress and saving the theme options to the database. It’s fairly uninteresting and so I won’t reprint it here.
5. mytheme_admin()
is where the real meat of the options screen gets generated. In particular, the following loop iterates through the options array set in the top of the file and generates the inputs for the form options. (Line 128)
<?php foreach ($options as $value) { switch ( $value['type'] ) { case 'text': ?> <tr valign="top"> <th scope="row"><?php echo $value['name']; ?>:</th> <td> <input 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> <?php break; case 'select': ?> <tr valign="top"> <th scope="row"><?php echo $value['name']; ?>:</th> <td> <select 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> <?php break; case 'textarea': $ta_options = $value['options']; ?> <tr valign="top"> <th scope="row"><?php echo $value['name']; ?>:</th> <td> <textarea name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>" cols="<?php echo $ta_options['cols']; ?>" rows="<?php echo $ta_options['rows']; ?>"><?php if( get_settings($value['id']) != "") { echo get_settings($value['id']); }else{ echo $value['std']; }?></textarea> </td> </tr> <?php break; case "radio": ?> <tr valign="top"> <th scope="row"><?php echo $value['name']; ?>:</th> <td> <?php foreach ($value['options'] as $key=>$option) { $radio_setting = get_settings($value['id']); if($radio_setting != ''){ if ($key == get_settings($value['id']) ) { $checked = "checked=\"checked\""; } else { $checked = ""; } }else{ if($key == $value['std']){ $checked = "checked=\"checked\""; }else{ $checked = ""; } }?> <input type="radio" name="<?php echo $value['id']; ?>" value="<?php echo $key; ?>" <?php echo $checked; ?> /><?php echo $option; ?><br /> <?php } ?> </td> </tr> <?php break; case "checkbox": ?> <tr valign="top"> <th scope="row"><?php echo $value['name']; ?>:</th> <td> <?php 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; ?> /> <?php ?> </td> </tr> <?php break; default: break; } } ?>
6. I then register sidebar Widgets in mytheme_wp_head()
, as well as detect whether we should use the WP Custom Header code. (Line 263)
if ( function_exists('register_sidebar') ) { register_sidebar(array('name'=>'Navigation')); register_sidebar(array('name'=>'Extra')); register_sidebar(array('name'=>'Bottom-Left')); register_sidebar(array('name'=>'Bottom-Right')); } $use_custom_header = $shortname."_use_custom_header"; if(get_settings($use_custom_header) == true){ // Set up custom header code define('HEADER_TEXTCOLOR', 'cfcfd0'); define('HEADER_IMAGE', '%s/styles/default/newbanner2.png'); define('HEADER_IMAGE_WIDTH', '1024'); define('HEADER_IMAGE_HEIGHT', '279'); add_custom_image_header('header_style', 'elbee_admin_header_style');
7. I do a few things as per the Custom Header specs and then, last of all, to sew it all up, I hook in to the WP head and admin_menu. (Line 346)
add_action('wp_head', 'mytheme_wp_head'); add_action('admin_menu', 'mytheme_add_admin');
That’s pretty much it. If you want to download the whole thing (as currently incarnated), click the download link below.
(05-19-2008) Note: I’ve updated the download to reflect my current functions.php file. There’s a lot of changes — I’m working on an updated post to cover the additions and changes.
Download removed
Download removed
Hope it’s a help to someone out there.
thanks for this. i’ve been desperately missing the checkbox from theundersigned’s options.
[…] I always like to have something of value to you in every post. So: all the theme options you’ll ever need. There. I feel […]
[…] I always like to have something of value to you in every post. So: all the theme options you’ll ever need. There. I feel […]
I know this post is kinda old, but i find it very usefull but i have a problem when i input some text with ” ” it adds to many \ to the items :S do you know any way to fix this? would realy apriciate if u could answer this
for both textareas and
<input type="text">
, you’ll need to surround the value withstripslashes()
, so that the slashes aren’t re-added every time. slightly modified exampleNice catch, Adam. I’ll update my example to do so — don’t know why I haven’t come across that before.
thanks for the fast response!! 😀
sorry for doble posting, but after doing what adam said i came up with something so i dont have to add stripslashes() everytime i need to use the values i set
if ( ‘save’ == $_REQUEST[‘action’] ) {
foreach ($options as $value) {
$dato = stripslashes($_REQUEST[$value[‘id’]]);
update_option( $value[‘id’], $dato ); }
foreach ($options as $value) {
$dato = stripslashes($_REQUEST[$value[‘id’]]);
if( isset( $_REQUEST[ $value[‘id’] ] ) ) { update_option( $value[‘id’], $dato ); } else { delete_option( $value[‘id’] ); } }
}
simple add the stripslashes before the data is added 😀
Omar:
You’re coming at it from the wrong direction, though. The slashes generally get inserted by php at save time by magic_quotes so as to avoid confusing (certain) MySQL servers. This will result in all data returned from the DB having the slashes in it, thus displaying them in your options page.
You want to clean the data on retrieval if possible so as to avoid \”options\” showing up in your options page.
ohh ok thanks… kinda wierd cause the code i posted works perfectly on my server… just that functions.php is messing up the headers in wordpress admin panel and yet i see no posible way this could happen :S
[…] blazed the trail in 2006 with a great tutorial as to how to go about creating options pages and Literal Barrage added more sophistication to the original design. I’ve taken aspect of both from them in […]
[…] talvez un poco mas simple pero si desean tambien hay otra version de este con muchas mas opciones Aqui. Por lo que vi en algunos premium themes, este es el metodo que usan. Escrito 9 de Julio, 2008 […]
A Theme Tip For WordPress Theme Authors…
For theme authors looking to customize their theme offerings with a fancy options/administration screen, functions.php is the place to start. By default, WordPress loads it whenever your theme is active — on the front page or on the back end….
Ive spent last 3 hours implementing a much-better theme options page to my later WP theme, largely with thanks to the info posted above and within these comments.
However, after a lot of head-scratching and editing, I have managed to strip the slashes from inside my WP options page (I want to add a “text-area” field for a google adsense banner code), the adsense code when saved no longer has the slashes, but when I return to the site, clear cache and refresh, the adsense code doesn’t work as when I view the source it’s still showing the adsense code WITH slashes.
So can anyone tell me of a way to make the adsense banner code work on-site?
Any help would be GREATLY appreciated – I can offer a free theme from stylewp.com to anyone who solves this problem I have 🙂
[…] literalbarrage […]
[…] This is condensed version of the options setup for example purposes only, for further info on this please see this post. […]
Old but golden tip this.
There’s one “fix” I’ve added to your code, namely that standard values aren’t saved until you actually press save. This issue, incidentally, also makes standard values for checkboxes not work.
Update the code to look like this:
} else if( ‘reset’ == $_REQUEST[‘action’] ) {
// delete options
foreach ($options as $value) {
delete_option( $value[‘id’] ); }
// update standards
foreach ($options as $value) {
update_option( $value[‘id’], $value[‘std’] ); }
header(“Location: themes.php?page=theme-options.php&reset=true”);
die;
After this, boolean standard values for checkboxes should be input without quotes, i.e.
array( “name” => __(‘Windows Live Writer?’,’proto’),
“desc” => __(‘Use Windows Live Writer?’,’proto’),
“id” => $shortname.”_wlw”,
“std” => true,
“type” => “checkbox”),
offline link: functions-2.0.zip (48) –
Whoops. It should be fixed now. Sorry for the slip-up!
…Or not. WordPress Download Monitor is acting very strangely.
Is there somewhere else I can download the functions-2.0.zip file? I get an error when I try to download it: “Download path is invalid!” Thanks!