<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Aliso the GeekPosts tagged ‘jQuery’ | Aliso the Geek</title>
	<atom:link href="http://alisothegeek.com/tag/jquery/feed/" rel="self" type="application/rss+xml" />
	<link>http://alisothegeek.com</link>
	<description>A coder in love with WordPress</description>
	<lastBuildDate>Tue, 15 Nov 2011 16:46:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Extended WordPress Settings API Tutorial, Part 2</title>
		<link>http://alisothegeek.com/2011/01/wordpress-settings-api-tutorial-2/</link>
		<comments>http://alisothegeek.com/2011/01/wordpress-settings-api-tutorial-2/#comments</comments>
		<pubDate>Sun, 02 Jan 2011 00:57:05 +0000</pubDate>
		<dc:creator>Alison Barrett</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Settings API]]></category>
		<category><![CDATA[theme options]]></category>

		<guid isPermaLink="false">http://alisothegeek.com/?p=913</guid>
		<description><![CDATA[Download the files (updated June 5, 2011) This post is based on part 1 of this tutorial, so read it if you haven&#8217;t. We left off with a theme options class, My_Theme_Options, that had all the behind-the-scenes work complete. The next step is the HTML. 4. Display the Options Page and Sections Up to this point, [...]]]></description>
			<content:encoded><![CDATA[<div class="bolts-toc"><h1>In This Article</h1><ul><li><a href="#4-display-the-options-page-and-sections">4. Display the Options Page and Sections</a><ul><li><a href="#options-page-html">Options Page HTML</a></li><li><a href="#sections-html">Sections HTML</a></li></ul></li><li><a href="#5-display-the-form-fields">5. Display the Form Fields</a><ul><li><a href="#where-are-the-form-labels-and-the-table-structure">Where are the form labels and the table structure?</a></li><li><a href="#subheadings-within-a-section">Subheadings Within a Section</a></li></ul></li><li><a href="#6-custom-javascript-and-styling">6. Custom Javascript and styling</a><ul><li><a href="#jquery-tabs">jQuery Tabs</a></li><li><a href="#placeholder-text">Placeholder Text</a></li><li><a href="#custom-styling">Custom Styling</a></li></ul></li></ul></div>
<p><a class="bolts-download-link" href="http://alisothegeek.com/wp-content/uploads/2011/01/settings-api-tutorial.zip">Download the files (updated June 5, 2011)</a></p>
<p>This post is based on <a href="/2011/01/wordpress-settings-api-tutorial-1/">part 1 of this tutorial</a>, so read it if you haven&#8217;t.</p>
<p>We left off with a theme options class, My_Theme_Options, that had all the behind-the-scenes work complete. The next step is the HTML.</p>
<p><span id="more-913"></span></p>
<h3 id="4-display-the-options-page-and-sections">4. Display the Options Page and Sections</h3>
<p>Up to this point, we&#8217;ve had a completely blank options page in our admin. We want to see the fruits of our labor! We use three functions to make this happen: display_page(), display_section(), and display_setting(). Let&#8217;s tackle the page and sections first.</p>
<h4 id="options-page-html">Options Page HTML</h4>
<p>Add this to the display_page() function:</p>
<pre class="brush:php">echo '&lt;div class="wrap"&gt;
&lt;div class="icon32" id="icon-options-general"&gt;&lt;/div&gt;
&lt;h2&gt;' . __( 'Theme Options' ) . '&lt;/h2&gt;
&lt;form action="options.php" method="post"&gt;
	';
	settings_fields( 'mytheme_options' );
	do_settings_sections( $_GET['page'] );

	echo '&lt;p class="submit"&gt;&lt;input name="Submit" type="submit" class="button-primary" value="' . __( 'Save Changes' ) . '" /&gt;&lt;/p&gt;
&lt;/form&gt;';</pre>
<p>Look at the theme options page now. There is a big &#8220;Theme Options&#8221; heading, a subheading for each section, and a whole lot of errors. That&#8217;s because there&#8217;s no display_section() function written yet, and we&#8217;ll get to that next.</p>
<p>The &#8220;icon32&#8243; div at the top of the above code is what creates the nice-looking settings icon next to our heading. You can change the id to use a different WordPress icon (<a href="http://www.onextrapixel.com/2009/07/01/how-to-design-and-style-your-wordpress-plugin-admin-panel/">onextrapixel has a great cheat sheet</a>).</p>
<p>The settings_fields() function inserts a few hidden form fields, including a nonce for security.</p>
<p>The do_settings_sections() function is looking for sections assigned to the current page slug. Remember the code we used to register the sections in part 1:</p>
<pre class="brush:php">add_settings_section( $slug, $title, array( &amp;$this, 'display_section' ), 'mytheme-options' );</pre>
<p>The page slug was referenced there, along with the display_section() function.</p>
<h4 id="sections-html">Sections HTML</h4>
<p>The purpose of the display_section() function is only to add descriptive text (or other HTML) to that specific settings section. Whatever is output by this function will be displayed below the section subheading. If you register the sections individually instead of in a loop, you can use a different callback function for each section and insert custom content here.</p>
<p>For now, just put an empty function inside the class:</p>
<pre class="brush:php">/* Description for section */
public function display_section() {
	// code
}</pre>
<h3 id="5-display-the-form-fields">5. Display the Form Fields</h3>
<p>The reason we wrote a helper function to add our settings to the database is so we could pass certain arguments along to the callback function (which is responsible for outputting the HTML to display the field). This allows us to use the same callback function for every single field, and still get unique displays for each type. Let&#8217;s walk through the callback function, display_setting().</p>
<pre class="brush:php">/* HTML output for individual settings */
public function display_setting( $args = array() ) {

	extract( $args );

	$options = get_option( 'mytheme_options' );

	if ( ! isset( $options[$id] ) &amp;&amp; 'type' != 'checkbox' )
		$options[$id] = $std;
	elseif ( ! isset( $options[$id] ) )
		$options[$id] = 0;

	$field_class = '';
	if ( $class != '' )
		$field_class = ' class="' . $class . '"';</pre>
<p>The arguments for this function, which are the same arguments as our create_setting() function, get passed in an array and then turned into variables by extract(). Then, we create an array of all the existing options in the database with get_option(). The argument for that, &#8216;mytheme_options&#8217;, is the name of our master options array.</p>
<p>If the current setting, $id, doesn&#8217;t exist in the database, then it assigns that setting its default value. You should also exclude checkboxes in this if statement, because checkboxes don&#8217;t have user-created values (they&#8217;re either on or off).</p>
<p>Then we check for a custom class to use for this field. If it&#8217;s equal to anything other than an empty string, it will output &#8216;class=&#8221;$class&#8221;&#8216; in the HTML form field.</p>
<p>There is a fairly massive swtich statement coming up next. I&#8217;ll just give you the text field code for now, and the rest after I explain it:</p>
<pre class="brush:php">	switch ( $type ) {

		case 'text':
		default:
			echo '&lt;input class="regular-text' . $field_class . '" type="text" id="' . $id . '" name="mytheme_options[' . $id . ']" placeholder="' . $std . '" value="' . esc_attr( $options[$id] ) . '" /&gt;';

	 		if ( $desc != '' )
	 			echo '&lt;br /&gt;&lt;span class="description"&gt;' . $desc . '&lt;/span&gt;';

	 		break;
	}
}</pre>
<p>This is pretty straightforward. It&#8217;s printing an HTML input field, with a custom class if the setting has one, and setting its name, id, and value. It prints the description, if it exists, on a line below the field in small text. It&#8217;s also setting a &#8220;placeholder&#8221; attribute. This is an HTML5 attribute, and we&#8217;ll be using it to find the default value for that field in some jQuery later on.</p>
<p>Note that I&#8217;m using the text field as the default in this switch statement. You can use whichever type you want as the default, just make sure it comes last in the switch statement and has &#8220;default:&#8221; under the &#8220;case&#8221; line.</p>
<h4 id="where-are-the-form-labels-and-the-table-structure">Where are the form labels and the table structure?</h4>
<p>The Settings API prints the HTML for these settings inside a table cell that&#8217;s already created. WordPress automatically creates the table, creates a row for each field with a table header containing the field label, and opens and closes the table cell around the form field.</p>
<p>This is both good and bad. It saves us a lot of code doing that manually, and it formats it like other settings pages in WordPress so it has the same look and feel. However, it is less flexible for those who want their options page to look a little different. This is where the jQuery comes in (back to that in a bit).</p>
<p>Below is the rest of the switch statement. This code should all go after <code>switch ( $type ) {</code> and before <code>case 'text':</code> for it to work properly.</p>
<pre class="brush:php">case 'heading':
	echo '&lt;/td&gt;&lt;/tr&gt;&lt;tr valign="top"&gt;&lt;td colspan="2"&gt;&lt;h4&gt;' . $desc . '&lt;/h4&gt;';
	break;

case 'checkbox':

	echo '&lt;input class="checkbox' . $field_class . '" type="checkbox" id="' . $id . '" name="mytheme_options[' . $id . ']" value="1" ' . checked( $options[$id], 1, false ) . ' /&gt; &lt;label for="' . $id . '"&gt;' . $desc . '&lt;/label&gt;';

	break;

case 'select':
	echo '&lt;select class="select' . $field_class . '" name="mytheme_options[' . $id . ']"&gt;';

	foreach ( $choices as $value =&gt; $label )
		echo '&lt;option value="' . esc_attr( $value ) . '"' . selected( $options[$id], $value, false ) . '&gt;' . $label . '&lt;/option&gt;';

	echo '&lt;/select&gt;';

	if ( $desc != '' )
		echo '&lt;br /&gt;&lt;span class="description"&gt;' . $desc . '&lt;/span&gt;';

	break;

case 'radio':
	$i = 0;
	foreach ( $choices as $value =&gt; $label ) {
		echo '&lt;input class="radio' . $field_class . '" type="radio" name="mytheme_options[' . $id . ']" id="' . $id . $i . '" value="' . esc_attr( $value ) . '" ' . checked( $options[$id], $value, false ) . '&gt; &lt;label for="' . $id . $i . '"&gt;' . $label . '&lt;/label&gt;';
		if ( $i &lt; count( $options ) - 1 )
			echo '&lt;br /&gt;';
		$i++;
	}

	if ( $desc != '' )
		echo '&lt;br /&gt;&lt;span class="description"&gt;' . $desc . '&lt;/span&gt;';

	break;

case 'textarea':
	echo '&lt;textarea class="' . $field_class . '" id="' . $id . '" name="mytheme_options[' . $id . ']" placeholder="' . $std . '" rows="5" cols="30"&gt;' . wp_htmledit_pre( $options[$id] ) . '&lt;/textarea&gt;';

	if ( $desc != '' )
		echo '&lt;br /&gt;&lt;span class="description"&gt;' . $desc . '&lt;/span&gt;';

	break;

case 'password':
	echo '&lt;input class="regular-text' . $field_class . '" type="password" id="' . $id . '" name="mytheme_options[' . $id . ']" value="' . esc_attr( $options[$id] ) . '" /&gt;';

	if ( $desc != '' )
		echo '&lt;br /&gt;&lt;span class="description"&gt;' . $desc . '&lt;/span&gt;';

	break;</pre>
<h4 id="subheadings-within-a-section">Subheadings Within a Section</h4>
<p>In the switch statement, I added a &#8220;heading&#8221; type as an option. This is useful for dividing up long sections. Since a setting is displayed within a table cell on the right-hand side, I had to cheat the system a bit here. I close the table cell and the table row, and then open a new row with a cell spanning two columns. Then I put an h4 inside to give it a consistent appearance and (somewhat) proper semantics. To avoid displaying a label on the left, the title is left blank, and the text for the heading is put in the description.</p>
<h3 id="6-custom-javascript-and-styling">6. Custom Javascript and styling</h3>
<p>At this point, the settings page is 100% functional and is visually consistent with the rest of the WordPress admin. You could stop right here and have a solid theme options page. If you want something with a little more pizzazz, then we have more coding to do.</p>
<h4 id="jquery-tabs">jQuery Tabs</h4>
<p>Go back to the add_pages() function and add this line of code under what&#8217;s already there:</p>
<pre class="brush:applescript">add_action( 'admin_print_scripts-' . $admin_page, array( &amp;$this, 'scripts' ) );</pre>
<p>This calls a function in our class so we can insert our own Javascript, and it only applies it to our theme options page in the admin. Here&#8217;s that function:</p>
<pre class="brush:php">/* jQuery Tabs */
public function scripts() {
	wp_print_scripts( 'jquery-ui-tabs' );
}</pre>
<p>Now we need to add some jQuery code to our admin page. We will do that in the display_page() function. Replace everything inside that function with the following:</p>
<pre class="brush:applescript">echo '&lt;div class="wrap"&gt;
&lt;div class="icon32" id="icon-options-general"&gt;&lt;/div&gt;
&lt;h2&gt;Theme Options&lt;/h2&gt;
&lt;form action="options.php" method="post"&gt;';

	settings_fields( 'mytheme_options' );
	echo '&lt;div class="ui-tabs"&gt;
		&lt;ul class="ui-tabs-nav"&gt;';

	foreach ( $this-&gt;sections as $section )
		echo '&lt;li&gt;&lt;a href="#' . strtolower( str_replace( ' ', '_', $section ) ) . '"&gt;' . $section . '&lt;/a&gt;&lt;/li&gt;';

	echo '&lt;/ul&gt;';
	do_settings_sections( $_GET['page'] );

	echo '&lt;/div&gt;
	&lt;p class="submit"&gt;&lt;input name="Submit" type="submit" class="button-primary" value="' . __( 'Save Changes' ) . '" /&gt;&lt;/p&gt;

&lt;/form&gt;
&lt;script type="text/javascript"&gt;
	jQuery(document).ready(function($) {

	});
&lt;/script&gt;
&lt;/div&gt;';</pre>
<p>Before we get to the jQuery, I&#8217;ve added a couple of things. The entire settings output is now wrapped in a div with class=&#8221;ui-tabs&#8221;. Then there&#8217;s an unordered list with class=&#8221;ui-tabs-nav&#8221; that loops through our sections to output a link for each one.</p>
<p>Now the jQuery magic. First, we need to make some modification to the code structure. Each section needs to be wrapped in a div with class=&#8221;ui-tabs-panel&#8221;, but we can&#8217;t access any of the code between the sections with just PHP. So we&#8217;ll search for the &lt;h3&gt; tags and use those as a marker for beginning a new section.</p>
<pre class="brush:js">var wrapped = $(".wrap h3").wrap("&lt;div class=\"ui-tabs-panel\"&gt;");
wrapped.each(function() {
	$(this).parent().append($(this).parent().nextUntil("div.ui-tabs-panel"));
});</pre>
<p><em>Thanks, Nathan, for the tip on using nextUntil() instead of next()!</em></p>
<p>This wraps the section headings inside of the div, and then takes what was directly after the headings—the table with all the form fields in it—and puts it inside that div. The next step is to add id attributes to the headings, and apply a class to all but the first panel to hide it from view:</p>
<pre class="brush:js">$(".ui-tabs-panel").each(function(index) {
	var str = $(this).children("h3").text().replace(/\s/g, "_");
	$(this).attr("id", str.toLowerCase());
	if (index &gt; 0)
		$(this).addClass("ui-tabs-hide");
});</pre>
<p>The .each() function loops through the panels. By adding the &#8220;index&#8221; attribute to the function, it generates an arbitrary counter that we can use to determine whether we&#8217;re on the first panel.</p>
<p>Finally, apply the actual tabs functionality to our modified HTML:</p>
<pre class="brush:js">$(".ui-tabs").tabs({ fx: { opacity: "toggle", duration: "fast" } });</pre>
<p>The parameters inside the .tabs() function can be altered to change the animation and speed of the transition between tabs. Check out the <a href="http://jqueryui.com/demos/tabs/#options">jQuery UI documentation</a> to see what&#8217;s possible.</p>
<h4 id="placeholder-text">Placeholder Text</h4>
<p>The default values of our text and textarea fields are currently just showing up as values that the user has to manually erase to enter their own information. This isn&#8217;t a horrible thing, but we can make it more user-friendly by adding some jQuery and styling to the mix. Add this to the jQuery block in display_page():</p>
<pre class="brush:js">$("input[type=text], textarea").each(function() {
	if ($(this).val() == $(this).attr("placeholder"))
		$(this).css("color", "#999");
});

$("input[type=text], textarea").focus(function() {
	if ($(this).val() == $(this).attr("placeholder")) {
		$(this).val("");
		$(this).css("color", "#000");
	}
}).blur(function() {
	if ($(this).val() == "" || $(this).val() == $(this).attr("placeholder")) {
		$(this).val($(this).attr("placeholder"));
		$(this).css("color", "#999");
	}
});</pre>
<p>This takes any field with a default value in it and makes the text grey. The value then disappears when the user clicks on the field (only if the value was the default). When a user clicks out of a field, if the field is still empty, it re-inserts the value and makes it grey again.</p>
<p>Because we&#8217;re creating some HTML dynamically and it&#8217;s going to be styled after the fact, we use CSS to hide the elements on the page to avoid the &#8220;flash&#8221; of unstyled content when the page loads. We need to put in one line of jQuery to show that content again when the loading is complete.</p>
<pre class="brush:js">$(".wrap h3, .wrap table").show();</pre>
<p>There are some strange issues that show up in Firefox because of its autocomplete functionality. To fix that, add this to the jQuery block:</p>
<pre>if ($.browser.mozilla)
         $("form").attr("autocomplete", "off");</pre>
<p>Thank you, <a href="#comment-208726579">Billyben</a>, for pointing this out to me!</p>
<h4 id="custom-styling">Custom Styling</h4>
<p>All the hard work is done! Everything from here on out is just gravy. To add custom CSS, we need to call our own stylesheet on our admin page.</p>
<p>First, create a new CSS file in your theme folder, and name it what you like (I&#8217;ll use mytheme-options.css). Add this to the add_pages() function:</p>
<pre>add_action( 'admin_print_styles-' . $admin_page, array( &amp;$this, 'styles' ) );</pre>
<p>Now add the styles() function to the theme options class:</p>
<pre class="brush:php">/* Insert custom CSS */
public function styles() {

	wp_register_style( 'mytheme-admin', get_bloginfo( 'stylesheet_directory' ) . '/mytheme-options.css' );
	wp_enqueue_style( 'mytheme-admin' );

}</pre>
<p>Any CSS you put in that stylesheet will now be applied to your theme options page. To get the look seen in the screenshot below, put this in the stylesheet:</p>
<pre>.ui-tabs-nav {
	border-bottom: 1px solid #ccc;
	height: 27px;
	margin: 20px 0;
	padding: 0;
}

.ui-tabs-nav li {
	display: block;
	float: left;
	margin: 0;
}

.ui-tabs-nav li a {
	padding: 4px 20px 6px;
	font-weight: bold;
}

.ui-tabs-nav li a {
	border-style: solid;
	border-color: #CCC #CCC #F9F9F9;
	border-width: 1px 1px 0;
	color: #C1C1C1;
	text-shadow: rgba(255, 255, 255, 1) 0 1px 0;
	display: inline-block;
	padding: 4px 14px 6px;
	text-decoration: none;
	margin: 0 6px -1px 0;
	-moz-border-radius: 5px 5px 0 0;
	-webkit-border-top-left-radius: 5px;
	-webkit-border-top-right-radius: 5px;
	-khtml-border-top-left-radius: 5px;
	-khtml-border-top-right-radius: 5px;
	border-top-left-radius: 5px;
	border-top-right-radius: 5px;
}

.ui-tabs-nav li.ui-tabs-selected a,
.ui-tabs-nav li.ui-state-active a {
	border-width: 1px;
	color: #464646;
}

.ui-tabs-panel {
	clear: both;
}

.ui-tabs-panel h3 {
	font: italic normal normal 24px/29px Georgia,"Times New Roman","Bitstream Charter",Times,serif;
	margin: 0;
	padding: 0 0 5px;
	line-height: 35px;
	text-shadow: 0 1px 0 #fff;
}

.ui-tabs-panel h4 {
	font-size: 15px;
	font-weight: bold;
	margin: 1em 0;
}

.wrap h3, .wrap table {
	display: none;
}</pre>
<p>Voilà! <del>I used some CSS3 to achieve some nice visual effects, so there are no images required.</del><ins>This will make the page look consistent with the rest of the WordPress admin.</ins></p>
<p><img class="aligncenter size-large wp-image-1069" title="Theme Options screenshot" src="http://alisothegeek.com/wp-content/uploads/2011/01/Screen-shot-2011-06-05-at-1.44.17-PM-520x655.png" alt="Theme Options screenshot" width="520" height="655" /></p>
<p>Now you have a functional, beautiful, kickass theme options page!</p>
<p>There are still a couple of small things to cover, so be sure to <a href="http://alisothegeek.com/2011/04/wordpress-settings-api-tutorial-follow-up/">read the follow-up post to this tutorial</a>.</p>
<p><a class="bolts-download-link" href="http://alisothegeek.com/wp-content/uploads/2011/01/settings-api-tutorial.zip">Download the files (updated June 5, 2011)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://alisothegeek.com/2011/01/wordpress-settings-api-tutorial-2/feed/</wfw:commentRss>
		<slash:comments>51</slash:comments>
		</item>
		<item>
		<title>Extended WordPress Settings API Tutorial, Part 1</title>
		<link>http://alisothegeek.com/2011/01/wordpress-settings-api-tutorial-1/</link>
		<comments>http://alisothegeek.com/2011/01/wordpress-settings-api-tutorial-1/#comments</comments>
		<pubDate>Sat, 01 Jan 2011 18:19:05 +0000</pubDate>
		<dc:creator>Alison Barrett</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Settings API]]></category>
		<category><![CDATA[theme options]]></category>

		<guid isPermaLink="false">http://alisothegeek.com/?p=880</guid>
		<description><![CDATA[The WordPress Settings API has been around for a little while, but I haven&#8217;t used it until now. I highly recommend it. It does a lot of work for you and is still flexible enough to create custom-styled options pages (with a little jQuery). Once you&#8217;re done with this tutorial, this is what you&#8217;ll have: [...]]]></description>
			<content:encoded><![CDATA[<div class="bolts-toc"><h1>In This Article</h1><ul><li><a href="#1-set-up-the-theme-options-class">1. Set Up the Theme Options Class</a></li><li><a href="#2-register-the-settings">2. Register the Settings</a></li><li><a href="#3-initialize-settings">3. Initialize Settings</a></li><li><a href="#whats-next">What's next?</a></li></ul></div>
<p>The WordPress Settings API has been around for a little while, but I haven&#8217;t used it until now. I highly recommend it. It does a lot of work for you and is still flexible enough to create custom-styled options pages (with a little jQuery).</p>
<p>Once you&#8217;re done with this tutorial, this is what you&#8217;ll have:</p>
<p><a href="http://alisothegeek.com/wp-content/uploads/2011/01/Screen-shot-2011-06-05-at-1.44.17-PM.png"><img class="aligncenter size-medium wp-image-1069" title="Theme Options screenshot" src="http://alisothegeek.com/wp-content/uploads/2011/01/Screen-shot-2011-06-05-at-1.44.17-PM-237x300.png" alt="Theme Options screenshot" width="237" height="300" /></a></p>
<p>This will be a little more complicated than just putting code into <code>functions.php</code> (that&#8217;s why it&#8217;s an &#8220;extended&#8221; tutorial). Here we go!</p>
<p><span id="more-880"></span></p>
<p>If you want to download the complete code in advance to follow along, here it is:</p>
<p><a class="bolts-download-link" href="http://alisothegeek.com/wp-content/uploads/2011/01/settings-api-tutorial.zip">Download the files (updated June 5, 2011)</a></p>
<h4 id="how-options-are-stored-in-the-database">How Options are Stored in the Database</h4>
<p>Using the Settings API, WordPress creates an array of options and puts it into a single database entry. This is the cleanest, most efficient way to do it. Without the Settings API, it requires a decent chunk of code to accomplish that. You can create more than one options array if you wish, but in this tutorial we&#8217;re putting all the options in the same array.</p>
<h3 id="1-set-up-the-theme-options-class">1. Set Up the Theme Options Class</h3>
<p>Almost everything we do is going to be contained in a custom PHP class so we can be more liberal with our function and variable names. First, create the PHP file. The naming standard for PHP class files is <code>class.classname-here.php</code> or <code>class-classname-here.php</code>. For the tutorial, I&#8217;m naming the class My_Theme_Options.</p>
<p>We&#8217;ll start with a couple of lines of code in functions.php:</p>
<pre class="brush:php">if ( file_exists( STYLESHEETPATH . '/class.my-theme-options.php' ) ) {
	require_once( STYLESHEETPATH . '/class.my-theme-options.php' );
}</pre>
<p>This will start up our theme options class. The rest of the PHP in this tutorial is written within that class, so you can close functions.php. <strong>Note: since we haven&#8217;t written the class yet, this will break your theme if you make it live before the next step.</strong></p>
<p>Make a new file in the theme folder and make sure the filename matches the code above. In that file, create the My_Theme_Options class:</p>
<pre class="brush:php">&lt;?php

class My_Theme_Options {

	/* Array of sections for the theme options page */
	private $sections;

	/* Initialize */
	function __construct() {
		// This will keep track of the checkbox options for the validate_settings function.
		$this->checkboxes = array();
		$this->settings = array();
		$this->get_settings();

		$this->sections['general']      = __( 'General Settings' );
		$this->sections['appearance']   = __( 'Appearance' );

		add_action( 'admin_menu', array( &#038;$this, 'add_pages' ) );
		add_action( 'admin_init', array( &#038;$this, 'register_settings' ) );

		if ( ! get_option( 'mytheme_options' ) )
			$this->initialize_settings();
	}

	/* Add page(s) to the admin menu */
	public function add_pages() {
		$admin_page = add_theme_page( 'Theme Options', 'Theme Options', 'manage_options', 'mytheme-options', array( &amp;$this, 'display_page' ) );
	}

	/* HTML to display the theme options page */
	public function display_page() {
		// code
	}

	/* Define all settings and their defaults */
	public function get_settings() {
		// code
	}

	/* Initialize settings to their default values */
	public function initialize_settings() {
		// code
	}

	/* Register settings via the WP Settings API */
	public function register_settings() {
		// code
	}
 }
 ?&gt;</pre>
<p>What&#8217;s going on here? Well, the __construct() function is called automatically when the class is used to create a variable. (This only works in PHP5; for PHP4, you must use the class name as the function name.) We&#8217;re defining the sections in which we want our theme options organized, and then using two WordPress hooks to run a couple of functions. The add_pages() function is adding our theme options page to the menu in the WordPress admin, under &#8220;Appearance.&#8221; It&#8217;s just a blank page right now, but we&#8217;ll fill it in later.</p>
<h3 id="2-register-the-settings">2. Register the Settings</h3>
<p>Registering settings with the WordPress Settings API is extremely simple if you only have a few settings, but once you get a dozen or more settings involved, it&#8217;s best to streamline your code.</p>
<p>In the WordPress Settings API, individual settings need a callback function to display the HTML. This does not need to be a unique function for each setting. If it shares a callback function with other settings, you need to pass arguments to that callback function to tell it which setting it needs to display.</p>
<p>To add all the settings to our database, we&#8217;re going to create our own helper function to register the setting with WordPress and then pass the proper arguments to the callback function. Put this inside the class:</p>
<pre class="brush:php">/* Create settings field */
public function create_setting( $args = array() ) {

	$defaults = array(
		'id'      =&gt; 'default_field',
		'title'   =&gt; 'Default Field',
		'desc'    =&gt; 'This is a default description.',
		'std'     =&gt; '',
		'type'    =&gt; 'text',
		'section' =&gt; 'general',
		'choices' =&gt; array(),
		'class'   =&gt; ''
	);

	extract( wp_parse_args( $args, $defaults ) );

	$field_args = array(
		'type'      =&gt; $type,
		'id'        =&gt; $id,
		'desc'      =&gt; $desc,
		'std'       =&gt; $std,
		'choices'   =&gt; $choices,
		'label_for' =&gt; $id,
		'class'     =&gt; $class
	);

	if ( $type == 'checkbox' )
		$this->checkboxes[] = $id;

	add_settings_field( $id, $title, array( $this, 'display_setting' ), 'mytheme-options', $section, $field_args );

}</pre>
<p>The only thing that needs to be changed here are the default arguments at the top. You can make these whatever you like. Here&#8217;s what each one does:</p>
<ul>
<li><strong>id</strong>: the ID of the setting in our options array, and the ID of the HTML form element</li>
<li><strong>title</strong>: displayed as the label for the HTML form element</li>
<li><strong>desc</strong> (optional): description displayed under the HTML form element</li>
<li><strong>std</strong>: default value for this setting</li>
<li><strong>type</strong>: which HTML form element to use</li>
<li><strong>section</strong>: the section to put this setting into—must match the array ID of a section defined in __construct()</li>
<li><strong>choices</strong> (optional): different choices in radio buttons or a drop-down menu</li>
<li><strong>class</strong> (optional): add a custom class to the HTML form element</li>
</ul>
<p>When you create the settings themselves, you&#8217;ll have to fill out these arguments for each one. If any of the arguments is left blank, then the default set in this function will be applied.</p>
<p>We&#8217;re also keeping track of which fields are checkboxes, because they need special treatment when the settings are saved.</p>
<p>The final line in this function is the WordPress Settings API in action. The &#8220;mytheme-options&#8221; argument is the slug for the admin page (it needs to match the slug used in the add_theme_page() function inside our add_pages() function.</p>
<p>In order for the settings to be initialized when the theme is activated, we specify our settings in a separate function, <code>get_settings()</code>.</p>
<pre>/* Define all settings and their defaults */
public function get_settings() {

	/* General Settings
	===========================================*/

	$this->settings['example_text'] = array(
		'title'   => __( 'Example Text Input' ),
		'desc'    => __( 'This is a description for the text input.' ),
		'std'     => 'Default value',
		'type'    => 'text',
		'section' => 'general'
	);

	$this->settings['example_textarea'] = array(
		'title'   => __( 'Example Textarea Input' ),
		'desc'    => __( 'This is a description for the textarea input.' ),
		'std'     => 'Default value',
		'type'    => 'textarea',
		'section' => 'general'
	);

	$this->settings['example_checkbox'] = array(
		'section' => 'general',
		'title'   => __( 'Example Checkbox' ),
		'desc'    => __( 'This is a description for the checkbox.' ),
		'type'    => 'checkbox',
		'std'     => 1 // Set to 1 to be checked by default, 0 to be unchecked by default.
	);

	$this->settings['example_heading'] = array(
		'section' => 'general',
		'title'   => '', // Not used for headings.
		'desc'    => 'Example Heading',
		'type'    => 'heading'
	);

	$this->settings['example_radio'] = array(
		'section' => 'general',
		'title'   => __( 'Example Radio' ),
		'desc'    => __( 'This is a description for the radio buttons.' ),
		'type'    => 'radio',
		'std'     => '',
		'choices' => array(
			'choice1' => 'Choice 1',
			'choice2' => 'Choice 2',
			'choice3' => 'Choice 3'
		)
	);

	$this->settings['example_select'] = array(
		'section' => 'general',
		'title'   => __( 'Example Select' ),
		'desc'    => __( 'This is a description for the drop-down.' ),
		'type'    => 'select',
		'std'     => '',
		'choices' => array(
			'choice1' => 'Other Choice 1',
			'choice2' => 'Other Choice 2',
			'choice3' => 'Other Choice 3'
		)
	);

	/* Appearance
	===========================================*/

	$this->settings['header_logo'] = array(
		'section' => 'appearance',
		'title'   => __( 'Header Logo' ),
		'desc'    => __( 'Enter the URL to your logo for the theme header.' ),
		'type'    => 'text',
		'std'     => ''
	);

	$this->settings['favicon'] = array(
		'section' => 'appearance',
		'title'   => __( 'Favicon' ),
		'desc'    => __( 'Enter the URL to your custom favicon. It should be 16x16 pixels in size.' ),
		'type'    => 'text',
		'std'     => ''
	);

	$this->settings['custom_css'] = array(
		'title'   => __( 'Custom Styles' ),
		'desc'    => __( 'Enter any custom CSS here to apply it to your theme.' ),
		'std'     => '',
		'type'    => 'textarea',
		'section' => 'appearance',
		'class'   => 'code'
	);

}</pre>
<p>I included one of each possible type in this tutorial. You can just copy and paste these to add more settings to the page. Note: The &#8216;section&#8217; argument must match the ID of a section defined in __construct().</p>
<p>Now that we have our helper function and the settings in place, let&#8217;s use them! Update the register_settings() function with this:</p>
<pre class="brush:php">/* Register settings via the WP Settings API */
public function register_settings() {

	register_setting( 'mytheme_options', 'mytheme_options', array ( &amp;$this, 'validate_settings' ) );

	foreach ( $this-&gt;sections as $slug =&gt; $title )
		add_settings_section( $slug, $title, array( &amp;$this, 'display_section' ), 'mytheme-options' );

	$this->get_settings();

	foreach ( $this->settings as $id => $setting ) {
		$setting['id'] = $id;
		$this->create_setting( $setting );
	}

}</pre>
<p>At the beginning of the function, register_setting() belongs to the Settings API. This is making our master settings array in the database, which is being named &#8220;mytheme_options.&#8221; The &#8220;validate_settings&#8221; argument is a function we will define later, to add custom validation to the user-entered data.</p>
<p>The add_settings_section() function is registering the different sections we defined in __construct().</p>
<h3 id="3-initialize-settings">3. Initialize Settings</h3>
<p>When the theme is first activated, the settings need to be initialized and set to their default values (this is especially important if the options control title tags or other front-end output).</p>
<pre>/* Initialize settings to their default values */
public function initialize_settings() {

	$default_settings = array();
	foreach ( $this->settings as $id => $setting ) {
		if ( $setting['type'] != 'heading' )
			$default_settings[$id] = $setting['std'];
	}

	update_option( 'mytheme_options', $default_settings );

}</pre>
<h3 id="whats-next">What&#8217;s next?</h3>
<p>At this point, the settings are all defined, and there are only two things left to do: tell WordPress how to display the settings, and create our custom validation function (which is entirely optional). That&#8217;s it!</p>
<p><a href="http://alisothegeek.com/2011/01/wordpress-settings-api-tutorial-2/">Read Part 2 of the WordPress Extended Settings API Tutorial »</a></p>
]]></content:encoded>
			<wfw:commentRss>http://alisothegeek.com/2011/01/wordpress-settings-api-tutorial-1/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Meet the WordPress Settings API</title>
		<link>http://alisothegeek.com/2010/12/meet-the-wordpress-settings-api/</link>
		<comments>http://alisothegeek.com/2010/12/meet-the-wordpress-settings-api/#comments</comments>
		<pubDate>Tue, 28 Dec 2010 05:07:04 +0000</pubDate>
		<dc:creator>Alison Barrett</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Settings API]]></category>

		<guid isPermaLink="false">http://alisothegeek.com/?p=864</guid>
		<description><![CDATA[I&#8217;ve been working on my own WordPress theme framework for the past several months, and it&#8217;s getting closer and closer to completion every week. A few months ago, after I had finished writing all the code for the framework&#8217;s theme options page, I learned of the WordPress Settings API. I initially ignored it because I [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on my own WordPress theme framework for the past several months, and it&#8217;s getting closer and closer to completion every week. A few months ago, after I had finished writing all the code for the framework&#8217;s theme options page, I learned of the WordPress Settings API. I initially ignored it because I had just finished writing all this beautiful code, which had taken far too many hours and given me far too many headaches to just abandon it all.</p>
<p>I decided to revisit the Settings API today, and I&#8217;m so glad I did! After about 9 hours at the computer, I rebuilt my theme options page using the Settings API, jQuery, and CSS3.</p>
<p><span id="more-864"></span></p>
<p><a href="http://alisothegeek.com/wp-content/uploads/2010/12/Screen-shot-2010-12-27-at-9.46.46-PM.png"><img class="aligncenter size-medium wp-image-865" title="Options page for my WordPress theme framework" src="http://alisothegeek.com/wp-content/uploads/2010/12/Screen-shot-2010-12-27-at-9.46.46-PM-300x219.png" alt="Screenshot of the options page for my WordPress theme framework" width="300" height="219" /></a>My theme options class went from 1258 lines of code to just 667. The API took care of a lot automatically. There are basically three things you have to do when using the Settings API:</p>
<ol>
<li>Register the pages &amp; sections for your options (if applicable)</li>
<li>Register the settings themselves</li>
<li>Tell WordPress how to display each field</li>
</ol>
<p>Doing just those three things, you will have fully-functioning theme or plugin options. Anything on top of that is just extra PHP, Javascript, and CSS to make it look pretty.</p>
<p>Without extra styling or manipulation, here&#8217;s what an options page will look like when using the Settings API. (Click on the image for a full-size version with some annotations.)</p>
<p><a href="http://alisothegeek.com/wp-content/uploads/2010/12/options-annotated.png"><img class="aligncenter size-large wp-image-869" title="Options page using the WP Settings API" src="http://alisothegeek.com/wp-content/uploads/2010/12/options-520x440.png" alt="Options page using the WP Settings API" width="520" height="440" /></a></p>
<p><strong>Without</strong> using the Settings API, that entire page would have to be created and formatted manually. In addition, you&#8217;d have to write the code that processes the form, validates the fields, saves the options to the database, and sends the user back to this page (with error messages if necessary).</p>
<p><strong>With</strong> the Settings API, all the form handling &amp; processing is done for you, as is a good chunk of the actual page display. The form fields themselves are displayed using a callback function assigned to each specific setting, so unless you want to write a separate function to display each field, it&#8217;s helpful to make your own mini-API around this one and keep your code organized in the process.</p>
<p>There are a few great tutorials out there on the Settings API—the two I used were <a href="http://www.presscoders.com/wordpress-settings-api-explained/" target="_blank">Settings API Explained</a> from PressCoders and <a href="http://ottopress.com/2009/wordpress-settings-api-tutorial/" target="_blank">WordPress Settings API Tutorial</a> from Otto on WordPress. Based on their tutorials, I developed a theme options class that you can reuse for your own projects (it will ultimately be released as part of my open-source theme framework).</p>
<p>I&#8217;ll go through the code piece by piece in my next post, the <a href="http://alisothegeek.com/2011/01/wordpress-settings-api-tutorial-1/">Extended WordPress Settings API Tutorial</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://alisothegeek.com/2010/12/meet-the-wordpress-settings-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>5 tips on writing WordPress plugins &quot;the right way&quot;</title>
		<link>http://alisothegeek.com/2010/01/tips-on-writing-wordpress-plugins-the-right-way/</link>
		<comments>http://alisothegeek.com/2010/01/tips-on-writing-wordpress-plugins-the-right-way/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 03:31:40 +0000</pubDate>
		<dc:creator>Alison Barrett</dc:creator>
				<category><![CDATA[Plugins]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[localization]]></category>
		<category><![CDATA[wpdb]]></category>
		<category><![CDATA[wp_enqueue_script]]></category>

		<guid isPermaLink="false">http://alisothegeek.com/?p=511</guid>
		<description><![CDATA[Just like many fellow programmers out there, when I first started publishing my own code for the world to see and use, it wasn’t the greatest. I didn’t fully understand the WordPress API and all the tools it had to offer. I have since learned a lot about how to write WordPress plugins “the right way”—the most efficient, clean, and safe way, that is. WordPress has functions, classes, and hooks that work right out of the box to make plugins easier to code and less risky to use. Here are a few of my favorite tips.]]></description>
			<content:encoded><![CDATA[<p>Just like many fellow programmers out there, when I first started publishing my own code for the world to see and use, it wasn&#8217;t the greatest. I didn&#8217;t fully understand the WordPress API and all the tools it had to offer. I have since learned a lot about how to write WordPress plugins &#8220;the right way&#8221;—the most efficient, clean, and safe way, that is. WordPress has functions, classes, and hooks that work right out of the box to make plugins easier to code and less risky to use. Here are a few of my favorite tips.</p>
<h3 id="1-use-the-wpdb-object-for-all-database-queries">1. Use the <a href="http://codex.wordpress.org/Function_Reference/wpdb_Class">$wpdb object</a> for all database queries</h3>
<p>If you only read and follow one of these tips, make it this one. Setting up database connections with mysql_connect over and over again is a waste of code. If you&#8217;re in anything other than a standalone processing script, $wpdb is ready to go with just one line of code:</p>
<pre><code>global $wpdb;</code></pre>
<p>(If you are using a standalone script for something, just include two files to make $wpdb work: wp-load.php and wp-includes/wp-db.php.)</p>
<p>There are different functions for the $wpdb class to make different kinds of database queries (see <a href="http://codex.wordpress.org/Function_Reference/wpdb_Class">the WordPress codex page</a> for details on them all).</p>
<p>On average, I find that using $wpdb saves two to three lines of code for each time I make any sort of database query. For example, this:</p>
<pre><code>$name = mysql_real_escape_string($name);
$result = mysql_query("INSERT INTO $myplugin-&gt;categories_table (name) VALUES ('$name')");
if (!$result)
    die("Could not insert into database. ".mysql_error());</code></pre>
<p>turns into this:</p>
<pre><code>$wpdb-&gt;insert($myplugin-&gt;categories_table, array('name' =&gt; $name), array('%s'));</code></pre>
<p>One of the most important reasons to use $wpdb instead of mysql_query is that it automatically protects the database from MySQL injection attacks. <a href="http://codex.wordpress.org/Function_Reference/wpdb_Class#Protect_Queries_Against_SQL_Injection_Attacks">More details about that are on the codex page as well.</a></p>
<h3 id="2-call-jquery-using-wp_enqueue_script">2. Call jQuery using wp_enqueue_script</h3>
<p>One of the most frustrating things I&#8217;ve seen responsible for my WordPress plugins not working is that other plugins are calling jQuery the wrong way:</p>
<pre><code>&lt;script src="../../../wp-includes/js/jquery/jquery.js" type="text/javascript"&gt;&lt;/script&gt;</code></pre>
<p>WordPress has its own way of handling calls to jQuery (and other common Javascript libraries). It&#8217;s called wp_enqueue_script. This is how WordPress would have you call jQuery in a plugin:</p>
<pre><code>wp_enqueue_script('jquery');</code></pre>
<p>So if WordPress itself needs to load jQuery, or an additional plugin calls it in this way, then it&#8217;s only loaded once, and it&#8217;s loaded in no-conflict mode. This means that there won&#8217;t be two jQuery scripts of different versions competing for attention. And if you prefer an external reference to jQuery (such as the one from Google Code), <a href="http://www.ericmmartin.com/5-tips-for-using-jquery-with-wordpress/">there is a method for doing that in a WordPress-friendly way, too (see step 2 on this linked page).</a></p>
<h3 id="3-use-unique-class-function-names">3. Use unique class &amp; function names</h3>
<p>If you have a function in your plugin called &#8220;load()&#8221;, then what happens if another plugin is activated on a user&#8217;s blog that uses a function called &#8220;load()&#8221;? Well, crap explosions happen. Plugins break. Solving this problem is easy: name all your functions something unique to your plugin. My personal method is to come up with a two- or three-letter representation of my plugin (like &#8220;sm&#8221; for SimpleMap) and use that as a prefix to all my function names. For example:</p>
<pre><code>sm_display_map()</code></pre>
<p>Easy as pie.</p>
<h3 id="4-prep-all-text-for-localization-from-the-get-go">4. Prep all text for localization from the get-go</h3>
<p>Even if you don&#8217;t include any translation files with your plugin, someone out there might want to write one for you (or for themselves). It&#8217;s pretty tedious to go back through your existing code and prep the text for translation, so make it a habit right away. First, you have to pick a key for your plugin&#8217;s translation files (this is usually just the plugin name or slug). Then you have to surround any text that gets displayed to the user with the following code:</p>
<pre><code>__('This is the text to be translated.', 'PluginKeyHere');</code></pre>
<p><em>Note: &#8216;PluginKeyHere&#8217; would be the key you picked. For example, in SimpleMap this is &#8216;SimpleMap&#8217;.</em></p>
<p>The double underscore at the beginning will return the translated string to PHP. If you want to echo the string, instead of adding echo before the double underscore, you can use this shorthand:</p>
<pre><code>_e('This is the text to be translated.', 'PluginKeyHere');</code></pre>
<p>More details on localizing your plugin can be found in <a href="http://codex.wordpress.org/I18n_for_WordPress_Developers">the WordPress codex.</a></p>
<h3 id="5-write-a-good-readme-file">5. Write a good README file</h3>
<p>This is something I highly recommend. When I&#8217;m searching for a plugin to install, an inadequate or poorly written README file will often make me go back to my search results and keep looking. Writing a good README file shows that you care about the people using your plugin. If you treat it like it&#8217;s just a step WordPress forces you to take to submit a plugin to the repository, it&#8217;s going to make you look like an ass, and users won&#8217;t want to try your plugin at all.</p>
<p>To top it off, Mark Jaquith has recently released a plugin that makes good use of your README files on your own blog. It&#8217;s called <a href="http://txfx.net/wordpress-plugins/i-make-plugins/">I Make Plugins</a>, and it automatically populates pages on your blog to promote the plugins you&#8217;ve created. You can <a href="http://alisothegeek.com/wordpress-plugins/">see it in action here on Aliso the Geek</a>.</p>
<p>Well, that&#8217;s all for now. More tips are sure to come in the future! If you have any suggestions, please leave a comment and share them!</p>
]]></content:encoded>
			<wfw:commentRss>http://alisothegeek.com/2010/01/tips-on-writing-wordpress-plugins-the-right-way/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

