If you’re customizing your site in a way that require site-wide options to be managed in the backend, it’s a good idea to use the Genesis Theme Settings page rather than create a separate backend page specifically for your feature. This keeps all theme-related settings in a single location.
I’m going to walk you through creating your own theme options for Genesis. I’ll be adding a Social Settings box that allows you to specify a Twitter and Facebook URL, to be used in the nav menu of the theme.
Set up Defaults
The default values are what the fields will be set to when a user clicks “Reset Settings”. I’m just going to use blank values, but you could use whatever you like.
Sanitization
One of the major improvements to Genesis in the 1.7 release is the addition of a Sanitizer class. Mark Jaquith, a lead developer of WordPress, was hired by StudioPress to conduct a security audit, and this was one of the results.
The Sanitizer class makes it easy to ensure only the specific types of data you want can be saved in your theme settings. This prevents someone from dropping malicious scripts into one of your theme settings. For more information, watch this Theme & Plugin Security presentation.
By default, Genesis comes with four sanitization filters: one_zero, no_html, safe_html, and requires_unfiltered_html. These should cover almost anything you need to do, but if you did want to add something to this list you could use the genesis_available_sanitizer_filters
filter (see /lib/classes/sanitization.php).
We’re going to use the no_html filter.
Register Metabox
We’ll use the add_meta_box()
function to add a metabox to the Theme Settings page. You can look in /lib/admin/theme-settings.php for more examples:
Create Metabox
Our add_meta_box()
function basically says “Stick the metabox the the be_social_settings_box()
function on the Theme Settings page.” Now we have to create that function.
For more examples of metaboxes, see /lib/admin/theme-settings.php.
Putting it all together
Since there’s a lot code, I recommend putting it in a single file. Inside my child theme I’ve created /lib/functions/social-settings.php, and this is the contents:
Vivek Parmar says
Thanks for the useful guide, never use filters always using hooks as i do not have to done major customization.
Thanks a ton, will try to ad more things using this tut.
slhomme says
Thank Bill for this quick walk through, It’s not an easy thing to find good articles about adding or customizing theme options for Genesis even in the official support forum!
kirkoconnor says
This article helps us in an area that is really important to us – customising our Genesis installs to make them even quicker and simpler to produce in record times.
i have one question though – what sort of protection do the options you create have when Genesis versions change when you update the parent theme in the future?
Bill Erickson says
Since all of the customizations are done in your child theme, they are perfectly save from an upgrade. The only thing that could cause problems is if Genesis drastically changes how the settings are registered, but I don’t see that happening. They add the filters and hooks so that you can extend the theme settings without worrying about an upgrade.
In the past the only way to customize it was to unhook the Genesis function that registered all the theme settings and create your own. The problem here is your settings page is now “frozen” at the version you originally built it on, since any new metaboxes added to Genesis won’t be included in your function. Now that they have a hook inside the function that registers Genesis metaboxes, this isn’t a problem.
Greg Rickaby says
Bookmarked. (I’m pretty sure that’s the highest form of compliment one can receive) 🙂
Bill Erickson says
Haha thanks!
Jon Brown says
This is excellent and totally opens my eyes to lots of new possibilities, so glad SP added this and that you told us about it.
Personally for social media button I usually create a “social media menu” using WP 3.0 menus with custom links inserted, link classes assigned to each item and then apply images with CSS. I like this method in part because it keeps the drag and drop functionality of rearranging the icons at will.
As for the Genesis Theme Settings menu however I have a request to the universe… would someone with far superior skills then me… please considering making the Genesis Theme Settings page meta boxes flexible the way the WP dashboard is? I personally hate the new single column layout, and the fact that it’s fixed width… it ought to be flexible and stretchy/fluid just like the Dashboard.
Bill Erickson says
I agree, if you’re just adding the social icons to the menu just add them directly to the menu and use a class to set the image. For this project the links we had social icons in the menu, a sidebar widget, and the footer, but to keep the example simple I just did the menu (and to show off the great filter wp_nav_menu_{menu-name}_items to customize a specific menu).
Chris Cree says
Heya Bill! You’re tutorials and code examples for Genesis themes are fantastic! You’ve helped me think about creating custom child themes in a whole new way that has sped up my development time considerably. Thanks so much for that!
Have a question about this tutorial, though. I’m curious how you would modify this to add a child theme settings page rather than adding the settings to the Genesis –> Theme Settings since that’s the preference for the folks at StudioPress when it comes to creating new settings.
Bill Erickson says
Wow, I’ve never seen that link before. In that case I’d recommend you just copy how Genesis does it in /lib/admin/theme-settings.php, but for your own page.
I’ll revisit the tutorial or create a new one specifically about this.
Dee says
Bill, I love that every time I’m looking for a thing I need to do with Genesis, there you are with the answer… thanks!
Cathy says
Thanks again – this is going to take my own themes up a notch. 🙂
Cathy Tibbles says
Putting this into practice now. And learning from your code int he core functions plugin and then the child theme – and trying to put it all into practice. One thing has me confused – I’ve added custom meta boxes to a file in child theme and called the file from the genesis setup hook in the child functions file, but the defaults aren’t working? And in looking for answers, I’m running into the CMB plugin you co-wrote, we do NOT need that with the genesis options right? It looks like I’ve written most ofthe code into the admin file, so I want to confirm that I dont need that core function plugin with the genesis theme options page?
Thanks for any tips you can give me!
Bill Erickson says
The CMB code is only for post-specific metaboxes (postmeta). This code is for site-wide metaboxes. So no, it isn’t required.
The defaults will only work the first time the option is loaded. It basically says, if there’s no value in the database for this option, put the default value in there. Once you save the page (if you didn’t have defaults) then the option will now exist in the database as empty. So even if you specify a default, it won’t work.
Try dropping your theme in a brand new WordPress website and see if it loads.
Ade says
Nice tutorial, Bill!
Just a comment – but you should add the new settings directly to the $defaults array, not as a sub-array, eg like this:
$defaults['new_setting'] = 'some text';
$defaults['another_setting'] = 'some other text';
etc
Bill Erickson says
Good catch! updated the code.
Ade says
Great!
Cheers.