<?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>SixCrayons &#187; plugin</title>
	<atom:link href="http://sixcrayons.com/tag/plugin/feed/" rel="self" type="application/rss+xml" />
	<link>http://sixcrayons.com</link>
	<description>non-toxic designing</description>
	<lastBuildDate>Mon, 12 Apr 2010 14:33:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>WordPress plugin template with settings page</title>
		<link>http://sixcrayons.com/2009/12/16/wordpress-plugin-template-with-settings-page/</link>
		<comments>http://sixcrayons.com/2009/12/16/wordpress-plugin-template-with-settings-page/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 18:04:55 +0000</pubDate>
		<dc:creator>steve</dc:creator>
				<category><![CDATA[Plugins]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[Template]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://sixcrayons.com/?p=2295</guid>
		<description><![CDATA[Over the past few months I&#8217;ve found myself working on a number of WordPress powered projects and as a result of this have ended [...]]]></description>
			<content:encoded><![CDATA[<p class="first">Over the past few months I&#8217;ve found myself working on a number of <a href="http://wordpress.org/" target="_blank">WordPress</a> powered projects and as a result of this have ended up writing a number of plugins to solve some of the problems I had encountered.</p>
<p>In order to keep each plugin standardised and at the same time speed up the development process, I decided to create a plugin template containing some the features commonly used. After de-constructing my existing plugins it was clear that one of the most common features was the inclusion of a settings page, so have included that in the template.</p>
<h3 class="title">Introduction</h3>
<p>If you haven&#8217;t glanced your eyes over the WordPress Codex yet, it&#8217;s recommend you start by taking a look at it&#8217;s introduction to <a href="http://codex.wordpress.org/Writing_a_Plugin" target="_blank">Writing a Plugin</a>. It outlines all the basic principles and practices of plugin development as well as linking to some other useful resources.</p>
<h3 class="title">The Template</h3>
<p>The <a href="http://sixcrayons.com/files/2009/12/myplugin.zip">template</a> assumes we are writing a plugin called &#8220;<strong>MyPlugin</strong>&#8220;, which does absolutely nothing (that&#8217;s your task for later) and is stored a directory called &#8220;<strong>myplugin</strong>&#8221; in the plugins folder (/wp-content/plugins/).</p>
<p>In this directory there are three files &#8211; <em>index.php</em>, <em>readme.txt</em> and <em>settings.php</em>.</p>
<p>It&#8217;s recommended that you <a href="http://sixcrayons.com/files/2009/12/myplugin.zip" target="_blank">download the files</a> first and take a look, however the following brief description should prove some insight into what&#8217;s there.</p>
<h3 class="title">readme.txt</h3>
<p>If you want to host your Plugin on http://wordpress.org/extend/plugins/, you need a readme.txt file which contains details about the plugin, who it was written by, current version etc.</p>
<pre>=== MyPlugin ===
Contributors: Steve Whiteley
Tags: my, plugin, template
Requires at least: 2.8.2
Tested up to: 2.9
Stable tag: 0.1

A short description of my plugin.

== Description ==

A longer description outlining some of the major features.

...</pre>
<h3 class="title">index.php</h3>
<p>If you open up index.php you will you see the core functionality of the plugin, the following will attempt to break it down a little and explain what it going on.</p>
<p>The first thing you will see are the comments at the top of the file:</p>
<pre>/*
Plugin Name: MyPlugin
Plugin URI: http://wordpress.org/extend/plugins/myplugin/
Description: A short description of the plugin that is displayed on the plugins overview page.
Version: 0.1
Author: SixCrayons
Author URI: http://sixcrayons.com
*/</pre>
<p>WordPress will use the details provided here when displaying the plugin within the admin panel.</p>
<p>Our plugin template is going to use a class based structure, my main reason behind this is that it provides a namespace for your functions and allowing for shorter function names and prevention of conflicts.</p>
<p>We are now going to begin writing our class, but first ensuring that there are no classes with the same name in existence:</p>
<pre>if (!class_exists('MyPlugin')) {
	class MyPlugin {
		var $name = 'MyPlugin'; // The name of your plugin used for display purposes.
		var $tag = 'myplugin'; // This should be the same value as the plugin directory.
		var $options = array(); // Will hold any settings the plugin has saved.
		function MyPlugin()
		{
			// Fetch any stored plugin options/settings...
			if ($options = get_option($this-&gt;tag)) {
				$this-&gt;options = $options;
			}
			...
		}
	}
	$myPlugin = new MyPlugin(); // Instantiates the plugin
}</pre>
<p>This is pretty much all we need to get the plugin appearing on the plugins list of the admin area, but we really want to add at least a small bit of functionality. Because this template assumes we are using a settings page, we want to make the settings as easy to get to as possible.</p>
<p>This can be done in two ways, adding a link under the plugins side menu and appending a link to the the plugin description on the plugins list. To do this we require two different hooks (admin_menu and plugin_row_meta) which we will add to out class initialisation function.</p>
<pre>function MyPlugin()
{
	if ($options = get_option($this-&gt;tag)) {
	...
	}
	if (is_admin()) { // Only if we are currently in the admin panel should we add these hooks...
		add_action('admin_menu', array(&amp;$this, 'admin_menu'));
		add_filter('plugin_row_meta', array(&amp;$this, 'plugin_row_meta'), 10, 2);
		...
	}
}
function admin_menu()
{
	// Add a link to the settings page under "Plugins" on the sidebar menu...
	add_submenu_page(
		'plugins.php',
		'Manage '.$this-&gt;name,
		$this-&gt;name,
		'administrator',
		$this-&gt;tag,
		array(&amp;$this, 'settings')
	);
}
function settings()
{
	// Include the settings page when we click on a settings link...
	include_once('settings.php');
}
function plugin_row_meta($links, $file)
{
	// Append a link the after the author URL on plugins list page...
	$plugin = plugin_basename(__FILE__);
	if ($file == $plugin) {
		return array_merge(
			$links,
			array(sprintf(
				'&lt;a href="plugins.php?page=%s"&gt;%s&lt;/a&gt;',
				$this-&gt;tag, __('Settings')
			))
		);
	}
	return $links;
}</pre>
<p>We now have two links in place which take you through to the settings page (settings.php). The example contains two options (&#8220;<em>Option One</em>&#8221; and &#8220;<em>Option Two</em>&#8220;) and uses the same template found elsewhere on the default settings pages.</p>
<h3 class="title">settings.php</h3>
<p>It also includes a message that is displayed when the settings have been saved.</p>
<p>A settings page requires the settings to be registered by calling <em>register_setting</em> and output <em>settings_fields</em> within the settings page form. Additionally the settings can be validated, but this step has not been included in the template.</p>
<p>The template also stores all the settings in a single options field, helping to keep the footprint of the plugin to a minimum.</p>
<h3 class="title">Summary</h3>
<p>I&#8217;d like to round this one off by saying this is certainly not the be all and end all of writing a plugin, however I do find it very useful to have all my plugins in a similar structure. The <a href="http://codex.wordpress.org/Plugin_API" target="_blank">Plugin API</a> still requires completion in some areas and finding the right hooks and filters can often take some effort, so hopefully this will help save you a fair amount of time.</p>
<p>If you can recommend any &#8220;best practices&#8221; for plugin development or have your own style then your ideas and feedback are very welcome <img src='http://sixcrayons.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<h3 class="title">Download the WordPress Plugin Template</h3>
<p><a href="http://sixcrayons.com/files/2009/12/myplugin.zip"><img class="alignnone size-full wp-image-2337" src="http://sixcrayons.com/files/2009/12/downloadfiles.jpg" alt="downloadfiles" width="615" height="87" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://sixcrayons.com/2009/12/16/wordpress-plugin-template-with-settings-page/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A simple jQuery input hint plug-in</title>
		<link>http://sixcrayons.com/2009/09/10/a-simple-jquery-input-hint-plug-in/</link>
		<comments>http://sixcrayons.com/2009/09/10/a-simple-jquery-input-hint-plug-in/#comments</comments>
		<pubDate>Thu, 10 Sep 2009 15:02:44 +0000</pubDate>
		<dc:creator>steve</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[hint]]></category>
		<category><![CDATA[input]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://sixcrayons.com/?p=319</guid>
		<description><![CDATA[A popular feature that can be found lot of web sites is the pre-population of form fields. When focusing on the input the default [...]]]></description>
			<content:encoded><![CDATA[<p class="first">A popular feature that can be found lot of web sites is the <strong>pre-population of form fields</strong>. When focusing on the input the default value is removed and when losing focus is replaced if the field value is left empty .</p>
<p>This tutorial will take you through the process of developing <strong>a simple jQuery input hint</strong> in an unobtrusive manner, allowing the form to function as expected when JavaScript is not enabled.</p>
<h3>Step One</h3>
<p>Before we start on the plug-in itself, we need some basic HTML defining our form.</p>
<pre>&lt;form method="get" action=""&gt;
	&lt;input type="text" value="" title="Search..." name="s" id="s" /&gt;
	&lt;input type="submit" value="Search" /&gt;
&lt;/form&gt;</pre>
<h3>Step Two</h3>
<p>The first stage of plug-in creation is setting up the <strong>basic plug-in structure</strong>. I tend to stick to the custom aliasing method as this will prevent conflicts with other libraries or frameworks and still allow us to make use of the &#8220;$&#8221; alias.</p>
<p>To achieve this, we execute an anonymous function, passing jQuery through and using &#8220;$&#8221; as the alias (although this could be any variable name), creating the fn and then enable chaining by looping through and returning each matched element.</p>
<pre>(function($) {
	$.fn.inputHint = function() {
		return this.each(function() {
			//...
		});
	};
})(jQuery);</pre>
<p>You can read more about plug-in authoring on the <a href="http://docs.jquery.com/Plugins/Authoring">jQuery site</a>.</p>
<h3>Step Three</h3>
<p>This plug-in is going to allow the default value to be defined by either passing it in as a set value or fetching the value from the title attribute of the input.</p>
<p>To achieve the first method we are going to use the <a href="http://docs.jquery.com/Utilities/jQuery.extend">extend method</a>, allowing us to globally set and re-define the customisations such as the hint value to use.</p>
<p>Here we take the globally defined values from the <strong>$.fn.inputHint.settings</strong> object and over-ride them with any values passed in by the <strong>callerSettings</strong> object. (Although we are using a deep / recursive merge in the example, it&#8217;s not totally necessary for this plug-in in it&#8217;s current state.)</p>
<pre>(function($) {
	$.fn.inputHint = function(callerSettings) {
		var settings = $.extend(true, {}, $.fn.inputHint.settings, callerSettings);
		return this.each(function() {
			//...
		});
	};
	$.fn.inputHint.settings = {
		value: false,
		className: false
	};
})(jQuery);</pre>
<h3>Step Four</h3>
<p>Now that we can define any custom options, let&#8217;s move on to actually doing something useful.</p>
<p>We need the ability to set the value of the input to the predefined value if the input is empty and clear the default value when the input receives focus.</p>
<p>Setting the default value if the input is empty:</p>
<pre>$(this).blur(function() {
	$(this).val($(this).val() == '' ? settings.value : $(this).val());
});</pre>
<p>Clearing the default value  on focus:</p>
<pre>$(this).focus(function() {
	$(this).val($(this).val() == settings.value ? '' : $(this).val());
});</pre>
<p>If we added these two events to our plug-in directly, it would look as follows:</p>
<pre>(function($) {
	$.fn.inputHint = function(callerSettings) {
		var settings = $.extend(true, {}, $.fn.inputHint.settings, callerSettings);
		return this.each(function() {
			$(this).blur(function() {
				$(this).val($(this).val() == '' ? settings.value : $(this).val());
			});
			$(this).focus(function() {
				$(this).val($(this).val() == settings.value ? '' : $(this).val());
			});
		});
	};
	$.fn.inputHint.settings = {
		value: false,
		className: false
	};
})(jQuery);</pre>
<p>We should however make use the chaining ability to cut down the amount of code we need to write.</p>
<p>The following introduces a couple of additions to go alongside the chaining, including the triggering of the blur event that will fire when the page loads and set the default value if necessary.</p>
<p>Here we have also included the ability to take the default value from the title attribute instead of the settings array <em>(see variable v)</em>.</p>
<pre>$.fn.inputHint = function(callerSettings) {
	var settings = $.extend(true, {}, $.fn.inputHint.settings, callerSettings);
	return this.each(function() {
		var n = $(this), v = settings.value || $(this).attr('title');
		n.focus(function() {
			n.val(n.val() == v ? '' : n.val());
		})
		.blur(function() {
			n.val(n.val() == '' ? v : n.val());
		})
		.blur();
	});
};</pre>
<p>Using what has been written so far will provide us with a working version, but there are a few additions.</p>
<p>We should unset the default value when the form is submitted, as most back end scripts will be checking against an empty value. This can be achieved by checking the existence of a parent form and unsetting the default value on submission by triggering the focus event.</p>
<p>The second addition is the ability to add and remove a class name to the input,  so we can set a style when the default value is present and a class name is defined <em>(see addClass and removeClass)</em>.</p>
<h3>Step Five: The Completed Plug-in:</h3>
<pre>(function($) {
	$.fn.inputHint = function(callerSettings) {
		var settings = $.extend(true, {}, $.fn.inputHint.settings, callerSettings);
		return this.each(function() {
			var n = $(this), v = settings.value || $(this).attr('title'), f = $(this.form);
			n.focus(function() {
				n.val(n.val() == v ? '' : n.val())
					.removeClass(settings.className);
			})
			.blur(function() {
				n.val(n.val() == '' ? v : n.val())
					.addClass(settings.className);
			})
			.blur();
			if (f) {
				f.submit(function(e) {
					n.trigger('focus');
				});
			}
		});
	};
	$.fn.inputHint.settings = {
		value: false,
		className: false
	};
})(jQuery);</pre>
<p>To make the whole effect work, add either of the following snippets to your page or script.<br />
The first will attempt to use the title attribute as there are no custom settings.</p>
<pre>$(function() {
	$('#s').inputHint();
});</pre>
<p>The second specifies a defined hint value and a class to add to the input when the hint is visible, which are passed through in the settings object.</p>
<pre>$(function() {
	$('#s').inputHint({
		value: "Search",
		className: 'faded'
	});
});</pre>
<p>You should place the plug-in inside a file called jquery.inputHint.js and include this file in your page, this conforms to the jQuery <a href="http://docs.jquery.com/Plugins/Authoring">plug-in author guidelines</a> (&#8220;Name your file jquery.[insert name of plugin].js&#8221;).</p>
<h3><strong>Additional Notes</strong></h3>
<p>This is just one method of achieving an input hint, an alternative method would be to use the the label tag instead of input and set the hint value based on this, or even place the label tag itself on top of the input.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixcrayons.com/2009/09/10/a-simple-jquery-input-hint-plug-in/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

