. : April 25, 2015 : .

Making a template with a meta box for a WordPress theme

When customizing a WordPress theme, it’s important to allow your theme’s users to override the defaults. For example, you might be making a template for a contact page. You want to allow people to customize the placeholder text in the inputs, text areas and confirmation/error messages. You’ll need to display the default text to them in the admin screen, so they can decide if they want to change it or not. You’ll also need to display the default text to their site visitors if they did not change the defaults. Here is an example of how you would go about that.

Start by defining your defaults in your functions.php file.

$contactDefaults = array(
	'nameLabel' => 'Name',
	'namePlaceholder' => 'First Last',
	'emailLabel' => 'email',
	'emailPlaceholder' => 'your@email.com',
	'messageLabel' => 'Message',
	'messagePlaceholder' => 'Type your message here',
	'submitText' => 'send',
	'successFeedback' => 'Thanks for reaching out! We’ll be in touch soon.',
	'errorFeedback' => 'An error occured, and your message could not be sent.',
);

Next, we need to create a meta box for our theme users to override the defaults with their own witty text. This will require us to write 4 functions. The first will initiate things with the admin_menu action hook. The second will display the meta box. The third will save the text that our theme users enter using the fourth one will clean up the data.

Here is the first one that gets triggered by the admin_menu action hook.

add_action( 'admin_menu', 'my_meta_init' );

function my_meta_init() {
	$post_id = $_GET['post'] ? $_GET['post'] : $_POST['post_ID'] ;
	// check to see if it's the contact template
	$template_file = get_post_meta($post_id,'_wp_page_template',TRUE);
	if ($template_file == 'contact.php')
	{
		// it's the contact template, add the meta box
		add_meta_box('my-contact-meta', 'Contact Settings', 'my_contact_meta', 'page', 'normal', 'high');
		// add a function to save the meta
		add_action( 'save_post', 'save_contact_meta', 10, 2 );
	}
}

That function will then call this second function that displays the meta box to our theme users when they are editing the contact page and allow them to enter their own clever comments to their site visitors.

function my_contact_meta(){

	global $post;
	global $contactDefaults;
	$meta = get_post_meta($post->ID,'_contact',TRUE);
	?>
		<label for="_contact[name-label]">Name label text</label><br/>
		<input type="text" name="_contact[name-label]" id="_contact[name-label]" placeholder="<?php echo $contactDefaults['nameLabel']; ?>" class="contact-text" style="width: 100%;" value="<?php if(!empty($meta['name-label'])) echo $meta['name-label']; ?>"><br/><br/>

		<label for="_contact[name-placeholder]">Name placeholder text</label><br/>
		<input type="text" name="_contact[name-placeholder]" id="_contact[name-placeholder]" placeholder="<?php echo $contactDefaults['namePlaceholder']; ?>" class="contact-text" style="width: 100%;" value="<?php if(!empty($meta['name-placeholder'])) echo $meta['name-placeholder']; ?>"><br/><br/>

		<label for="_contact[email-label]">email label text</label><br/>
		<input type="text" name="_contact[email-label]" id="_contact[email-label]" placeholder="<?php echo $contactDefaults['emailLabel']; ?>" class="contact-text" style="width: 100%;" value="<?php if(!empty($meta['email-label'])) echo $meta['email-label']; ?>"><br/><br/>

		<label for="_contact[email-placeholder]">email placeholder text</label><br/>
		<input type="text" name="_contact[email-placeholder]" id="_contact[email-placeholder]" placeholder="<?php echo $contactDefaults['emailPlaceholder']; ?>" class="contact-text" style="width: 100%;" value="<?php if(!empty($meta['email-placeholder'])) echo $meta['email-placeholder']; ?>"><br/><br/>

		<label for="_contact[message-label]">Message label text</label><br/>
		<input type="text" name="_contact[message-label]" id="_contact[message-label]" placeholder="<?php echo $contactDefaults['messageLabel']; ?>" class="contact-text" style="width: 100%;" value="<?php if(!empty($meta['message-label'])) echo $meta['message-label']; ?>"><br/><br/>

		<label for="_contact[message-placeholder]">Message placeholder text</label><br/>
		<input type="text" name="_contact[message-placeholder]" id="_contact[message-placeholder]" placeholder="<?php echo $contactDefaults['messagePlaceholder']; ?>" class="contact-text" style="width: 100%;" value="<?php if(!empty($meta['message-placeholder'])) echo $meta['message-placeholder']; ?>"><br/><br/>

		<label for="_contact[submit-text]">Text for the submit button</label><br/>
		<input type="text" name="_contact[submit-text]" id="_contact[submit-text]" placeholder="<?php echo $contactDefaults['submitText']; ?>" style="width: 100%;" value="<?php if(!empty($meta['submit-text'])) echo $meta['submit-text']; ?>"><br/><br/>

		<label for="_contact[success-feedback]">Feedback for when a message has been successfully submitted</label><br/>
		<input type="text" name="_contact[success-feedback]" id="_contact[success-feedback]" placeholder="<?php echo $contactDefaults['successFeedback']; ?>" class="contact-text" style="width: 100%;" value="<?php if(!empty($meta['success-feedback'])) echo $meta['success-feedback']; ?>"><br/><br/>

		<label for="_contact[error-feedback]">Feedback for when a message has been successfully submitted</label><br/>
		<input type="text" name="_contact[error-feedback]" id="_contact[error-feedback]" placeholder="<?php echo $contactDefaults['errorFeedback']; ?>" class="contact-text" style="width: 100%;" value="<?php if(!empty($meta['error-feedback'])) echo $meta['error-feedback']; ?>">

		<input type="hidden" name="my_meta_box_nonce" value="<?php echo wp_create_nonce( plugin_basename( __FILE__ ) ); ?>" />

Our third function will then save all that awesome verbiage for the rest of the world to see.

<?php
}
function save_contact_meta( $post_id, $post ){
	// bail if it's autosaving
	if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
	return;

	// check that nonce!
	if ( !wp_verify_nonce( $_POST['my_meta_box_nonce'], plugin_basename( __FILE__ ) ) )
	return $post_id;

	// make sure the user has rights to edit the post
	if ( !current_user_can( 'edit_post', $post_id ) )
	return $post_id;

	$current_data = get_post_meta($post_id, '_contact', TRUE);
	$new_data = $_POST['_contact'];
	clean_meta($new_data);

	if (!is_null($new_data)) {
		add_post_meta($post_id,'_contact',$new_data,TRUE);
	}
	return $post_id;
}

And here is the clean up method that is called by the third method just before it saves the new text.

function clean_meta(&$arr)
{
	if (is_array($arr))
	{
		foreach ($arr as $i => $v)
		{
			if (is_array($arr[$i]))
			{
				my_meta_clean($arr[$i]);

				if (!count($arr[$i]))
				{
					unset($arr[$i]);
				}
			}
			else
			{
				if (trim($arr[$i]) == '')
				{
					unset($arr[$i]);
				}
			}
		}

		if (!count($arr))
		{
			$arr = NULL;
		}
	}
}

That’s it for the functions.php file. Now all we have to do is add the functionality to our contact page template.

At the top of your contact page template, add we the following.

global $post;
global $contactDefaults;
$contact_meta = get_post_meta($post->ID,'_contact',TRUE);

That will give us access to the defaults as well as any customized excellence our theme users might have entered.

Now, we can create our form. Every time we need to display a label or placeholder text, we check to see if our theme user has entered their own text. If they have, we display it. If they haven’t, we display the default value.

<form id="contact-form" class="contact-form" action="<?php esc_url( $_SERVER['REQUEST_URI'] )?>" method="post">
	<fieldset class="contact-fieldset">
		<label for="contact-name"><?php if($contact_meta['name-label']): echo $contact_meta['name-label']; else: echo $contactDefaults['nameLabel']; endif ?>
			<input type="text" name="contact-name" id="contact-name" placeholder="<?php if($contact_meta['name-placeholder']): echo $contact_meta['name-placeholder']; else: echo $contactDefaults['namePlaceholder']; endif ?>" value="<?php echo ( isset( $_POST["contact-name"] ) ? esc_attr( $_POST["contact-name"] ) : '' ); ?>" class="form-control" tabindex="1">
		</label>

		<label for="contact-email"><?php  if($contact_meta['email-label']): echo $contact_meta['email-label']; else: echo $contactDefaults['emailLabel']; endif ?>
			<input type="text" name="contact-email" id="contact-email" value="<?php echo ( isset( $_POST["contact-email"] ) ? esc_attr( $_POST["contact-email"] ) : '' ); ?>" placeholder="<?php if($contact_meta['email-placeholder']): echo $contact_meta['email-placeholder']; else: echo $contactDefaults['emailPlaceholder']; endif ?>" class="form-control" tabindex="2">
		</label>

		<label for="contact-message"><?php  if($contact_meta['message-label']): echo $contact_meta['message-label']; else: echo $contactDefaults['messageLabel']; endif ?>
			<textarea name="contact-message" id="contact-message" placeholder="<?php  if($contact_meta['message-placeholder']): echo $contact_meta['message-placeholder']; else: echo $contactDefaults['messagePlaceholder']; endif ?>" rows="3" class="form-control" tabindex="3"><?php echo ( isset( $_POST["contact-message"] ) ? esc_attr( $_POST["contact-message"] ) : '' ); ?></textarea>
		</label>

		<label for="contact-humanCheck" class="sr-only">This is a dummy field to trick bots. You will not be able to send your message if you enter anything into it.
			<input type="text" name="contact-humanCheck" id="contact-humanCheck" class="sr-only" value="<?php if(isset($_POST['contact-humanCheck']))  echo $_POST['contact-humanCheck'];?>" tabindex="-1"/>
		</label>
	</fieldset>

	<fieldset class="contact-buttons">
		<button type="submit" name="contact-submitted" class="btn btn-default contact-button" id="contact-submitted" tabindex="4"><?php  if($contact_meta['submit-text']): echo $contact_meta['submit-text']; else: echo $contactDefaults['submitText']; endif ?></button>
	</fieldset>
</form>

So, there you have it! Now when people use our theme, they can change the default placeholder text, labels, and confirmation messages!

References:

Categories:

Leave a Reply