Custom Settings For Genesis Child Themes

When building a site using a framework like Genesis (or when heavily modifying a WordPress theme), it is necessary to create a child theme to prevent code changes or additions from being overwritten when the framework or theme is updated.  When creating themes, it is common practice to create an admin menu item for the theme options.  The Genesis Framework has such a dedicated menu item for theme settings.  To keep all theme settings in the same place, it is necessary to build our child theme settings into the Genesis page. This blog post, we’ll be implementing custom settings for Genesis child themes.

The Genesis Framework provides a set of methods to easily add child theme settings. Using these methods, we set default values for our settings, register sanitation filters, add meta boxes, and create content functions for the meta boxes. The code below makes use of several WordPress methods.  Here are the links if you are unfamiliar: add_filter, add_action and add_meta_box.

Almost every site we build requires logo and favicon images. The code demonstrated here will give us a logo URL field and a favicon URL field. We begin by setting default values for the two URLs:

<?php
/**
 * Add Genesis Child Theme Settings Defaults
 */
function genesis_child_settings_defaults( $defaults ) {
    //Logo//
    $defaults['logo_url'] = '';
 
    //Favicon//
    $defaults['favicon_url'] = '';
    
    return $defaults;
}
add_filter( 'genesis_theme_settings_defaults', 'genesis_child_settings_defaults' );

You can add as many settings here as are required. Next, we attach sanitation functions to the settings defined above. Genesis has four built-in sanitation filters: one_zero, no_html, safe_html, and requires_unfiltered_html. To register our settings to use one of these sanitation filters we use the following code:

<?php
/**
 * Sanatize Genesis Child Theme Settings
 */
function genesis_child_register_sanitization_filters() {
    genesis_add_option_filter( 'no_html', GENESIS_SETTINGS_FIELD, 
                              array(
                                    'logo_url', 
                                    'favicon_url',
                              ) );
}
add_action( 'genesis_settings_sanitizer_init', 'genesis_child_register_sanitization_filters' );

By adding our option to the GENESIS_SETTINGS_FIELD, we limit what we have to do to manage the settings. Convenience is king in this case. The code above only registers filters of type no_html. If other types of settings are needed, simply call genesis_add_optin_filter again.

<?php
/** 
* Sanatize Genesis Child Theme Settings Extended
 */
function genesis_child_register_sanitization_filters_extended() {
    genesis_add_option_filter( 'no_html', GENESIS_SETTINGS_FIELD,
                              array(
                                    'logo_url',
                                    'favicon_url',
                              ) );
    genesis_add_option_filter('one_zero', GENESIS_SETTINGS_FIELD,
                              array(
                                    'foo',
                              ) );
    genesis_add_option_filter('safe_html', GENESIS_SETTINGS_FIELD,
                              array(
                                    'bar',
                              ) );
}
add_action( 'genesis_settings_sanitizer_init', 'genesis_child_register_sanitization_filters_extended' );

Next we add meta boxes to display our settings. Check out the following code:

<?php
/**
 * Add Genesis Child Settings Metabox
 */
function add_genesis_child_settings_boxes( $_genesis_theme_settings_pagehook ) {
    add_meta_box('genesis-child-settings', 'Child Settings', 'genesis_child_settings_box', 
                 $_genesis_theme_settings_pagehook, 'main', 'high');
}
add_action('genesis_theme_settings_metaboxes', 'add_genesis_child_settings_boxes');

There are a couple things going on here. As you can see, we use the WordPress add_meta_box method. The arguments are all standard, but page hook is passed in from the genesis_theme_settings_metaboxes hook. This is very important to include or we would not see any added settings. The first argument is our meta box slug. We then have title, content function hook, admin page hook, context, and priority. Check out the WordPress documentation of add_meta_box for further info. The content function, here defined as genesis_child_settings_box, is where we show our settings. Genesis and WordPress take care of the grunt work when it comes to loading and saving the settings we create. Look over the code below. The syntax is very important to making this work.

<?php
/**
 * Create Genesis Child Settings Metabox
 */
function genesis_child_settings_box() {
    ?>
    <p>Favicon URL:<br />
    <input type="text" name="<?php echo GENESIS_SETTINGS_FIELD; ?>[favicon_url]" 
        value="<?php echo esc_attr( genesis_get_option( 'favicon_url') ); ?>" size="50" /><p>
  
    <p>Logo URL:<br />
    <input type="text" name="<?php echo GENESIS_SETTINGS_FIELD; ?>[logo_url]" 
        value="<?php echo esc_attr( genesis_get_option( 'logo_url') ); ?>" size="50" /></p>
    <?php
}

The inputs must have the correct name attributes for Genesis to save the settings. As you may guess from the code, GENESIS_SETTINGS_FIELD is an array. When Genesis saves settings, it checks this array with the [slug]esc_attr method to encode any characters part of the settings value that may interfere with the HTML of the input field. The genesis_get_option simply dumps the option value. Great! We have registered new settings and have the ability to save them. All we have to do is call genesis_get_option( ‘option_slug’ ) to use a setting:

<a href="<?php echo get_site_url(); ?>"><img src="<?php echo genesis_get_option( 'logo_url' ); ?>" /></a>

Example:

<?php
/**
 * Add Genesis Child Theme Settings Defaults
 */
function cmsaddons_logo_defaults( $defaults ) {
	$defaults['cmsaddons_logo_url'] = '';
	
	return $defaults;
}
add_filter( 'genesis_theme_settings_defaults', 'cmsaddons_logo_defaults' );


/**
 * Sanatize Genesis Child Theme Settings
 */
function cmsaddons_register_logo_sanitization_filters() {
	genesis_add_option_filter( 'no_html', GENESIS_SETTINGS_FIELD,
		array(
			'cmsaddons_logo_url',
			
		) );
}
add_action( 'genesis_settings_sanitizer_init', 'cmsaddons_register_logo_sanitization_filters' );

/**
 * Add Genesis Child Settings Metabox
 */
function cmsaddons_register_logo_settings_box( $_genesis_theme_settings_pagehook ) {
	add_meta_box('cmsaddons-logo-settings', 'Logo Links', 'cmsaddons_logo_settings_box', $_genesis_theme_settings_pagehook, 'main', 'high');
}
add_action('genesis_theme_settings_metaboxes', 'cmsaddons_register_logo_settings_box');

/**
 * Create Genesis Child Settings Metabox
 */
function cmsaddons_logo_settings_box() {
	?>

	<p>Logo URL:<br />
	<input type="text" name="<?php echo GENESIS_SETTINGS_FIELD; ?>[cmsaddons_logo_url]" value="<?php echo esc_attr( genesis_get_option('cmsaddons_logo_url') ); ?>" size="50" /> 
	</p>	 

	<?php
}

Fontend external use , insert the code into the file function.php

// Add Image Header
function add_image_header() {

  $url = genesis_get_option('cmsaddons_logo_url');
  
  $linkhome = get_option('siteurl');
  if(!empty($url))
  echo "<a class='imgbanner' href='{$linkhome}' title='".get_bloginfo('name')."'><img src='{$url}' alt='".get_bloginfo('name')."' /></a>";
}
add_action('genesis_header','add_image_header');

Thank you pushpolitics.