Nettuts+ » Wordpress http://net.tutsplus.com Web Development & Design Tutorials Fri, 19 Mar 2010 22:35:57 +0000 http://wordpress.org/?v=2.9.2 en hourly 1 10 Features to Look Forward to in WordPress 3.0 http://net.tutsplus.com/tutorials/wordpress/10-features-to-look-forward-to-in-wordpress-3-0/ http://net.tutsplus.com/tutorials/wordpress/10-features-to-look-forward-to-in-wordpress-3-0/#comments Tue, 16 Mar 2010 16:48:35 +0000 Rohan Mehta http://net.tutsplus.com/?p=10101 WordPress 3.0 is scheduled to be released within the next 30-60 days. There are some great new features coming, including custom post types, a new default theme, and a menu manager. Read on to find out what to expect in version three!

1. Choose your Username and Password

You’ll encounter new features as soon as you start! Currently, when you first install WordPress, you are assigned a default username of admin, and a randomly generated password. No more – now WordPress lets you choose a username and password when installing.

What does this mean for us?

This means that security within WordPress has been enhanced. Previously, a hacker could probably depend on the fact that there was a username called ‘admin’. This will no longer be the case in version three. Read any tutorial on securing WordPress – you will always be told to remove the admin username. You no longer need to!


2. New Default Theme!

WordPress 3.0 comes with a new default theme, called TwentyTen (2010, like the current year – go figure). Apparently, the WP team has an aim to release a new default theme every year! TwentyTen is a nice theme. The main typeface used is Georgia; it has two columns, with a widgetized sidebar and footer – and it even has some nice dropdown menus built in! Needless to say, custom header and background (new feature) functions are also available.

What does this mean for us?

We start off with a nice new theme, and bloggers have more options to try out before they start looking for themes. More options are always helpful, right?


3. Custom Background Support

WordPress 3.0 adds custom background support. Add the code below to your functions.php to make your theme support it:

add_custom_background();

Once that’s done, you’ll see an option called Background added under Appearance in the WordPress admin. This will allows you to upload a header image and customize it.

What does this mean for us?

This doesn’t really mean much to advanced theme developers, since they often provide an option like this themselves. Nevertheless, I have no doubt that the WordPress community will come up with some creative uses for this.


4. Multi-site Capabilities and WPMU Codebase Merge

WordPress and WPMU (WordPress MultiUser) are merging their codebases. This makes it much easier to handle large WordPress networks. See the Multi-Site settings under Settings>Network.

What does this mean for us?

A lot! A network of WordPress sites is much easier to maintain – either with a subdomain.domain.com structure, or a domain.com/subdirectory structure. This network capability is optional, and WordPress and WPMU users shouldn’t face any difficulties while upgrading. Also, this makes it easier for WPMU users to utilize plugins – no more plugins that go bust or stop working.


5. Custom Post Types

A great new feature! Before, all you could add from the WordPress admin section was new posts and pages. Now, you can create new post types to show up. Add the following code to create a new post type called ‘Portfolio’:

function post_type_portfolio() {
	register_post_type( 'Portfolio',
                array( 'label' => __('Portfolio'), 'public' => true, 'show_ui' => true ) );
	register_taxonomy_for_object_type('post_tag', 'Portfolio');
}

add_action('init', 'post_type_portfolio');

What does this mean for us?

Quite simply, it means WordPress has become much more of a CMS. This holds unlimited possibilities for theme developers, and reduces the need to fiddle around with custom fields.


6. Custom Taxonomies

Custom taxonomies have been made easier to use, as well as hierarchical – which means you could have a taxonomy called ‘Rating’, with sub-taxonomies like PG-13, R , U etc.

What does this mean for us?

It means that WordPress is moving more and more from a blog-type CMS, with effort required for better capabilities, to a much more flexible and usable Content Management System.


7. Easy Menu Management

This is my favorite new feature in WordPress 3.0 – a menu manager. It’s developed by WooThemes’ WooNav, and I absolutely love it. You can create multiple menus, categories, and even custom external or internal links! The menu feature even comes with a default widget to add to any widget ready area – awesome, isn’t it?

What does this mean for us?

On the surface, this provides us a great UI (user interface) for adding new menus, it simplifies the job of WordPress theme developers and makes things as simple as possible for users. Benearth the surface, there is a lot more – this marks a point where commercial WordPress theme developers join hands with WordPress and contribute to it. A win-win situation for both, and an incentive to continue working.


8. A Bunch of Other Smaller Features

  • Welcome guide: WordPress 3.0 will be including a guide with it which helps users to know the system better and teach them basic usage.
  • Specific author templates: We already have hierarchy for categories and tags like category-{slug}.php followed by category-{id}.php in the Template Hierarchy, but now you can do the same for authors. So, if the author name was ‘Rohan’ with id 1, WordPress would first look for author-rohan.php, then author-1.php before author.php in the template files for display.
  • Media UI redeign: Started, but not implemented in WordPress 2.9, the Media tab in the admin panel may get a UI redesign

Conclusion

The screenshots and features that I’ve written about here are taken from the most recent nightly build. You may want to try it out yourself, though keep in mind that it’s still unstable. Nevertheless, WordPress is evolving at a rate no one could have predicted, and is fully morphing into a powerful and flexible CMS.

]]>
http://net.tutsplus.com/tutorials/wordpress/10-features-to-look-forward-to-in-wordpress-3-0/feed/ 127
How to Create a Better WordPress Options Panel http://net.tutsplus.com/tutorials/wordpress/how-to-create-a-better-wordpress-options-panel/ http://net.tutsplus.com/tutorials/wordpress/how-to-create-a-better-wordpress-options-panel/#comments Tue, 16 Feb 2010 18:16:32 +0000 Rohan Mehta http://net.tutsplus.com/?p=9360 ]]> Today, we’ll go through the entire process of creating an admin options panel for a WordPress theme, using the excellent WooFramework as an example. Then, we’ll take things a step further, as we implement jQuery to improve some of the functionality.

Tutorial Details

  • Program: WordPress
  • Version: 2.7, 2.8, 2.9 onwards
  • Difficulty: Intermediate
  • Estimated Completion Time: 1.5 hours
Final Product

WordPress is one of the most popular Content Management Software (CMS) systems out there. Whether it be for a client project or for selling themes on ThemeForest, WordPress is fast emerging as a CMS of choice for many web developers. It’s relatively easy to use, but can be made even simpler when you include an administration panel for users. Rather than having to open up the PHP template files and fiddling with the code, users can directly use the options panel to interact with your WordPress theme.

For example – if your theme has red, blue and green color schemes, and each has a corresponding CSS file, it would be far easier for a user to select their preferred color from a dropdown list. So today, let me guide you through the entire process of creating and enhancing a WordPress admin panel page inspired by Woo.

Step 1

Before we begin creating the admin panel, we need to have a theme, right? So download the source files provided with the tutorial. I’ve slightly modified the Classic WordPress theme. Place the ‘nettuts’ folder (I’ve named the theme ‘Nettuts’) in your wp-content/themes folder. You should see the following files:

  • functions.php (blank)
  • index.php
  • comments.php
  • footer.php
  • header.php
  • rtl.php
  • sidebar.php
  • style.css
  • screenshot.png
  • An images folder with two files

Most of our work is going to be done within functions.php file.

A theme can optionally use a functions file, which resides in the theme subdirectory and is named functions.php. This file basically acts like a plugin, and if it is present in the theme you are using, it is automatically loaded during WordPress initialization (both for admin pages and external pages).

Suggested uses for this file:

  • Define functions used in several template files of your theme
  • Set up an admin screen, giving users options for colors, styles, and other aspects of your theme

(From the WP Codex)

Step 2

Now that we’ve got our WordPress theme set up, go to Appearance>Themes, and activate the nettuts theme.

Activated? Ok, great. Now we have to think of a layout for our admin panel page. Here’s the structure I’ve decided upon:

<div class="wrap rm_wrap">
	<div class="rm_opts">
		<form method="post">
			<div class="rm_section">
				<div class="rm_title>
					<h3>Title</h3>
					<submit button>
				</div>
				<div class="rm_input rm_<select/textarea/text etc>">
					<input area>
					<description>
				</div>
			</div>

			/*Repeat the inputs for as many options as required. */
			/* use <div class="rm_section"> for each new section of inputs eg General, Home Page etc */
		</form>
	</div>
</div>

Let me explain all of that to you. The options set is going to be wrapped up into a div named “rm_wrap” and then “rm_opts” for the options. Then we start a form, with all the inputs within it. Each section of options(general Settings, Homepage settings, Blog settings etc) has a separate div with a class of “rm_section”. This div has a title (for the name) as well as several input divs within it. By using classes like <div class=”rm_input rm_select”>, we can style dropdowns, text inputs, and textareas differently.

Now, the most important thing is that the coding of this shouldn’t be done manually – we should use PHP’s flexibility as much as possible. That means efficiency: don’t code manually when you have loops for you!

Step 3

Begin by opening up functions.php in your favorite code editor (I use Notepad++). Enter the following code:

<?php

$themename = "Nettuts";
$shortname = "nt";

The two PHP variables hold the name of your theme (Nettuts in our case), and a shortname which you’ve defined (nt in our case). The shortname is used to prefix all our theme options names, and is usually unique to a particular theme. Moving on, we’ll write some code to automatically generate a list of WordPress categories, rather than having users type in ID numbers. Enter the code below under the already typed code:

$categories = get_categories('hide_empty=0&orderby=name');
$wp_cats = array();
foreach ($categories as $category_list ) {
       $wp_cats[$category_list->cat_ID] = $category_list->cat_name;
}
array_unshift($wp_cats, "Choose a category");

This snippet uses WordPress’ built-in get_categories function to fetch all categories, and then uses a foreach loop to store them in the variable $wp_cats. The options “Choose a category” is then added to the top of the array

Step 4

Now we start entering a list of options for the theme. See below, and paste it into your functions.php file:


$options = array (

array( "name" => $themename." Options",
	"type" => "title"),

array( "name" => "General",
	"type" => "section"),
array( "type" => "open"),

array( "name" => "Colour Scheme",
	"desc" => "Select the colour scheme for the theme",
	"id" => $shortname."_color_scheme",
	"type" => "select",
	"options" => array("blue", "red", "green"),
	"std" => "blue"),

array( "name" => "Logo URL",
	"desc" => "Enter the link to your logo image",
	"id" => $shortname."_logo",
	"type" => "text",
	"std" => ""),

array( "name" => "Custom CSS",
	"desc" => "Want to add any custom CSS code? Put in here, and the rest is taken care of. This overrides any other stylesheets. eg: a.button{color:green}",
	"id" => $shortname."_custom_css",
	"type" => "textarea",
	"std" => ""),		

array( "type" => "close"),
array( "name" => "Homepage",
	"type" => "section"),
array( "type" => "open"),

array( "name" => "Homepage header image",
	"desc" => "Enter the link to an image used for the homepage header.",
	"id" => $shortname."_header_img",
	"type" => "text",
	"std" => ""),

array( "name" => "Homepage featured category",
	"desc" => "Choose a category from which featured posts are drawn",
	"id" => $shortname."_feat_cat",
	"type" => "select",
	"options" => $wp_cats,
	"std" => "Choose a category"),

array( "type" => "close"),
array( "name" => "Footer",
	"type" => "section"),
array( "type" => "open"),

array( "name" => "Footer copyright text",
	"desc" => "Enter text used in the right side of the footer. It can be HTML",
	"id" => $shortname."_footer_text",
	"type" => "text",
	"std" => ""),

array( "name" => "Google Analytics Code",
	"desc" => "You can paste your Google Analytics or other tracking code in this box. This will be automatically added to the footer.",
	"id" => $shortname."_ga_code",
	"type" => "textarea",
	"std" => ""),	

array( "name" => "Custom Favicon",
	"desc" => "A favicon is a 16x16 pixel icon that represents your site; paste the URL to a .ico image that you want to use as the image",
	"id" => $shortname."_favicon",
	"type" => "text",
	"std" => get_bloginfo('url') ."/favicon.ico"),	

array( "name" => "Feedburner URL",
	"desc" => "Feedburner is a Google service that takes care of your RSS feed. Paste your Feedburner URL here to let readers see it in your website",
	"id" => $shortname."_feedburner",
	"type" => "text",
	"std" => get_bloginfo('rss2_url')),

array( "type" => "close")

);

That was a large chunk of code, which surely warrants some explanation. So here we go:

  • The PHP variable $options stores the entire list of options for the theme.
  • It is composed of a number of arrays, each with a “type” key to signify how it will be displayed, and what it does.
  • We start with a “type” => “title” array – this will be used to show the themename and a title at the top of the page
  • Each section (General, Homepage and Footer) has a separate list of options.
  • We start a new section by closing any previous sections, declaring a new section using array( "name" => "Footer",
    "type" => "section")
    and opening a new section.
  • Each option can have the options specified below:
    name: The name of the input field.
    desc: A short description explaining what it is to the user.
    id: the id of the field, prefixed by the shortname. It will be used to store as well as access the options.
    type: the input type – select, text or textarea
    options: used to declare an array of options for a select type input.
    std: the default input value, used if no other input is given.

Step 5

Try navigating to WordPress. You will see that there’s no option anywhere to actually view the admin panel page; so how can we view it? Add the following pieces of code to the functions.php file:

function mytheme_add_admin() {

global $themename, $shortname, $options;

if ( $_GET['page'] == basename(__FILE__) ) {

	if ( 'save' == $_REQUEST['action'] ) {

		foreach ($options as $value) {
		update_option( $value['id'], $_REQUEST[ $value['id'] ] ); }

foreach ($options as $value) {
	if( isset( $_REQUEST[ $value['id'] ] ) ) { update_option( $value['id'], $_REQUEST[ $value['id'] ]  ); } else { delete_option( $value['id'] ); } }

	header("Location: admin.php?page=functions.php&saved=true");
die;

}
else if( 'reset' == $_REQUEST['action'] ) {

	foreach ($options as $value) {
		delete_option( $value['id'] ); }

	header("Location: admin.php?page=functions.php&reset=true");
die;

}
}

add_menu_page($themename, $themename, 'administrator', basename(__FILE__), 'mytheme_admin');
}

function mytheme_add_init() {

}

This function is meant for updating options, as well as adding a menu page. If the options are being saved (indicated by a hidden variable save), then all the options are updated with their new values. If the options are being reset (indicated by another hidden variable with a value reset), then all of the options are deleted. The last line adds a menu page – the parameters are respectively, name and title, the user authorization level required to view the page, the save page and the function used for display/saving (called mytheme_admin in our case). See the mytheme_add_init, a blanbk function? Let that be, we’ll come to it later.

Step 6

Still no theme options page, right? Well, remember the mytheme_admim function we had talked about a few lines ago? We still haven’t written that function. So use the code from steps 6,7 and 8 to write that function. Starting off:

function mytheme_admin() {

global $themename, $shortname, $options;
$i=0;

if ( $_REQUEST['saved'] ) echo '<div id="message" class="updated fade"><p><strong>'.$themename.' settings saved.</strong></p></div>';
if ( $_REQUEST['reset'] ) echo '<div id="message" class="updated fade"><p><strong>'.$themename.' settings reset.</strong></p></div>';

?>
<div class="wrap rm_wrap">
<h2><?php echo $themename; ?> Settings</h2>

<div class="rm_opts">
<form method="post">

Pretty simple, right? If the options have been saved, write a message indicating so. Likewise for resets. You’ll notice a class=”updated fade” – WordPress will automatically fade this out in a few sections. Nifty, right? Moving on, we then start the “rm_wrap” div.

Step 7

Carrying on from above, paste in the following code:

<?php foreach ($options as $value) {
switch ( $value['type'] ) {

case "open":
?>

<?php break;

case "close":
?>

</div>
</div>
<br />

<?php break;

case "title":
?>
<p>To easily use the <?php echo $themename;?> theme, you can use the menu below.</p>

<?php break;

case 'text':
?>

<div class="rm_input rm_text">
	<label for="<?php echo $value['id']; ?>"><?php echo $value['name']; ?></label>
 	<input name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>" type="<?php echo $value['type']; ?>" value="<?php if ( get_settings( $value['id'] ) != "") { echo stripslashes(get_settings( $value['id'])  ); } else { echo $value['std']; } ?>" />
 <small><?php echo $value['desc']; ?></small><div class="clearfix"></div>

 </div>
<?php
break;

case 'textarea':
?>

<div class="rm_input rm_textarea">
	<label for="<?php echo $value['id']; ?>"><?php echo $value['name']; ?></label>
 	<textarea name="<?php echo $value['id']; ?>" type="<?php echo $value['type']; ?>" cols="" rows=""><?php if ( get_settings( $value['id'] ) != "") { echo stripslashes(get_settings( $value['id']) ); } else { echo $value['std']; } ?></textarea>
 <small><?php echo $value['desc']; ?></small><div class="clearfix"></div>

 </div>

<?php
break;

case 'select':
?>

<div class="rm_input rm_select">
	<label for="<?php echo $value['id']; ?>"><?php echo $value['name']; ?></label>

<select name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>">
<?php foreach ($value['options'] as $option) { ?>
		<option <?php if (get_settings( $value['id'] ) == $option) { echo 'selected="selected"'; } ?>><?php echo $option; ?></option><?php } ?>
</select>

	<small><?php echo $value['desc']; ?></small><div class="clearfix"></div>
</div>
<?php
break;

case "checkbox":
?>

<div class="rm_input rm_checkbox">
	<label for="<?php echo $value['id']; ?>"><?php echo $value['name']; ?></label>

<?php if(get_option($value['id'])){ $checked = "checked=\"checked\""; }else{ $checked = "";} ?>
<input type="checkbox" name="<?php echo $value['id']; ?>" id="<?php echo $value['id']; ?>" value="true" <?php echo $checked; ?> />

	<small><?php echo $value['desc']; ?></small><div class="clearfix"></div>
 </div>
<?php break;

That is one large piece of code! Explanation – using a php foreach loop, each option type is evaluated on a case-by-case basis. We use a switch-case technique for this. The switch variable is the options – the cases are matched and evaluated. Notice the ‘break’ statement after each case? This is to prevent something known as the ‘fall-through’ property. When a case is matched, all successive cases are also executed. This means that if we match case 3, cases 4,5 etc. are also executed. We don’t wan’t that, right? So use a break to stop the switch-case.

If there is an “open” type option – nothing is done. If there is a “close” type options, two divs are closed. The “title” option is only used once – it is an introduction to the theme options. For each of the types “text” (input type=”text”), “select” (dropdowns), “checkbox” and “textarea” (its obvious what those mean), the corresponding input is displayed. Notice the <div class=”clearfix”> – it’s used for clearing floats, which we will do later.

Step 8

We’re coming to the end of that rather massive function. Paste in the code below:


case "section":

$i++;

?>

<div class="rm_section">
<div class="rm_title"><h3><img src="<?php bloginfo('template_directory')?>/functions/images/trans.gif" class="inactive" alt="""><?php echo $value['name']; ?></h3><span class="submit"><input name="save<?php echo $i; ?>" type="submit" value="Save changes" />
</span><div class="clearfix"></div></div>
<div class="rm_options">

<?php break;

}
}
?>

<input type="hidden" name="action" value="save" />
</form>
<form method="post">
<p class="submit">
<input name="reset" type="submit" value="Reset" />
<input type="hidden" name="action" value="reset" />
</p>
</form>
<div style="font-size:9px; margin-bottom:10px;">Icons: <a href="http://www.woothemes.com/2009/09/woofunction/">WooFunction</a></div>
 </div> 

<?php
}

?>

For a “section” type option, I’ve used a counter variable $i. This keeps track of the sections number and conactenates it to the name of the submit button, to have unique submit buttons. There is also a last form at the end for resetting all options. The image used is going to be a transparent image used in our jQuery-fication. Use this very last piece of code to bring our functions into play:

<?php
add_action('admin_init', 'mytheme_add_init');
add_action('admin_menu', 'mytheme_add_admin');
?>

That tells WordPress to add the admin menu.

Step 9

And voila! We have our own awesome admin panel page with a separate menu position for itself. So let’s check it out – click the link. And yuck. That has got to be the most ugly admin panel page ever. So let’s call upon our good friend, CSS! Create a new folder in the nettuts/ directory and name it “functions”. Create a new CSS file there – functions.css. Paste in the following code:

.rm_wrap{
	width:740px;
}
.rm_section{
	border:1px solid #ddd;
	border-bottom:0;
	background:#f9f9f9;
}
.rm_opts label{
	font-size:12px;
	font-weight:700;
	width:200px;
	display:block;
	float:left;
}
.rm_input {
	padding:30px 10px;
	border-bottom:1px solid #ddd;
	border-top:1px solid #fff;
}
.rm_opts small{
	display:block;
	float:right;
	width:200px;
	color:#999;
}
.rm_opts input[type="text"], .rm_opts select{
	width:280px;
	font-size:12px;
	padding:4px;
	color:#333;
	line-height:1em;
	background:#f3f3f3;
}
.rm_input input:focus, .rm_input textarea:focus{
		background:#fff;
}
.rm_input textarea{
	width:280px;
	height:175px;
	font-size:12px;
	padding:4px;
	color:#333;
	line-height:1.5em;
	background:#f3f3f3;
}
.rm_title h3 {
	cursor:pointer;
	font-size:1em;
	text-transform: uppercase;
	margin:0;
	font-weight:bold;
	color:#232323;
	float:left;
	width:80%;
	padding:14px 4px;
}
.rm_title{
	cursor:pointer;
	border-bottom:1px solid #ddd;
	background:#eee;
	padding:0;
}
.rm_title h3 img.inactive{
	margin:-8px 10px 0 2px;
	width:32px;
	height:32px;
	background:url('images/pointer.png') no-repeat 0 0;
	float:left;
	-moz-border-radius:6px;
	border:1px solid #ccc;
}
.rm_title h3 img.active{
	margin:-8px 10px 0 2px;
	width:32px;
	height:32px;
	background:url('images/pointer.png') no-repeat  0 -32px;
	float:left;
	-moz-border-radius:6px;
	-webkit-border-radius:6px;
	border:1px solid #ccc;
}
.rm_title h3:hover img{
	border:1px solid #999;
}
.rm_title span.submit{
	display:block;
	float:right;
	margin:0;
	padding:0;
	width:15%;
	padding:14px 0;
}
.clearfix{
	clear:both;
}
.rm_table th, .rm_table td{
	border:1px solid #bbb;
	padding:10px;
	text-align:center;
}
.rm_table th, .rm_table td.feature{
	border-color:#888;
	}

I won’t explain anything here; it’s pretty clear what each CSS declaration does, and you’re free to customize the layout for your own theme.

Step 10

So now we have a nice CSS file. But how do we add it to the page? After all, we don’t have direct access to the <head> of the document. Remember that blank mytheme_add_init() function we wrote in Step 4? That will come in handy. Change it to this:

function mytheme_add_init() {
$file_dir=get_bloginfo('template_directory');
wp_enqueue_style("functions", $file_dir."/functions/functions.css", false, "1.0", "all");
}

That adds the functions.css file to the head. The location of the file is determined by the template directory.

Step 11

Go look at the page now. Pretty nice looking, isn’t it? But then, you ask, whats the ‘+’ icon for? Well, thats where jQuery comes in!. Create a new file rm_script.js in the nettuts/functions/ folder. Paste in the following code:

jQuery(document).ready(function(){
		jQuery('.rm_options').slideUp();

		jQuery('.rm_section h3').click(function(){
			if(jQuery(this).parent().next('.rm_options').css('display')==='none')
				{	jQuery(this).removeClass('inactive').addClass('active').children('img').removeClass('inactive').addClass('active');

				}
			else
				{	jQuery(this).removeClass('active').addClass('inactive').children('img').removeClass('active').addClass('inactive');
				}

			jQuery(this).parent().next('.rm_options').slideToggle('slow');
		});
});

What this does is – once the DOM loads, all the rm_options slide up. When the ‘+’ icon is clicked, the inactive class is removed from the image and the active class added – making it a ‘-’ icon. The reverse is done when the ‘-’ icon is clicked. The rm_options is then slid up or down(determined by the current CSS state) using the slideToggle function – pretty simple. To add this script, the same mytheme_add_init() function is used. Change it to:

function mytheme_add_init() {
$file_dir=get_bloginfo('template_directory');
wp_enqueue_style("functions", $file_dir."/functions/functions.css", false, "1.0", "all");
wp_enqueue_script("rm_script", $file_dir."/functions/rm_script.js", false, "1.0");
}

The jQuery script will now be active. Gp check it out. Personally, I think its beautiful!

Step 12

Now that we have our theme options page all set up, I’ll just run you through using the options. The code to use the options is as follows:

$var = get_option('nt_colur_scheme');

That will fetch the nt_color_scheme options. See the examples below:

/* To change the CSS stylesheet depending on the chosen color */
<link rel="stylesheet" type="text/css"  href="<?php bloginfo('template_directory'); ?>/<?php echo get_option('nt_color_scheme'); ?>.css" /> 

/*To echo some footer copyright text, with HTML */
<p><?php echo stripslashes(get_option('bl_footer_text')); ?></p>

The variety of uses is limited only by your imagination.

Conclusion

I hope you’ve learned something in this tutorial. This isn’t your standard options panel. This one doesn’t use tables, it’s jQuery enhanced, uses awesome CSS, and is extremely easy to use. The point of this tutorial is to learn – you could always replace collapsible panels with tabs, for example, or even something more advanced. Use your creativity! Feel free to discuss or ask questions in the comments!

WooThemes has since released version two of their framework. You can review the details here.

]]>
http://net.tutsplus.com/tutorials/wordpress/how-to-create-a-better-wordpress-options-panel/feed/ 96
Quick Tip: How to Use the New “Post-Thumbnail” Feature in WordPress 2.9 http://net.tutsplus.com/tutorials/wordpress/quick-tip-how-to-use-the-new-post-thumbnail-feature-in-wordpress-2-9/ http://net.tutsplus.com/tutorials/wordpress/quick-tip-how-to-use-the-new-post-thumbnail-feature-in-wordpress-2-9/#comments Thu, 04 Feb 2010 07:58:58 +0000 Jeffrey Way http://net.tutsplus.com/?p=9096 ]]> Up until the release of WordPress 2.9, setting up “post-image” support for your blog was a bit more tedious a task than it really needed to be. Luckily, that’s no longer an issue. I’ll show you how to get setup in this four minute video quick tip.

Step 1. Edit your Functions.php Page

// Enable support for post-thumbnails

add_theme_support('post-thumbnails');

// If we want to ensure that we only call this function if
// the user is working with WP 2.9 or higher,
// let's instead make sure that the function exists first

if ( function_exists('add_theme_support') ) {
	add_theme_support('post-thumbnails');
}

Step 2. Insert the Image Tag into your Loop

Within the “if have_posts()” loop, simply place this piece of code anywhere you like. At that point, WordPress will insert an image tag onto the page accordingly. Please note that you’ll have access to a “wp-post-image” class that you may then work with to format/style the image.

<?php the_post_thumbnail(); ?>
]]>
http://net.tutsplus.com/tutorials/wordpress/quick-tip-how-to-use-the-new-post-thumbnail-feature-in-wordpress-2-9/feed/ 54
The Definitive Guide to Securing WordPress: New Premium Tutorial http://net.tutsplus.com/tutorials/wordpress/the-definitive-guide-to-securing-wordpress-new-plus-tutorial/ http://net.tutsplus.com/tutorials/wordpress/the-definitive-guide-to-securing-wordpress-new-plus-tutorial/#comments Thu, 30 Jul 2009 17:27:51 +0000 John Pratt http://net.tutsplus.com/?p=6034 ]]> In this Premium tutorial and screencast, you’ll learn how to protect your website from hackers, spammers, automated software, and bots that run rampant online. WordPress is by far the most popular self-hosted blogging solution, and for that very reason, it’s also one of the most targeted for vulnerabilities. You may be surprised how easy it is to take preventative measures to protect your site. Sign up today!

Join Tuts Plus

NETTUTS+ Screencasts and Bonus Tutorials

For those unfamiliar, the family of TUTS sites runs a premium membership service called “Premium”. For $9 per month, you gain access to exclusive premium tutorials, screencasts, and freebies at nettuts+, psdtuts+, and vectortuts+! For the price of a pizza, you’ll learn from some of the best minds in the business. Join today!

  • Subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.


]]>
http://net.tutsplus.com/tutorials/wordpress/the-definitive-guide-to-securing-wordpress-new-plus-tutorial/feed/ 27
10 WordPress 2.8 Features To Look Out For http://net.tutsplus.com/tutorials/wordpress/10-wordpress-28-features-to-look-out-for/ http://net.tutsplus.com/tutorials/wordpress/10-wordpress-28-features-to-look-out-for/#comments Fri, 19 Jun 2009 22:34:43 +0000 Andrew Turner http://net.tutsplus.com/?p=5513 ]]> It’s a great achievement for WordPress 2.8 to be released so soon after 2.7. Named ‘Baker’, 2.8 adds plenty of new features, including syntax highlighting for theme/plugin editing, a theme installer, and a great revamped widgets interface and API.

1. Dashboard Columns

You can now sort your dashboard into columns, which is a great feature for those who are small or large on screen space. You can set up to 4 columns and drag and drop different widgets. I found it to be a good feature as I like re-arrange my dashboard and management pages to suit my workspace. This will surely appeal to many users.

2. Password Reminder

Just installed WordPress? This is the feature for those that forget to change their admin account password after a fresh install. It displays a big notice across the top of the admin area until you change it.

3. Theme Installer

In WordPress 2.7, you could install plugins directly through your installation. Now, the same feature has been ported to themes, allowing you to install any theme directory into your WordPress site. Installing is as easy as installing plugins — through the click of a button.

4. Theme/Plugin Editor – Syntax Highlighter & Function Reference

This is a feature that I’ve been looking forward to, along with many other developers. WordPress now has syntax highlighting thanks to CodePress. This means you can find functions and browse through code much easier, as you would with your code editor.

You’ll also find a Documentation lookup, as so you can quickly reference WordPress functions through the Codex. These new features will speed up development of WordPress themes even further by having the tools right in front of you for quick & easy access.

5. Widgets Interface

WordPress’ widgets management interface was a bit plain and simple. That’s no longer true with the brand new widgets interface allowing you to sort and manage your theme’s widgets more efficiently. It still uses the drag and drop method of adding/removing widgets, but takes the active/inactive widgets one step further separating them from each other.

6. Widgets API

Creating widgets is now easier than ever before with the new widgets API. All you have to do is extend the basic class and functions, and you can easily create a widget with options and more. Here’s an example widget using the new API; it’s been coded to allow the user to set the title, but display predefined content.

<?php
/*
Plugin Name: Example Widget
Plugin URI:
Description: An example widget using the WordPress 2.8 Widget API.
Version: 1.0.0
Author: Andrew Turner
Author URI: http://andrew-turner.com
*/
class exWidget extends WP_Widget {
    /* Constructs Widget */
    function exWidget() {
        parent::WP_Widget(false, $name = 'exWidget');
    }

    /* Widget Base */
    function widget($args, $instance) {
        extract( $args );
        ?>
              <?php echo $before_widget; ?>
                  <?php echo $before_title
                      . $instance['title']
                      . $after_title; ?>
                  <?php echo 'Hello There!' ?>
              <?php echo $after_widget; ?>
        <?php
    }

    function update($new_instance, $old_instance) {
        return $new_instance;
    }

    /* Options Form */
    function form($instance) {
        $title = esc_attr($instance['title']);
        ?>
            <p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" /></label></p>
        <?php
    }
}
/* Register Widget */
add_action('widgets_init', create_function('', 'return register_widget("exWidget");'));
?>

7. Timezones and DST

WordPress now supports timezones, and the ability to automatically update when it comes around to daylight savings. This is a new feature, and was not found in previous versions.

8. Custom Taxonomies

A Taxonomy is essentially a way that things are grouped or divided. WordPress 2.8 improves upon its Taxonomies by allowing you to develop your own. By default, WordPress includes three of its own.

  • category
  • post_tag
  • link_category

Uses for custom taxonomies might include making post series or more. Here’s an example of creating a custom taxonomy, the code is placed in your theme’s functions.php file.

<?php
add_action( 'init', 'custom_taxonomies', 0 );
function custom_taxonomies() {
	register_taxonomy( 'version', 'post', array( 'hierarchical' => false, 'label' => 'Version', 'query_var' => true, 'rewrite' => true ) );
	register_taxonomy( 'released', 'post', array( 'hierarchical' => true, 'label' => 'Released', 'query_var' => true, 'rewrite' => true ) );
	register_taxonomy( 'downloads', 'post', array( 'hierarchical' => false, 'label' => 'Downloads', 'query_var' => true, 'rewrite' => true ) );
}
?>

To understand how to create your own taxonomy, you need to understand what’s behind the code. Here’s a breakdown of the following example:

	register_taxonomy( 'version', 'post', array( 'hierarchical' => false, 'label' => 'Version', 'query_var' => true, 'rewrite' => true ) );
  • version : Tells WordPress the name of your taxonomy.
  • post : Tells WordPress what type of content this applies to; you could apply your taxonomy to pages or even links if you wanted too. Though WordPress handles custom taxonomies with posts best.
  • hierarchical : Asks whether the taxonomy’s terms can be shown in a hierarchy (A hierarchy is setup like a tree of items, eg: categories.). You can set this to true for the terms to be organized like categories, or false for them to behave like tags.
  • label : The name of your taxonomy that will be seen in the WordPress admin for posts, pages or links.
  • query_var : A parameter that lets WordPress know if you want to retrieve your posts through a query — for example showing all posts which relate to the product released in 2008. If you’ve set your taxonomy so you can query it, remember the variable for the query will be the name of your taxonomy.
  • rewrite : Whether you’d like to allow WordPress to use your permalink structure when viewing the archives or taxonomy page. Eg, instead of yourproduct.net/?released=2008 it could become yourproduct.com/released/2008.

9. Faster Administration Pages

The WordPress team have sped up the administration pages (E.g: Posts, Comments, Settings, etc) through script compression and concatenation. Now, you can perform tasks quicker and easier. Take note of the fact that this feature doesn’t apply to the front end of your WordPress website.

10. Plugin Management Updated

The plugin management interface that allows you to activate and deactivate plugins has been updated with a new layout – it still heralds the same features as in WordPress 2.7, but with a different layout. You’ll find that they’ve been put together in a list on the single page, but there’s an option to view different statuses such as:

  • Active
  • Inactive
  • Recently Active
  • Upgrade Available

WordPress 2.8 brings some great new features to the table – some major and others minor – but they’re changes that make using WordPress more efficient, convenient and reliable. Keep an eye out for WordPress 2.9 and beyond as it evolves into what could be one of the best Content-Management-Systems available!


]]>
http://net.tutsplus.com/tutorials/wordpress/10-wordpress-28-features-to-look-out-for/feed/ 67
How to Set Up a Killer WordPress Testing Environment Locally http://net.tutsplus.com/tutorials/wordpress/how-to-set-up-a-killer-wordpress-testing-environment-locally/ http://net.tutsplus.com/tutorials/wordpress/how-to-set-up-a-killer-wordpress-testing-environment-locally/#comments Thu, 21 May 2009 14:51:15 +0000 Harley http://net.tutsplus.com/?p=5065 ]]> If you’re a heavy WordPress developer like me, you might find that you need to create a new installation for each site that requires a strange structure or specific posts, instead of using your uniform local test WordPress installation. Cue WordPress Mu. WordPress Multi User is a platform created by the geniuses at Automattic that is basically a WordPress installation that allows multiple blogs to run using the same software.

In this tutorial, I’m going to show you how to set up WordPress Mu locally so that it can be viewed in VMWare Fusion too, a piece of software that allows for cross-browser testing on Microsoft XP and Vista. Mac only, sorry, however I’m sure something similar can be done with the PC versions of MAMP.

Preface

Unfortunately this tutorial requires a few paid things, so it can get expensive. You’ll need MAMP PRO, Microsoft XP and VMWare Fusion- Only MAMP PRO is essential if you don’t need to cross-browser test. MAMP PRO has some functionality on MAMP that we need when defining our new developer site. Download WordPress MU as well, we’ll need that!

Note: MAMP PRO comes with MAMP- just stick both of them in Applications because you need the two.

Run Down

OK, so if you don’t know completely what we’ll be doing, I’m going to break it down further. If you use WordPress to develop your websites, then each time you create a new website you need to download a new installation of WordPress, install it, and go through that entire process just for a new site. This takes time AND hard drive space. What we’ll be doing, is setting up a type of WordPress installation that allows you to use the same WordPress files, and set up a new WordPress site via wp-admin instead of going through the famous 5 minute install.

At the end of the tutorial you’ll be able to visit http://wordpress.mu/ to see your local WordPress MU installation. You’ll also be able to open the same page in VMWare Fusion, which will be running Windows XP. This means you’ll be able to see it in ALL major browsers- IE5.5-8, Chrome, Safari Mac, Safari PC, Firefox Mac, Firefox PC, etc. The list goes on.

Step 1 – Changing Ports on MAMP PRO

Once you’ve installed MAMP PRO, open it up and the servers should start running. We need to change the ports. Ports are basically the ‘door’ that a server tells the browser to go through. You might be familiar with CPanelX’s port 8082. CPanel has told your server that to get to the CPanel, you need to go through door 8082. By default, MAMP PRO likes to have it’s own ports- 8888 for apache and 8889 for MySQL. We need to change this back to the default settings. You can either turn it to 80 / 3306 manually or simply click ‘Default Ports’

MAMP PRO will then tell you that the servers need to restart in order for changes to take effect. Click OK and let it do it’s thing. If it tells you that Apache’s failing to restart, check that ‘Web Sharing’ is un-ticked in your Sharing Prefs pane. You should now be able to visit http://localhost:80 to see either the ‘If you can see this page Apache is successfully installed’ page or the default MAMP index page. Great.

Step 2 – editing httpd.conf

httpd.conf is what Apache reads when it looks at what hosts or URLs to run on. You can find httpd.conf in ~/Applications/MAMP/conf/apache/httpd.conf

Scroll down to the very bottom, and you will probably find this:

<VirtualHost *>
	DocumentRoot "/Applications/MAMP/htdocs"
	ServerName localhost
</VirtualHost>

or nothing at all. We are going to add this, or change it to the following code. We’ll also be adding our own Virtual Host, which will be wordpress.mu (Just a side note, when doing this it’s important to never pick a URL that will conflict with an actual site, because while the settings are like you’ll never be able to visit your local site’s url online. e.g. if I set my host to be example.com, example.com would always resolve to my local machine as opposed to example.com online). So like I said, add this (or change the default one)

<VirtualHost *>
	DocumentRoot "/Users/YOU/wordpres.mu"
	ServerName localhost
</VirtualHost>

<VirtualHost *>
	DocumentRoot "/Users/YOU/Sites/wordpress.mu"
	ServerName http://wordpress.mu/
</VirtualHost>

Don’t forget to change YOU to your user name. This will also require a restart of the Apache and MySQL servers. You’ll probably notice that wordpress.mu doesn’t exist in your sites folder- so create it!

Step 3 – editing /etc/hosts

This file, hosts is the configuration for exactly that, the hosts. So httpd.conf set the hosts for your mac! This requires some Terminal work, but I promise you it’s as easy as copying and pasting the command, and then typing a single line!

Open Terminal (it’s in Utilities in the Applications folder) and type:

sudo pico /etc/hosts

And hit enter. sudo means it’s an admin action, pico is the Terminal’s editor (which you’ll soon see) and /etc/hosts is the path to what we want to edit. You’ll be prompted for your password, so type it in. You should now see this screen:

That last line may or may not be there- if it isn’t don’t worry we’ll be changing it anyway. Put the cursor at the bottom (clicking doesn’t work) and where that last line of code is, change localhost to wordpress.mu. It should read:

127.0.0.1 wordpress.mu

127.0.0.1 is the computer’s way of saying ‘me’. Save the file by pressing ctrl+o (o for write out and then ctrl+x to quit pico.

Step 4 – Adding a host for MAMP PRO

The final piece of the puzzle is to create a host alias in MAMP PRO. Now that the hosts are all set up, we need to tell MAMP PRO that it’s actually there. In MAMP PRO click on the ‘Hosts’ tab. You need to add an alias. Click the little plus in the bottom left. You need to set a few things. Server name: wordpress.mu, port: 80, Disk Location: /Users/YOU/Sites/wordpress.mu, and add an alias in the bottom right of wordpress.mu.

Click apply, and once again restart the servers

Step 5 – WordPress MU

Grab your wordpress-mu Download and rename it to wordpress.mu. Stick it in your sites folder. Hey presto, you can go through with the installation! Unfortunately I found no easy way to use sub-domains on a local server, so I just stuck to sub-folders as the structure. Great! You can now use WordPress mu on your local computer! Go ahead with the 5 minute install, and then you can add blogs under the ‘Admin Menu’. I wont go too much into the actual functionality of WPMU, but I’ll explain how I use when working at the end.

VMWare Fusion

I’m not going to go into depth on this topic, because there are many tutorials on it. I will however explain how to modify a brand new installation (even if you’ve used it for ages there probably isn’t a lot that will have changed anyway). Start up VMWare Fusion, and activate Unity if you so please. Unity allows you to run Windows XP windows natively in your mac- see screenshot below!

Step 6 – \etc\hosts (windows)

The /etc/hosts file in XP needs editing too. You can find it in C:\Windows\system32\drivers\etc\hosts. Open it up with Notepad, and we’re about to put our line in. We need to grab an IP address first. Open a new terminal window and type ifconfig -a. You will get a whole lot of junk back- scroll down a bit until you can see ‘vmnet8′. Grab that IP address, the one I’ve highlighted in the image below.

Then go back to your \etc\hosts file in windows, and at the bottom, paste that IP address in followed by wordpress.mu.

Step 7 – flushdns

Sadly, windows needs to be slapped for it to noticed that a change has taken place, so you now need to open Command Prompt. It is in Accessories in the start menu. Simply type ipconfig /flushdns. What this does is flush all the DNS names (localhost mainly) so that it recognises the updated hosts file.

Voila!

You are now able to visit your MAMP running WordPress MU installation on every windows browser there was- looks like I have a bit of work to do!

A practical use for it

So as promised, I said I’d tell you how I use it. What I’ve done is gone ahead and downloaded every browser I need/support and installed it into my XP install. This way I can compare my WordPress sites window beside window and easily have access to modify whatever I need to, without having to save it and refresh an online installation!

Take a Wrap

So there you have it. The ultimate guide to the ultimate WordPress setup. It feels like I haven’t put enough emphasis on WordPress MU itself, but it is just an install tutorial. WordPress MU saves loads and loads of disk space by taking all your separate WordPress blogs and putting them into 1- you have a universal theme folder/manager which makes it super easy to quickly swap between editing sites.


]]>
http://net.tutsplus.com/tutorials/wordpress/how-to-set-up-a-killer-wordpress-testing-environment-locally/feed/ 129
Dissecting the WordPress Text Widget http://net.tutsplus.com/tutorials/wordpress/dissecting-the-wordpress-text-widget/ http://net.tutsplus.com/tutorials/wordpress/dissecting-the-wordpress-text-widget/#comments Thu, 07 May 2009 09:20:47 +0000 Jarkko Laine http://net.tutsplus.com/?p=4720 ]]> In this tutorial, we will take a close look under the hood of the WordPress text widget to uncover the process of creating a widget that can be added to multiple widget locations.

The Problem

If you know the basics of programming in PHP, creating a WordPress widget is not difficult at all. I have covered the basics in an earlier tutorial, The Anatomy of a WordPress Plugin — it’s a good idea to check that one out before reading any further, if you haven’t built a widget before.

While that basic way of creating a widget is good enough for many plugins, it has one major drawback: the widget can be added to only one slot in a blog.

If you add the widget to one of the sidebars, the widget’s “Add” button disappears and the widget cannot be added to any other slot before removing it from the first one.


Notice how the “Archives” widget cannot be added anymore.

In some cases, that’s not a problem, because the nature of the widget is that it’s shown only once. For example, it’s quite OK to only list the blog archive in one place in the layout. But there are many cases where more than one instance can be very useful. One such example is the Text widget that comes bundled with WordPress.

The Text widget is a simple widget that lets you specify a header and a text, also allowing HTML, and renders its contents to the blog’s sidebar. Because of this simplicity, the widget can be used for a wide range of purposes. For example, in the next image — a screenshot from my personal blog — you can see how I use the text widget in my sidebar first to show a welcome text, and then again to show some ads at the bottom of the sidebar. In WordPress documentation, widgets like this are called “multi-widgets.”

But How Do You Create Your Own Multi-Widget?

Because WordPress is an open source project, we can dig into the source code and use it as a reference for our own projects. For this tutorial, it means that we can take a closer look at the Text widget and see how it has been implemented, using it as an example for turning our own widgets into multi-widgets.

Step 1: Locating the WordPress Text Widget

The first step is to search through the WordPress codebase and locate the text widget. It’s an interesting step and I recommend you check out some other files here and there too to gain an overall glimpse of what goes on inside of the blogging platform.

But if you just can’t wait to get to action, here’s where you will find the widget code:


The widget code is located in wordpress/wp-includes/widgets.php

Open the file and scroll down to the very end of it, around line 1958 (in version 2.7.1), and there, hidden in the middle of the source code, you’ll find an example widget, commented out and labeled “Pattern for multi-widget (allows multiple instances such as the text widget).”

At first, the example code can look rather daunting, so we’ll go through it line by line, making sense of the ideas around which the pattern is built. The code snippets in this tutorial have been copied from the example pattern, but I have made a few small changes here and there to make the code easier to follow (mainly splitting long lines to shorter ones). Apart from those small adjustments, the source code is exactly the same as you’ll find by opening widgets.php from the WordPress codebase.

Step 2: Understanding Widget Data

When the user presses the “Save Changes” button in the Widgets menu, WordPress collects the form parameters from each widget listed in the sidebars and sends them to each of the registered widgets. This feature is what makes creating multi-widgets possible: As the widget controller function gets notified to save a widget instance, all the parameters are passed to it, and it can update every instance of this widget type at one go, adding new ones and removing unused ones as needed.

We will look into the details of the saving process in a short while, but first, a good place to start looking at how the widget data for a multi-widget are stored is to look at the part of the code where the data are used. Here is the code for the method used for showing an instance of the example widget:

<?php
function widget_many( $args, $widget_args = 1 ) {
	extract( $args, EXTR_SKIP );
	if ( is_numeric($widget_args) )
		$widget_args = array( 'number' => $widget_args );
	$widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );
	extract( $widget_args, EXTR_SKIP );

	// Data should be stored as array
	$options = get_option('widget_many');
	if ( !isset($options[$number]) )
		return;

	echo $before_widget;

	// Do stuff for this widget, drawing data from $options[$number]

	echo $after_widget;
}
?>
  1. The first parameter passed to the widget rendering function, $args, contains generic widget settings, such as what should be printed before and after the widget, and how the widget heading should be formatted. The code on line 3 is used to split that information into local variables, from which $before_widget and $after_widget are used in the example.

  2. The second parameter, $widget_args is more interesting to us: it contains the id of the widget instance to be rendered. Lines 4 to 7 are there to make sure the parameter comes in a correct format, and that in the end, after the extract call on line 7, we can find the widget index in the local variable $number.

  3. Just like widget settings for a simple, one-time-only widget, the settings for a widget instance are stored as an array containing key-value pairs for each setting. But as we now need to store multiple instances, instead of saving each array with its own call to update_option, we put them all in one array using the instance id ($number) as the index and then save the whole thing with the id of the widget type.

  4. In the above example, we have a widget named “widget_many“, and let’s say we have added three instances of it to our blog sidebar. When rendering one of them, we first get an array containing all of the widget_many instances by calling get_option('widget_many'); (line 10) and then find the data for the current instance from that array (line 16).

The example code from doesn’t show the specifics of what you should do with the data, so let’s look at the actual text widget for more insight:

<?php
function wp_widget_text($args, $widget_args = 1) {
	extract( $args, EXTR_SKIP );
	if ( is_numeric($widget_args) )
		$widget_args = array( 'number' => $widget_args );
	$widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );
	extract( $widget_args, EXTR_SKIP );

	$options = get_option('widget_text');
	if ( !isset($options[$number]) )
		return;

	$title = apply_filters('widget_title', $options[$number]['title']);
	$text = apply_filters( 'widget_text', $options[$number]['text'] );
?>
		<?php echo $before_widget; ?>
			<?php
				if ( !empty( $title ) ) {
					echo $before_title . $title . $after_title;
				}
			?>
			<div class="textwidget"><?php echo $text; ?></div>
		<?php echo $after_widget; ?>
<?php
}
?>

On lines 13 and 14, you can see how the two parameters needed for the text widget are read from the options using $number as instance id. And on the next ten lines, the parameters are rendered on the screen.

Step 3: Saving Widget Settings

By analyzing the widget rendering function, we have now uncovered the basics behind saving the data for a multi-widget:

  1. Save the data of the specific widget instance to an array with setting names (for example “title”) as keys
  2. Save all widget instances into an array using the instance ids as keys
  3. Save the whole thing to the database using WordPress’s built-in get_option / update_option system.

Now, we’ll look closer and see the tricks and caveats involved.

Using the same approach as before, we will now look into the function used for showing and handling the settings forms and go through it line by line. This function, widget_many_control, is the function that saves the settings and renders the settings form for the “widget_many” example widget. It is called once for each widget_many instance, always passing the instance id in $widget_args.

As the function is a part of the form submission handling, the $_POST array will contain all parameters that have been sent using the widget editing form.

<?php
function widget_many_control( $widget_args = 1 ) {
	global $wp_registered_widgets;
	static $updated = false;

	if ( is_numeric($widget_args) )
		$widget_args = array( 'number' => $widget_args );
	$widget_args = wp_parse_args( $widget_args, array( 'number' => -1 ) );
	extract( $widget_args, EXTR_SKIP );

On the first lines of the function, you’ll see something familiar (lines 6-9). This is the same piece of code that was used in the rendering function to make sure $number has been initialized with the numerical id of the current widget instance.

But as you’ll soon notice, we won’t need that index for anything else than rendering the widget editing form, as we always save every instance of the “widget_many” widget type in one loop.

Next, we’ll retrieve the current widget settings, creating them if they don’t exist:

	$options = get_option('widget_many');
	if ( !is_array($options) )
		$options = array();

When implementing your own widget, remember to change the key, widget_many to your own widget’s id. Apart from that, this code can be reused as is. On lines 2 and 3, the code takes care of the case when we are adding the first widget instance of this type by creating an empty options array to use.

If settings have already been saved at least for one instance, we get them from get_option and can go on updating the settings if a form was submitted:

		if ( !$updated && !empty($_POST['sidebar']) ) {

The above line has two functions: It checks if data was posted (“!empty($_POST['sidebar'])“) and makes sure that instances of this widget type are handled only once.

The widget system calls the widget handling function once per each widget instance, but because we need to take care of things like adding and removing new widget instances, we can’t do that without knowing all the widgets of this type that exist. This is why the approach is to update every widget instance of this type on the first occurrence, and then set the global variable $updated to true so that the next instance will not do the updating again.

// Tells us what sidebar to put the data in
$sidebar = (string) $_POST['sidebar'];

$sidebars_widgets = wp_get_sidebars_widgets();
if ( isset($sidebars_widgets[$sidebar]) )
	$this_sidebar =& $sidebars_widgets[$sidebar];
else
	$this_sidebar = array();

foreach ( $this_sidebar as $_widget_id ) {
	$widget = $wp_registered_widgets[$_widget_id];
	if ( 'widget_many' == $widget['callback']
		&& isset($widget['params'][0]['number']) ) {
			$widget_number = $widget['params'][0]['number'];

			if ( !in_array( "many-$widget_number", $_POST['widget-id'] ) )
				unset($options[$widget_number]);
	}
}

// Compile data from $widget_many_instance
$widget_data = (array) $_POST['widget-many'];
foreach ( $widget_data as $widget_number => $widget_many_instance ) {
	if ( !isset($widget_many_instance['something'])
		&& isset($options[$widget_number]) ) {
			// user clicked cancel
			continue;
	}
	$something = wp_specialchars( $widget_many_instance['something'] );
	$options[$widget_number] = array( 'something' => $something );
}

update_option('widget_many', $options);

$updated = true; // So that we don't go through this more than once

This code snippet first looks up all the widgets stored in the sidebar that is being updated (lines 2-8) and then goes through the list removing all that match the widget id of this widget type (lines 10-18).

$_POST("sidebar") (line 2) contains the id of the sidebar. This way, if the user has removed a widget, it will be deleted from the data as well. And by deleting everything, we make sure we don’t accidentally leave duplicates, for example if the id of some widget has changed between updates.

After removing everything, we start adding the widgets that were posted by the user. In the posted form, there is an array containing all the data for every instance of the widget type. The array is organized like this:

	['widget-many'] =>
		[0] => params for widget instance 0 (array),
		[1] => params for widget instance 1 (array),
		...

On lines 23-31, the code loops over the widget instance data submitted and creates the settings for each instance (lines 29 and 30). As this is just example code, the saving part is using placeholder data such as “something”. So, let’s again take a look at the text widget to see how this works with real data:

$title = strip_tags(stripslashes($widget_text['title']));
if ( current_user_can('unfiltered_html') )
	$text = stripslashes( $widget_text['text'] );
else
	$text = stripslashes(wp_filter_post_kses( $widget_text['text'] ));
$options[$widget_number] = compact( 'title', 'text' );

The text widget has two parameters: title and text. The $widget_text variable in this piece of code is used the same way as $widget_many_instance in the example code we have been following: it holds the data posted for a specific instance of the widget.

In the text widget example, you’ll also see some interesting security features that you may want to look into a bit more when developing your own widgets. For this tutorial, however, it is enough to see that the contents of the variables $title and $text are read from the array posted and then stored as an array to the widget’s options on line 6.

If you are wondering about the compact() function, it’s the opposite of extract(), and takes the local variables whose names were passed as parameters and turns them into an array with the names as keys.

Finally, the new $options array is stored as the data for the widget, widget_many in the example code or widget_text in the text widget, using the update_option() function.

The last thing remaining in the widget settings function is drawing the form for this widget instance. This form is not rendered on screen as is, but WordPress converts it into a real form later, using some JavaScript magic. The code below is from the template code, so it uses $something to represent the widget data. In the text widget it is replaced by $title and $text, and in your own widget with anything you need to save.

It’s important to notice that although the saving is done for every instance at one go, the form rendered here is for just one instance. This is where we’ll use the widget instance id read in at the beginning of the function.

	if ( -1 == $number ) {
		$something = '';
		$number = '%i%';
	} else {
		$something = attribute_escape($options[$number]['something']);
	}

On the above lines, the widget first checks if a valid widget number was given or not. If not, and $number was set to the default value, -1, all data should be set to default values. Otherwise, we will get the data from the $options array and use it to populate the form with current settings. This is a nice thing to do so that the user won’t have to always start editing the widget from an empty slate.

And then, the form itself is built so that it can be read into an array when posted to the widget handling code: The form inputs are named following the pattern widget-many[$number][something] where $number is the number of this widget instance and something is the name of the parameter to be saved. WordPress then parses this into the array structure described earlier when the user submits the form.

The form doesn’t have a submit button because all the widgets are saved using the same submit button provided by WordPress.

<p>
	<input class="widefat"
		id="widget-many-something-<?php echo $number; ?>"
		name="widget-many[<?php echo $number; ?>][something]"
		type="text" value="<?php echo $data; ?>" />
	<input type="hidden"
		id="widget-many-submit-<?php echo $number; ?>"
		name="widget-many[<?php echo $number; ?>][submit]" value="1" />
</p>

Step 4: Registering the Widget as Multi-Widget

For WordPress to show a widget in the widget list, you need to register it by telling WordPress what functions to use for rendering the widget and its settings form. The way this is done for multi-widgets isn’t that different from regular widgets. The only difference is in how the id of the widget is defined: In $control_ops (line 7), we tell WordPress to enable multiple instances and to attach all widget instances with an id starting "many" to this widget type.

function widget_many_register() {
	if ( !$options = get_option('widget_many') )
		$options = array();

	$widget_ops = array('classname' => 'widget_many',
                'description' => __('Widget which allows multiple instances'));
	$control_ops = array('width' => 400, 'height' => 350, 'id_base' => 'many');
	$name = __('Many');

	$registered = false;
	foreach ( array_keys($options) as $o ) {
		// Old widgets can have null values for some reason
		if ( !isset($options[$o]['something']) )
			continue;

		// $id should look like {$id_base}-{$o}
		$id = "many-$o"; // Never never never translate an id
		$registered = true;
		wp_register_sidebar_widget( $id, $name, 'widget_many',
                        $widget_ops, array( 'number' => $o ) );
		wp_register_widget_control( $id, $name, 'widget_many_control',
                        $control_ops, array( 'number' => $o ) );
	}

	// If there are none, we register the widget's
    // existance with a generic template
	if ( !$registered ) {
		wp_register_sidebar_widget( 'many-1', $name, 'widget_many',
                $widget_ops, array( 'number' => -1 ) );
		wp_register_widget_control( 'many-1', $name, 'widget_many_control',
                $control_ops, array( 'number' => -1 ) );
	}
}

// This is important
add_action( 'widgets_init', 'widget_many_register' );

In the function above, we first register all the existing widgets of this type, skipping the ones that don’t have valid data (lines 11-23), and then if there is no instance available yet, register a default one to make sure the widget is registered and available in the sidebar (lines 27-32).

As the last, crucial step, on line 34, we hook the widget initialization function to the widgets_init event so that WordPress will call it when it is the time to initialize all widgets. Without this function, we wouldn’t see any of the functionality of the widget we just analyzed as no part of the code would ever get called.

Step 5: Putting it All Together

In the snippets above, I have deliberately left out some of the code to make things more readable, so you won’t be able to just copy the pieces and put them together. Instead, you should go and copy that same code from your WordPress installation.

After that, you just need to put in your own functionality, and there you have it: your own multi-widget.


]]>
http://net.tutsplus.com/tutorials/wordpress/dissecting-the-wordpress-text-widget/feed/ 26
Social Networking with BuddyPress http://net.tutsplus.com/tutorials/wordpress/social-networking-with-buddypress/ http://net.tutsplus.com/tutorials/wordpress/social-networking-with-buddypress/#comments Mon, 30 Mar 2009 10:30:14 +0000 Justin Shreve http://net.tutsplus.com/?p=4017 ]]> Automattic, the company behind WordPress, has recently acquired and will be releasing social networking software called BuddyPress. The software, built on top of WordPress, was created by Andy Peatling as way to start your very own social network similar to Facebook. Today, we will take a look at installing BuddyPress.

Step 1 – What is BuddyPress?

BuddyPress

BuddyPress is a social networking application built on top of WordPress Multi-User (MU) as a plugin. WordPress MU is the the software behind WordPress.com. It allows a user to host a network of blogs on a site. BuddyPress adds a large variety of new social interaction features to WordPress. The features can be added all at once or as individual components:

  • A WordPress blog
  • Individual profiles for members
  • Private Message (PM) functionality
  • Friend Networks
  • Groups, which include a blog, photos and other user generated content
  • "The Wire" (like the wall on Facebook)
  • Activity/Action streams of public actions on the site
  • Forums using bbPress
Features

A fully featured demo is available at the BuddyPress website.

Demo

Today, we will install a full installation of BuddyPress (all the bells and whistles), so we can start a social network from scratch.

The software is in its RC stage, but is nearing its final version. The current version will help you get started with social networking by providing an admin control panel and all the basic features outlined above. You will then be ready to upgrade to the final version when the time comes.

Step 2 – Requirements

Before you install the BuddyPress system, your server will require you have two components already in place:

  • a MySQL database to store all the BuddyPress information. If you do not have a database created, create one with a user who has all privileges (such as UPDATE, INSERT, DELETE, SELECT) on that database. Remember the username/password and database name for later steps.
  • a mod rewrite module so you can have clean URLS. If you have used WordPress or another piece of software that has clean URLs, then you should be ready to proceed without adding this component again.
phpMyAdmin

Step 3 – Download WordPress MU

Before you can start the BuddyPress installation you will need a copy of WordPress MU installed. Grab the latest version (ZIP) (TAR.GZ) and unzip it. You should see a folder with a name similar to "wordpress-mu".

Upload the files in this directory to the location where you want to access your site. This can be the main domain or a subfolder. Grab a cup of coffee or tea while you wait for the upload to finish.

FTP/Files

Step 4 – Install WordPress MU

Once the upload has completed you can go ahead and install WordPress MU.

Point your browser to the directory where you uploaded the files so that index.php is executed. You will be shown a screen to enter some details. The settings should be filled as given below:

  • Blog Addresses – For the purpose of this article we will select "sub-directories". If you happen to have Wildcard DNS records enabled, you can select the other option, but that is outside the scope of this article.
  • Database Name – The database name from Step 2
  • User Name – The username from Step 2
  • Password – The password from Step 2
  • Database Host – This is usually localhost if the MySQL server is on the same server as the web server. Only change this if the installation is returning errors about the server/host setting.
  • Server Address – The installer should be able to guess this setting, but double check that it is set to the server/domain you are installing to.
  • Site Title – This will be the name of the social network site, so name it whatever you want.
  • Email – Enter a valid email address to be used for the admin account.
Install

Once you have double-checked all the above settings, click Submit. If all goes well, you should be greeted with an "Installation Finished!" screen that includes your username and password. You have also been sent an email with the same details included.

Before you continue, follow the instructions for setting permissions on the Installation Finished page.

Install

Step 5 – Download BuddyPress

At this point, you can now install the BuddyPress system. Since we are installing the full system, you can download the "combo" archive here.

Unzip the combo file and upload all the contents of the extracted zip to the root mu-plugins folder located in wp-content. Upload ALL the folders and files located in the zip, and make sure these folders and files have been chmodded to 755.

Move the mu-plugins/bp-themes folder you just uploaded to wp-content. Make sure these folders have been chmodded to 755.

Files

Step 6 – Setup BuddyPress

Once the files are uploaded, log in to the WordPress MU admin control panel with the username and password you created earlier. The URL to log in (emailed to you when you installed WordPress MU) is in the form http://yourdomain.tld/folder/wp-login.php

Under the "Site Admin" menu find the "Themes" link and click it. You will be shown a list of installed WordPress MU themes, one of which is the BuddyPress theme. Select "Yes" for "BuddyPress Home Theme" and click "Update Themes".

Themes

Finally, you will need to enable registrations if you want users to be able to sign up for your site. Under the "Site Admin" menu go to "Options" and make sure the Enabled option is selected for "Allow new registrations".

Allow New Registration Settings

Congratulations! Your social network is now ready for use. When logged into the admin control panel, you can manage a few settings from the "BuddyPress" link under "Site Admin". To view your new network and profile click "My Account" from the admin bar at the top of the screen and select "Activity" or "Profile".

Step 7 – Additonal Plugins and Themes

The plugin space for BuddyPress is small right now, but it will probably explode with new activity like WordPress once did. However, there are a few cool plugins available for BuddyPress right now:

  • bpGroups which includes improvements to the group system.
  • Invite Friends which adds some functionality to allow you to add friends from other social networking applications like Twitter, Facebook and GMail.
  • Twitter To Wire which adds your tweets to your wire (the BuddyPress version of Facebook's Wall) automatically.

There is also a page for themes, but no themes have yet been made available for download. If you are curious about the power of the theming system, you can view a few examples at WannaNetwork, GrungePress, and Flokka.

Extend Screen Shot

Closing

I hope this tutorial has been successful in introducing you to BuddyPress and has opened up an opportunity for you to start your own social network site. The Wordpress MU / BuddyPress configuration provides more social functionality than can be provided by a simple forum or blog network setup.

Remember, this tutorial is meant to familiarize you with the software and its installation before its final release. If you want to continue with your BuddyPress installation on the programming side of things, the BuddyPress Codex has some developer documentation.

  • Subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.


]]>
http://net.tutsplus.com/tutorials/wordpress/social-networking-with-buddypress/feed/ 70
Create a Custom WordPress Plugin From Scratch http://net.tutsplus.com/tutorials/wordpress/creating-a-custom-wordpress-plugin-from-scratch/ http://net.tutsplus.com/tutorials/wordpress/creating-a-custom-wordpress-plugin-from-scratch/#comments Tue, 20 Jan 2009 17:52:54 +0000 Cristian Lupu http://nettuts.com/?p=2668 ]]> This tutorial will describe the implementation of a Wordpress plugin starting from scratch. The plugin will connect to an external OSCommerce database and display random products on your Wordpress site. It also implements a configuration page for the Wordpress admin panel.

Introduction

Wordpress is gaining more and more popularity each day, not just as a blogging platform but also as a basic CMS, thus improving and extending its basic functionality becoming a day-to-day necessity for a lot of developers. Fortunately, the Wordpress developers have foreseen these needs and added the possibility of customizing the basic functionality by adding plugins. Basicaly, a Wordpress plugin is a (more or less) stand-alone piece of code that can be executed in different sections and stages within a page or site.

In today’s tutorial we’ll be talking about creating a Wordpress plugin that extracts and displays products from an external OSCommerce shop database. We will start by describing the file structure of a plugin and where it must be included in the Wordpress structure, then we’ll be having a closer look at how to make our plugin visible for Wordpress and integrating it with actions run by its frame. Next, we’ll be creating a configuration panel for our plugin to allow the site administrator to customize it to his/her needs. Once done, we’ll be implementing the front-end functions themselves that will interact with the OSCommerce database and extract the required data. Finally, we’ll be modifying the default template to display the extracted data in the sidebar. Excited? Let’s get started!

Final Product

Getting started

While it would be possible to follow this tutorial by simply reading through it, I would recommend installing Wordpress on your computer and follow the tutorial implementing all the steps. For this, you’ll need a local server running on your machine, like XAMPP for instance. Once you have it running, download and install Wordpress. You will find extensive information about the installation process and troubleshooting on the Wordpress site. For this tutorial we will be using release 2.7

Further on, you will need to set up an OSCommerce shop on your machine. You can download the latest release here: http://www.oscommerce.com/solutions/downloads

Files and folders

First, we’ll need to create our basic files and folder structure. Wordpress stores its plugins in the wp-content/plugins/ folder. This is the place where we’ll be adding our files as well. Normally, if your plugin is going to be very simple, you will include all the code inside one single PHP file. In this case, you will simply store the file in the folder mentioned above. However, in our case, we are going to use two files (one for the main plugin file and one for implementing the administration page) therefore we’ll be putting all our files in a specific folder that we’ll name oscommerce_importer. Go ahead and create this folder.

Creating the plugin file

Next, we must create our main plugin file. We’ll name it oscommerce_importer.php. You can really name it whatever you want, it doesn’t make any difference.

If you now open your Wordpress administration panel and navigate to the Plugins sections, your screen will look something like this:

Admin panel

As you can see, there is not the slightest sign of our new plugin. It’s time to change that and tell Wordpress that our file is going to implement a plugin. The process to do so is very simple. All we need to do is add a plugin specific information header to our newly created file. This standard header will look like this:

	<?php
		/*
		Plugin Name: OSCommerce Product Display
		Plugin URI: http://www.orangecreative.net
		Description: Plugin for displaying products from an OSCommerce shopping cart database
		Author: C. Lupu
		Version: 1.0
		Author URI: http://www.orangecreative.net
		*/
	?>
	

Simple enough, don’t you think? You can, of course, change the content of this header to your liking but make sure you keep all the lines, otherwise Wordpress won’t correctly recognize your plugin.

If you refresh your administration panel’s plugin page, you’ll now see our plugin listed along with the other ones.

Admin panel with deactivated plugin

See how all the relevant information like name, description, author, URL are extracted from the information header? This is why it is always important to correctly fill out this information. Let’s go and activate our plugin by clicking Activate to the right of the plugin entry.

Working with action hooks

Our plugin is now shown in the administration panel so Wordpress is aware of it. However, it doesn’t do anything as it contains nothing except of the information header. We are going to change this now.

Wordpress offers a great way to include your plugin code in different places all over the template, be it physical positions within a page or logical positions within the process of building up a page that is going to be displayed. First, we are going to have a closer look at the second category, the logical positions, better known as action hooks.

Action Hooks

You can view action hooks as callback function. Whenever Wordpress is executing a certain operation, like, for instance, displaying the page footer, it will allow your plugins to execute their own code that must be run at that exact moment.

For a better understanding, let’s consider a generic plugin called my_plugin that implements a function called mp_footer() that has to be run whenever the page footer is displayed. We will tell Wordpress to call this function, at the moment of displaying the footer by using a special function called add_action():

		<php add_action('wp_footer', 'mp_footer'); ?>
	

The add_action() function takes the action hook name as its first parameter and the name of the function that must be executed, as a second parameter. This function call will be added to your main plugin file (the one containing the information header), usually, right under the function code that needs to be executed (mp_footer() in our example). You will find the full list of available action hooks in the Wordpress Codex.

We’ll be using action hooks in the next chapter, where we are going to build the administration page for our plugin.

Creating the plugin’s administration page

We’ll start the implementation of the module by defining its configurable parameters and make these accessible to the site administrator. Let’s see what these configuration bits would be:

  • Database settings
    • database host
    • database name
    • database user
    • database password
  • Store settings
    • store URL
    • folder for the product images

First, we need the database host, name, user and password in order to be able to connect to it and extract the needed data. Second, we need some general data about the store like its URL and the folder where the product images are stored. We need this information in order to be able to build the links because the paths contained in the database are all relative the previously mentioned product image folder.

Now that we know what we want to include in the configuration panel, it’s time to implement it. We’ll start by creating a new menu item to access the page and we’ll place it inside the Settings menu. Remember our chat about the action hooks in the previous chapter? It’s time to use this feature.

If you’ll scroll over the list of action hooks, you’ll see that Wordpress also provides one that gets called when the basic menu structure has been generated (admin_menu) so, this would be the optimal place to chime in and create our own menu item.

Now that we identified the action we are going to use, all we need is to define our own function that will be called when this action hook runs. We’ll call our function oscimp_admin_actions() where oscimp_ stands for oscommerce importer and is used to create a possibly unique function name that will not get mismatched with any other function within Wordpress or any of its plugins. Let’s see how the code will look like:

		function oscimp_admin_actions() {

		}

		add_action('admin_menu', 'oscimp_admin_actions');
	

As you can see, we are creating our function oscimp_admin_actions() then associate it with the admin_menu action hook using the add_action() function. The next step would then be to add some code to our oscimp_admin_actions() function to actually create the new menu item.

As with most Wordpress things, adding a new menu item is also very easy. It all boils down to calling a single function. We would like to add our new menu item to the Settings menu so, in this case the function we need is add_options_page(). We’ll add the code inside the oscimp_admin_actions() function.

		function oscimp_admin_actions() {
			add_options_page("OSCommerce Product Display", "OSCommerce Product Display", 1, "OSCommerce Product Display", "oscimp_admin");
		}

		add_action('admin_menu', 'oscimp_admin_actions');
	

If you refresh your admin page, you’ll see the new menu item appear under Settings.

New menu item

Each existing menu has its own function to be used to add sub-menu items. For instance, if we would like to add our sub-menu item to the Tools menu instead of Settings, we would use the add_management_page() function instead of add_options_page(). You can find more details about the available options in the Adding Administration Menus section of the Wordpress Codex.

If we get back to the newly added code line, you’ll probably notice the last parameter. This is actually a function name that will be called when the newly added menu item is clicked on and will be used to build the administration page of our plugin. Next, we’ll be adding this new function. However, before proceeding we should stop for a moment and think about what will be implemented on this page.

We already defined the parameters we want to make configurable (database host, name, user, etc) so these will have to be included in a form in order to allow the user to send the data to the database. Once the form is defined, we’ll need a bit of code that extracts the sent data from the form and saves it to the database. Last but not least, we need some code to extract the existing data from the database (if any) and pre-populate the form with these values. As you can see, there are quite a few things to do so, it might be a good idea to separate this functionality to its own file. We’ll name the file oscommerce_import_admin.php. Now, go and create an empty file with the given name.

As already mentioned, we’ll have to create the function that will display our plugin configuration page (we named this function oscimp_admin()). The code inside this function will be included from our newly created PHP file, oscommerce_import_admin.php

		function oscimp_admin() {
			include('oscommerce_import_admin.php');
		}

		function oscimp_admin_actions() {
			add_options_page("OSCommerce Product Display", "OSCommerce Product Display", 1, "OSCommerce Product Display", "oscimp_admin");
		}

		add_action('admin_menu', 'oscimp_admin_actions');
	

If you now click on the link under the Settings menu, you will be directed to an empty page. This is because our oscommerce_import_admin.phpfile is still empty.

Empty plugin configuration page

Next, we are going to create our form. For this we’ll use the following code:

		<div class="wrap">
			<?php    echo "<h2>" . __( 'OSCommerce Product Display Options', 'oscimp_trdom' ) . "</h2>"; ?>

			<form name="oscimp_form" method="post" action="<?php echo str_replace( '%7E', '~', $_SERVER['REQUEST_URI']); ?>">
				<input type="hidden" name="oscimp_hidden" value="Y">
				<?php    echo "<h4>" . __( 'OSCommerce Database Settings', 'oscimp_trdom' ) . "</h4>"; ?>
				<p><?php _e("Database host: " ); ?><input type="text" name="oscimp_dbhost" value="<?php echo $dbhost; ?>" size="20"><?php _e(" ex: localhost" ); ?></p>
				<p><?php _e("Database name: " ); ?><input type="text" name="oscimp_dbname" value="<?php echo $dbname; ?>" size="20"><?php _e(" ex: oscommerce_shop" ); ?></p>
				<p><?php _e("Database user: " ); ?><input type="text" name="oscimp_dbuser" value="<?php echo $dbuser; ?>" size="20"><?php _e(" ex: root" ); ?></p>
				<p><?php _e("Database password: " ); ?><input type="text" name="oscimp_dbpwd" value="<?php echo $dbpwd; ?>" size="20"><?php _e(" ex: secretpassword" ); ?></p>
				<hr />
				<?php    echo "<h4>" . __( 'OSCommerce Store Settings', 'oscimp_trdom' ) . "</h4>"; ?>
				<p><?php _e("Store URL: " ); ?><input type="text" name="oscimp_store_url" value="<?php echo $store_url; ?>" size="20"><?php _e(" ex: http://www.yourstore.com/" ); ?></p>
				<p><?php _e("Product image folder: " ); ?><input type="text" name="oscimp_prod_img_folder" value="<?php echo $prod_img_folder; ?>" size="20"><?php _e(" ex: http://www.yourstore.com/images/" ); ?></p>

				<p class="submit">
				<input type="submit" name="Submit" value="<?php _e('Update Options', 'oscimp_trdom' ) ?>" />
				</p>
			</form>
		</div>
	

Explaining the Code

If you are familiar with HTML and PHP, the code above will make some sense but, still, let us shortly walk through the lines.

  • We start by creating a div with the class wrap. This is a standard Wordpress class that will make our page look like any other page in the administration area.
  • The form will be using the POST method to send data back to itself. This means that the form data will be received by the same page so, we can add the database update code to the same file.
  • Next, there is a hidden field that will be used to determine whether the current page is displayed after the user has pressed the Update Options button or not. When the page receives the form data, the value of this field will be set to Y.
  • The next lines will create the form input fields for the database and store settings. As you can easily see, the value parameters are be set by the content of PHP variables. We’ll talk about these soon.
  • Now if you refresh the admin page, you’ll see our newly created form. However, pressing the Update Options button will have no effect other than refreshing the page and the form fields are empty.
Plugin configuration page with form

Handling the Data

Once the form is ready to go, we’ll take care of the form data handling itself, updating the database and retrieving existing option values from the database. For this, we’ll first have to decide whether the current page is displayed after the user has pressed the Update Options button or not. We’ll do this by analyzing the value of the form’s hidden field, oscimp_hidden. The following code will be added at the very beginning of our oscommerce_import_admin.php file, before the code for displaying the form:

	<?php
		if($_POST['oscimp_hidden'] == 'Y') {
			//Form data sent
		} else {
			//Normal page display
		}
	?>
	

Next, we’ll be handling the form data and update the plugin options in the database accordingly. For this we’ll be using the update_option() function. The first parameter of this function is the option name which will be sued later to uniquely identify this option and its value. The second parameter is the value to be assigned.

	<?php
		if($_POST['oscimp_hidden'] == 'Y') {
			//Form data sent
			$dbhost = $_POST['oscimp_dbhost'];
			update_option('oscimp_dbhost', $dbhost);

			$dbname = $_POST['oscimp_dbname'];
			update_option('oscimp_dbname', $dbname);

			$dbuser = $_POST['oscimp_dbuser'];
			update_option('oscimp_dbuser', $dbuser);

			$dbpwd = $_POST['oscimp_dbpwd'];
			update_option('oscimp_dbpwd', $dbpwd);

			$prod_img_folder = $_POST['oscimp_prod_img_folder'];
			update_option('oscimp_prod_img_folder', $prod_img_folder);

			$store_url = $_POST['oscimp_store_url'];
			update_option('oscimp_store_url', $store_url);
			?>
			<div class="updated"><p><strong><?php _e('Options saved.' ); ?></strong></p></div>
			<?php
		} else {
			//Normal page display
		}
	?>
	

The code above if pretty much self-explanatory but please note that here we are using the PHP variables we have previously mentioned while building the form. These variables will be updated with the current form data values and will be displayed in the form itself. Go, check it out! Refresh the configuration page and enter your OSCommerce database settings as well as your store parameters then press Update Options.

If everything was implemented like described above, you’ll see an Options saved success message and the form fields will contain the data you have just entered.

Plugin configuration page with success message

Last but not least, we’ll need to pre-populate the form with the database data when the user opens the configuration page. For this, we’ll be using the get_option() function which retrieves the specified option from the database.

	<?php
		if($_POST['oscimp_hidden'] == 'Y') {
			//Form data sent
			$dbhost = $_POST['oscimp_dbhost'];
			update_option('oscimp_dbhost', $dbhost);

			$dbname = $_POST['oscimp_dbname'];
			update_option('oscimp_dbname', $dbname);

			$dbuser = $_POST['oscimp_dbuser'];
			update_option('oscimp_dbuser', $dbuser);

			$dbpwd = $_POST['oscimp_dbpwd'];
			update_option('oscimp_dbpwd', $dbpwd);

			$prod_img_folder = $_POST['oscimp_prod_img_folder'];
			update_option('oscimp_prod_img_folder', $prod_img_folder);

			$store_url = $_POST['oscimp_store_url'];
			update_option('oscimp_store_url', $store_url);
			?>
			<div class="updated"><p><strong><?php _e('Options saved.' ); ?></strong></p></div>
			<?php
		} else {
			//Normal page display
			$dbhost = get_option('oscimp_dbhost');
			$dbname = get_option('oscimp_dbname');
			$dbuser = get_option('oscimp_dbuser');
			$dbpwd = get_option('oscimp_dbpwd');
			$prod_img_folder = get_option('oscimp_prod_img_folder');
			$store_url = get_option('oscimp_store_url');
		}
	?>
	

You can test the code above by simply navigating to another page within the admin area and then retuning to this page by clicking the OSCommerce Product Display sub-menu item in the Setting menu. If everything goes well, you will see the form with all the fields pre-populated with the data you have entered.

Plugin configuration page with pre-populated form

With this last piece of code, we have finished implementing the plugin’s configuration page so, let’s review what has been done in this chapter:

  • we defined what parameters need to be configured by the site administrator
  • we added an action hook for when the menu is displayed in the administration panel to help us add a new sub-menu item for our plugin
  • we have added a new sub-menu item to the Settings menu that will link to our plugin’s configuration page
  • we have defined a function that will build the plugin’s configuration page and separated its code in a second PHP file
  • we have built the form containing the user inputs for each of the configurable data bits
  • we have built the database update function
  • we have built a function that will pre-populate the form with the option values stored in the database

Creating the user function

Well, everything went quite fine so far but our plugin is yet unusable because we haven’t implemented the part that will actually allow us to display the products in the front-end.

In order to allow our users to display the products in the front-end, we’ll need to declare a function that can be called from the template’s PHP code and which will return the HTML code to be inserted in the template. We are going to name this function oscimp_getproducts() and accept the number of products to be displayed as a function parameter. The function itself will be implemented in our plugin’s main file, oscommerce_import.php

		function oscimp_getproducts($product_cnt=1) {

		}
	

As you can see, we are assigning a default value to our function parameter thus allowing our users to call the function both with and without a parameter. If the function is called with a parameter, like oscimp_getproducts(3), it will display three products. If the function is called without a parameter, like oscimp_getproducts(), it will only display one product.

First thing in our function would be to establish a connection to the OSCommerce database. Thanks to our plugin configuration page, we now have all the information we need: database host, name, user and password. We’ll be using the built-in wpdb class to create a new database object.

		function oscimp_getproducts($product_cnt=1) {
			//Connect to the OSCommerce database
			$oscommercedb = new wpdb(get_option('oscimp_dbuser'),get_option('oscimp_dbpwd'), get_option('oscimp_dbname'), get_option('oscimp_dbhost'));
		}
	

Once this is done, we declare a variable that will contain the HTML code and start quering the OSCommerce database for each of the specified number of products. The code below merely implements this query loop and can be further-on improved by checking for duplicates, for instance, but this is not the subject of this tutorial so, we’ll keep it simple for the sake of readability.

		function oscimp_getproducts($product_cnt=1) {
			//Connect to the OSCommerce database
			$oscommercedb = new wpdb(get_option('oscimp_dbuser'),get_option('oscimp_dbpwd'), get_option('oscimp_dbname'), get_option('oscimp_dbhost'));

			$retval = '';
			for ($i=0; $i<$product_cnt; $i++) {
				//Get a random product
				$product_count = 0;
				while ($product_count == 0) {
					$product_id = rand(0,30);
					$product_count = $oscommercedb->get_var("SELECT COUNT(*) FROM products WHERE products_id=$product_id AND products_status=1");
				}

				//Get product image, name and URL
				$product_image = $oscommercedb->get_var("SELECT products_image FROM products WHERE products_id=$product_id");
				$product_name = $oscommercedb->get_var("SELECT products_name FROM products_description WHERE products_id=$product_id");
				$store_url = get_option('oscimp_store_url');
				$image_folder = get_option('oscimp_prod_img_folder');

				//Build the HTML code
				$retval .= '<div class="oscimp_product">';
				$retval .= '<a href="'. $store_url . 'product_info.php?products_id=' . $product_id . '"><img src="' . $image_folder . $product_image . '" /></a><br />';
				$retval .= '<a href="'. $store_url . 'product_info.php?products_id=' . $product_id . '">' . $product_name . '</a>';
				$retval .= '</div>';

			}
			return $retval;
		}
	

Once this is done, all we have to do is insert the oscimp_getproducts() function call to the template. We’ll be displaying three products at the bottom of the sidebar so, we are going to modify the sidebar.php file of our template, inserting the following code right below the list item containing the meta links:

		<li><?php echo oscimp_getproducts(3); ?></li>
	

If you refresh your front-end page now, you’ll see the three random products displayed at the bottom of the sidebar.

Frontpage with random products

With this last piece of code, we have finished implementing the front-end function as well.

Conclusion

We have now implemented a Wordpress plugin from scratch. Let’s summarize what has been done:

  • we defined the way we store our plugin files
  • we defined the information header in order to make our plugin visible for Wordpress
  • we talked about the action hooks and the way these are used
  • we defined what parameters need to be configured by the site administrator
  • we added an action hook for when the menu is displayed in the administration panel to help us add a new sub-menu item for our plugin
  • we have added a new sub-menu item to the Settings menu that will link to our plugin’s configuration page
  • we have defined a function that will build the plugin’s configuration page and separated its code in a second PHP file
  • we have built the form containing the user inputs for each of the configurable data bits
  • we have built the database update function
  • we have built a function that will pre-populate the form with the option values stored in the database
  • we have built our user function for use in the template
  • we connected to the OSCommerce database
  • we queried the OSCommerce database extracting the product ID, image and name
  • we have built the HTML code for displaying the extracted data
  • we have included the user function to the template sidebar

I hope this tutorial gave you all the information you need to build a Wordpress plugin from the beginning. Please feel free to post your comments below.

Thanks for reading! :)

  • Subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.


]]>
http://net.tutsplus.com/tutorials/wordpress/creating-a-custom-wordpress-plugin-from-scratch/feed/ 103
Anatomy of a WordPress Plugin http://net.tutsplus.com/tutorials/wordpress/anatomy-of-a-wordpress-plugin/ http://net.tutsplus.com/tutorials/wordpress/anatomy-of-a-wordpress-plugin/#comments Fri, 12 Dec 2008 10:30:57 +0000 Jarkko Laine http://nettuts.com/?p=2127 ]]> WordPress is well known for its amazing collection of free plugins. There is one for almost every need
you can think of, from backing up your WordPress installation to asking for a cup of coffee
or fighting spam.

But there are times when none of the available plugins seem to quite do the trick you are looking for. To help you in moments like
that, this tutorial will guide you through every step of building a simple, widgetized WordPress plugin with settings.

Writing your own plugin is not rocket science reserved for the most savvy programmers. All you need
is a basic understanding of
the PHP programming language
and some information on how WordPress expects your plugin to behave. This tutorial will provide you with the latter.

The Goal

Before we get started, let me introduce the concept of the plugin and what we are trying to achieve with it.

“Coming Next” will be a widget plugin that queries a given number of blog posts scheduled for the future and lists them in the blog’s sidebar (or where ever
the blog owner decides to place the widget). The widget will be customizable so that the user can decide how many posts he wants to list,
if a summary of the post should be shown, and what the date format should be. The looks of the widget should be easily customizable through CSS.

Here is a quick drawing of how the widget could look like in action:


Let’s get started!

Step 1: The Plugin Template

Plugins in WordPress are PHP files that have been put in the wp-content/plugins directory under the WordPress installation directory.

For simple plugins that fit nicely in just one file, like the one we are creating today, it’s enough to create a single PHP file and upload it to the
plugin directory. It is, however, a good practice to always create a separate directory for every plugin and that way help the blog owners keep their plugins
organized. This will also make it easier to expand your plugin if you ever need to add new files to it.

Let’s create a directory for the “Coming Next” plugin:



Created directory: /wp-content/plugins/coming-next

In this new directory, we then create the plugin’s main PHP file. Let’s call it coming-next.php.

When searching for plugins, WordPress goes through each file inside the plugin directory looking for comments that identify the files as plugins. That
comment section tells basic information about the plugin and at the bare minimum needs to contain the name of the plugin.

Here’s how the comment block for our “Coming Next” plugin will look like:

<?php
/*
Plugin Name: Coming Next
Plugin URI: http://nettuts.com
Description: Shows the next scheduled posts with brief descriptions.
Version: 1.0
Author: Jarkko Laine
Author URI: http://jarkkolaine.com
*/
?>

Save the file and go to the plugins page in your WordPress admin area. The plugin, with all the information added in the comment,
is already visible in the the plugin list:



This is how the plugin appears on the plugin list

You can already activate the plugin, but as we haven’t yet put in any code, nothing will happen. We need some functionality.

Step 2: Adding Functionality

In its simplest form, a WordPress plugin is nothing more than one or more functions put inside a plugin file.

All functions created in plugins are visible to both the current theme and other active plugins, so it is possible to

use the plugin system to extend the platform with new functions and then just call them straight from your theme.

Let’s do that first and create the function at the core of the “Coming Next” plugin, list_upcoming_posts().

One word of warning is in place before we start: Because all functions added in plugin files will be visible throughout your
WordPress installation, you need to be very careful when naming them. If there are two functions with the same name
in two (or more) different plugins, they will conflict, and things just cannot work.

For larger plugins it’s a good idea to do some object oriented programming and create classes to encapsulate parts
of the functionality. That will give you more freedom in naming your functions and variables. In smaller plugins like
this one, you just need to be careful, and try to use descriptive function names that you think no one else is using.

function list_upcoming_posts($num_posts = 1, $show_excerpt = false,
                             $text_format = "Coming Up on [date]") {
  $posts = get_posts("numberposts=".$num_posts."&order=ASC&post_status=future");

  echo "<ul class=\"upcoming-posts\">";
  global $post;
  $old_post = $post;

  foreach ($posts as $post) :
    setup_postdata($post);
    $my_date = the_date('', '', '', FALSE);
    $coming_up_text = str_replace("[date]", $my_date, $text_format);
  ?>
    <li class="upcoming-post">
      <span class="upcoming-post-date"><?php echo $coming_up_text; ?></span>
      <span class="upcoming-post-title"><?php the_title(); ?></span>
      <?php if ($show_excerpt) : ?>
        <span class="upcoming-post-description">
          <?php the_excerpt_rss(); ?>
        </span>
      <?php endif; ?>
    </li>
  <?php
  endforeach;

  $post = $old_post;
  setup_postdata($post);
  echo "</ul>";
}

This function uses the get_posts() WordPress
function to retrieve as many future posts as specified in the $num_posts parameter, or all future posts
if $num_posts is greater than the actual number available.

Then it renders a list including the titles of the posts, their scheduled dates, and the excerpt of the post if $show_excerpt is set to true.

Note that we need to use the global $post variable to setup the post data (see line 10) for function calls such
as the_title() to work. Now, in case the blog template needs access to the current post after rendering the plugin,
we need to put back the original post once we are finished (see lines 7, and 26-27). Otherwise, the rest of the content would be rendered using the last
post that was set up using setup_postdata().

Congratulations! You have just written your first WordPress plugin and can test it by adding this call somewhere in your blog template:

<?php
if (function_exists("list_upcoming_posts")) {
  list_upcoming_posts();
}
?>

Create a post titled “Back to the Future” and schedule it to appear on your blog on January 1st, 2020. Here’s what you should see:



The Plugin in action. Without any CSS styling yet.

Step 3: Making the Widget

For some plugins, just having a function you can call from your theme is more than enough. But for this plugin, I think letting the user
customize the output through his WordPress admin page will provide a nice final touch. And the WordPress widget system is the perfect way to
achieve that level of user-friendliness.

In case you aren’t yet familiar with the concept of WordPress Widgets,
here’s what the WordPress documentation says about them:

WordPress Widgets allow the easy addition of design elements, gadgets, content, images, and more to your WordPress sidebar to personalize
your blog without knowing HTML, PHP, or any code. Many WordPress Plugins now come with a Widget version to allow easy addition to the sidebar.

If your theme supports widgets, you can go to the Widgets tab in the Design section of your WordPress admin area and assign widgets to the different
positions that the theme designer has created for them:



The “Widgets” settings screen

To make our “Coming Next” plugin work as a widget, we first need to create a function for rendering the widget. As we can reuse the
list_upcoming_posts() function we created earlier, this task will be rather straightforward.

Here is the code for the widget in its simplest form:

function widget_coming_next($args) {
  extract($args, EXTR_SKIP);
  echo $before_widget;
  list_upcoming_posts();
  echo $after_widget;
}

All the function does is that it extracts the HTML markup that the theme designer has set up to be rendered before ($before_widget) and
after ($after_widget) every widget, and then renders it around the list of upcoming posts.

The extract() function is standard PHP.
It takes the fields from the given array ($args) and creates local variables out of them. Another way of
doing the same would have been to reference the array directly using “before_widget” and “after_widget” as array indices.

Now, the widget knows how to render itself. But before it can be added to a blog, we still need to tell WordPress to add it to the list
of widgets on the administration page. This is done by creating an initialization function that registers the sidebar widget and adding
a plugin hook to call that function after all WordPress
plugins have been loaded into memory.

function widget_coming_next_init() {
  wp_register_sidebar_widget(COMING_NEXT_WIDGET_ID,
  	__('Coming Next'), 'widget_coming_next');
}

// Register widget to WordPress
add_action("plugins_loaded", "widget_coming_next_init");

The initialization function calls wp_register_sidebar_widget()
to register the widget to WordPress. The function needs three parameters: a unique identifier for the widget, a name to be used on the Widgets
page in the admin area and the name of the function that will render the widget.

To make things easier, if we ever need to change the unique identifier, I have created a constant for it. This way, when we use the same constant everywhere,
we will only have to update it in one place. Add this constant definition at the beginning of the widget file, right after the comment block that identifies the plugin:

define(COMING_NEXT_WIDGET_ID, "widget_coming_next");

Now, when you go to check out the “Widgets” page, you’ll see the new widget there waiting to be added on the blog. And when you add
the widget to a widget position, you’ll see the upcoming posts appear right where you put them!



The “Coming Next” widget has now been added to the widget list.

Step 4: Widget Settings

Finally, to complete the plugin, we will create a settings menu for updating the widget preferences. The settings box will contain all the same
parameters that the list_upcoming_posts() function takes as paramters. As that function has already been done and
it knows how to handle the parameters, all that is left is building the settings menu and making it save and retrieve the settings.

Just like for the widget rendering, we will create a function that renders the settings menu and stores the settings
in the persistent storage, and then tell WordPress about the function so that it knows to show it when adding or editing the widget.

Here’s the code for storing and retriving the settings:

function widget_coming_next_control() {
  $options = get_option(COMING_NEXT_WIDGET_ID);
  if (!is_array($options)) {
    $options = array();
  }

  $widget_data = $_POST[COMING_NEXT_WIDGET_ID];
  if ($widget_data['submit']) {
    $options['num_posts'] = $widget_data['num_posts'];
    $options['coming_up_text'] = $widget_data['coming_up_text'];
    $options['show_excerpt'] = $widget_data['show_excerpt'];

    update_option(COMING_NEXT_WIDGET_ID, $options);
  }

  // Render form
  $num_posts = $options['num_posts'];
  $coming_up_text = $options['coming_up_text'];
  $show_excerpt = $options['show_excerpt'];

  // The HTML form will go here
}

The heart of this function are these two calls to the WordPress API:
get_option() on line 2 and
update_option() on line 13.
update_option() can be used to save any variable to the WordPress database as a key-value pair and get_option to
read it.

For example, in the above code snippet, you’ll see that on line 13, update_option() is used to store the $options array with the
key COMING_NEXT_WIDGET_ID.

To make things more organized, instead of saving each variable as a separate key-value pair, we put them in an
array ($options) that can be saved at one go.
This array then holds all the data related to this widget. The array is loaded at the beginning of the function so that the data is available
for rendering the settings form and the existing settings can be used as form defaults and won’t get lost when the form gets submitted.

The widget_coming_next_control() function gets called both when the settings form is first shown and when the user presses the “Save Changes” button
to store the settings. To identify whether the form has been submitted or not, we use a hidden field
called COMING_NEXT_WIDGET_ID[submit]. If the hidden field has been saved, we read in the parameters from the
form and save them (lines 8-14). And in both cases, whether data is saved or not, the form is rendered.

Speaking of forms, that core part is still missing. Copy the form below and put it at the end of the function we just created
(right after line 21, before the closing brace):

?>


  <label for="<?php echo COMING_NEXT_WIDGET_ID;?>-num-posts">
    Number of posts to show:
  </label>
  <input class="widefat"
    type="text"
    name="<?php echo COMING_NEXT_WIDGET_ID; ?>[num_posts]"
    id="<?php echo COMING_NEXT_WIDGET_ID; ?>-num-posts"
    value="<?php echo $num_posts; ?>"/>



  
  <input class="widefat" type="text"
    name="<?php echo COMING_NEXT_WIDGET_ID; ?>[coming_up_text]"
    id="<?php echo COMING_NEXT_WIDGET_ID; ?>-coming-up-text"
    value="<?php echo $coming_up_text; ?>"/>



  
  <select class="widefat"
    name="<?php echo COMING_NEXT_WIDGET_ID; ?>[show_excerpt]"
    id="<?php echo COMING_NEXT_WIDGET_ID;?>-show-exceprt">
    <option value="1" <?php echo ($show_excerpt == "1") ? "selected" : ""; ?>>
      Yes
    </option>
    <option value="0" <?php echo ($show_excerpt == "1") ? "" : "selected"; ?>>
      No
    </option>
  </select>


<input type="hidden"
  name="<?php echo COMING_NEXT_WIDGET_ID; ?>[submit]"
  value="1"/>
<?php

If you look at the form carefully, you will notice that there are no form opening or ending tags. This is because all active widgets are
put in the same form, rendered by WordPress, and are saved at one press of “Save Changes.” This will be useful when you decide to write
a widget that can be added many times, such as the WordPress text widget (when doing that you will need to be aware of multiple widgets
and all their different states at the same time). But for now, it just means that you need to be careful with how you name the fields in your part of the form.

In this plugin, I decided to use the COMING_NEXT_WIDGET_ID constant as an identifier to define which of the fields belong to this widget.
Using the widget_id[field_id] notation in the name parameters of our input tags makes things
nice for us as they get parsed into an array with field_id as the array index.

After creating the settings screen function, we still need to tell WordPress to use it. This is done with the following hook.
Add it to the widget_coming_next_init() function we created earlier:

  wp_register_widget_control(COMING_NEXT_WIDGET_ID,
      __('Coming Next'), 'widget_coming_next_control');

Now, when you go to add or edit the widget, you’ll see that new options have appeared:



The widget now has settings

Last but not least, we will make the widget rendering use the settings defined in the settings box. It’s really quite simple: all we need to
do is to read the settings using the get_option() function. Replace the previously created widget rendering function with
this new version:

function widget_coming_next($args) {
  extract($args, EXTR_SKIP);
  $options = get_option(COMING_NEXT_WIDGET_ID);

  // Query the next scheduled post
  $num_posts = $options["num_posts"];
  $show_excerpt = $options["show_excerpt"];
  $coming_up_text = $options["coming_up_text"];

  echo $before_widget;
  list_upcoming_posts($num_posts, $show_excerpt, $coming_up_text);
  echo $after_widget;
}

That’s it. You have now created a WordPress widget with settings!
The output still looks rather dull, but with a small touch of CSS, it’ll come alive and be a perfect match to your blog theme.



The Coming Next widget live in action
]]>
http://net.tutsplus.com/tutorials/wordpress/anatomy-of-a-wordpress-plugin/feed/ 68