Author Archive

Create Perfect Emails For Your WordPress Website





 



 


Whatever type of website you operate, its success will probably hinge on your interaction with your audience. If executed well, one of the most effective tools can be a simple email.

image2

WordPress users are in luck, since WordPress already has easy-to-use and extendable functions to give you a lot of power and flexibility in handling your website’s emails.

In order to create our own system, we will be doing four things. First, we will create a nice email template to use. We will then modify the mailer function so that it uses our new custom template. We will then modify the actual text of some of the built-in emails. Then we will proceed to hook our own emails into different events in order to send some custom emails. Let’s get started!

How WordPress Sends Emails

WordPress has a handy function built in called wp_mail(), which handles the nitty-gritty of email sending. It is able to handle almost anything you throw at it, from custom HTML emails to modifications to the “From� field.

WordPress itself uses this function, and you can, too, by using WordPress hooks. You can read all about how hooks work in WordPress, but here is the nutshell version, and we will be working with them in this article so much that you’ll learn it by the end.

Hooks enable you to add your own functions to WordPress without modifying core files. Without hooks, if you wanted to send a publication notice to the author of a post, you would have to find the function that published the post and add your own code directly to it. With hooks, you write the function for sending the email, and then hook it into the function that publishes the post. Basically, you are telling WordPress to run your custom function whenever the function for publishing posts runs.

Setting Up Shop

The first thing we’ll have to do is create a plugin. We could get away without it and just use our theme’s functions file, but this would become clunky in the long run. Don’t worry: setting up a plugin is super-easy.

Go to your website’s plugins folder, which can be found under wp-content. Create a new folder named my_awesome_email_plugin. If you want a different name, use something unique, not email or email_plugin; otherwise, conflicts might arise with other plugins.

Create a file named my_awesome_email_plugin.php in the new folder. The name of the file (without the extension) must be the same as the name of the folder.

Edit the contents of my_awesome_email_plugin.php by copying and pasting the code below and modifying it where necessary. This is just some default information that WordPress uses to show the plugin in the plugins menu in the admin area.

<?php
/*
Plugin Name: My Awesome Email Plugin
Plugin URI: http://myawesomewebsite.com
Description: I created this plugin to rule the world via awesome WordPress email goodness
Version: 1.0
Author: Me
Author URI: http://myself.me
*/

?>

Once that’s done, save the file, go to the WordPress admin section, and activate your new plugin. If you’re new to this, then congratulations! You have just created your first working WordPress plugin! It doesn’t really do anything yet, but don’t let that bother you. Just read on, because we’ll be adding some functionality after the next section.

Creating An Email Template

Creating good email templates is worth an article on its own. I will just share the method that I use, which does not mean that doing it differently is not allowed. Feel free to experiment!

I am not a big fan of using images in emails, so we will be building an HTML template using only CSS. Our goal is to come up with a template to which we can add a header and footer section. We will send our emails in WordPress by pulling in the header, putting the email text under that and then pulling in the footer. This way, you can change the design of your emails very easily just by modifying the templates.

Without further ado, here’s the code for the email template that I made. Or you can download it as an HTML file (right-click, and then select “Save as�). If you want a quick preview of what it looks like, just click the link.

<html>
	<head>

		<title>The Subject of My Email</title>

	</head>
	<body>
		<div id="email_container" style="background:#444">
			<div style="width:570px; padding:0 0 0 20px; margin:50px auto 12px auto" id="email_header">
				<span style="background:#585858; color:#fff; padding:12px;font-family:trebuchet ms; letter-spacing:1px;
					-moz-border-radius-topleft:5px; -webkit-border-top-left-radius:5px;
					border-top-left-radius:5px;moz-border-radius-topright:5px; -webkit-border-top-right-radius:5px;
					border-top-right-radius:5px;">
					MyAwesomeWebsite.com
				</div>
			</div>

			<div style="width:550px; padding:0 20px 20px 20px; background:#fff; margin:0 auto; border:3px #000 solid;
				moz-border-radius:5px; -webkit-border-radius:5px; border-radius:5px; color:#454545;line-height:1.5em; " id="email_content">

				<h1 style="padding:5px 0 0 0; font-family:georgia;font-weight:500;font-size:24px;color:#000;border-bottom:1px solid #bbb">
					The subject of this email
				</h1>

				<p>
					Lorem ipsum dolor sit amet, consectetuer adipiscing
					elit. Aenean commodo ligula eget dolor. Aenean massa
					<strong>strong</strong>. Cum sociis natoque penatibus
					et magnis dis parturient montes, nascetur ridiculus
					mus. Donec quam felis, ultricies nec, pellentesque
					eu, pretium quis, sem. Nulla consequat massa quis
					enim. Donec pede justo, fringilla vel, aliquet nec,
					vulputate eget, arcu. In enim justo, rhoncus ut.
				</p>
				<p>
					Imperdiet a, venenatis vitae, justo. Nullam dictum
					felis eu pede <a style="color:#bd5426" href="#">link</a>
					mollis pretium. Integer tincidunt. Cras dapibus.
					Vivamus elementum semper nisi. Aenean vulputate
					eleifend tellus. Aenean leo ligula, porttitor eu,
					consequat vitae, eleifend ac, enim. Aliquam lorem ante,
					dapibus in, viverra quis, feugiat a, tellus. Phasellus
					viverra nulla ut metus varius laoreet. Quisque rutrum.
					Aenean imperdiet. Etiam ultricies nisi vel augue.
					Curabitur ullamcorper ultricies nisi.
				</p> 

				<p style="">
					Warm regards,<br>
					The MyAwesomeWebsite Editor
				</p>

				<div style="text-align:center; border-top:1px solid #eee;padding:5px 0 0 0;" id="email_footer">
					<small style="font-size:11px; color:#999; line-height:14px;">
						You have received this email because you are a member of MyAwesomeSite.com.
						If you would like to stop receiving emails from us, feel free to
						<a href="" style="color:#666">unregister</a> from our mailing list
					</small>
				</div>

			</div>
		</div>
	</body>
</html>

Remember that this is an email, so the HTML won’t be beautiful. The safest styling method is inline, so the fewer frills you can get away with, the better.

Let’s split this into two parts. The header part of the email is everything from the top right up to and including the h1 heading on row 23 (i.e. lines 01 to 23). Copy that bit and paste it into a new file in your my_email_plugin folder, and name it email_header.php. The footer part of the email is everything from the paragraph tag before “Warm regards� right until the end (i.e. lines 48 to 64). The text between the header and footer is just a placeholder so that you can see what the finished product will look like. We will fill it with whatever content we need to send at the time.

Preparing The WordPress System For Our Emails

By default, WordPress sends plain-text emails. In order to accommodate our fancy HTML email, we need to tell the wp_mail() function to use the HTML format. We will also set up a custom “From� name and “From� address in the process, so that the email looks good in everyone’s inbox. To accomplish this, we’ll be using the previously mentioned hooks. Let’s look at the code; explanation follows.

add_filter ("wp_mail_content_type", "my_awesome_mail_content_type");
function my_awesome_mail_content_type() {
	return "text/html";
}

add_filter ("wp_mail_from", "my_awesome_mail_from");
function my_awesome_mail_from() {
	return "hithere@myawesomesite.com";
}

add_filter ("wp_mail_from_name", "my_awesome_mail_from_name");
function my_awesome_email_from_name() {
	return "MyAwesomeSite";
}

On line 01, we have defined that we are adding a filter to the WordPress function wp_mail_content_type(). Our filter will be called my_awesome_mail_content_type. A filter is nothing more than a function, so we need to create the function my_awesome_mail_content_type().

Remember that actions are functions called from within other functions? We add an action to the wp_insert_user() function, and the action is performed whenever wp_insert_user() runs. Filters are specified in much the same way; but, instead of running alongside the function that it is called from, it modifies the value of the entity that it is called on.

In our case, this means that somewhere inside the wp_mail() function is a variable that holds the email type, which is by default text/plain. The filter hook wp_mail_content_type is called on this variable, which means that all attached filters will be run. We happen to have attached a filter to it on line 01, so our function will perform its task. All we need to do is return the value text/html, which will modify the value of the variable in the wp_mail function to text/html.

The logic behind the rest of the code is exactly the same. Adding a filter to wp_mail_from enables us to change the sender’s address to hithere@myawesomewebsite.com, and adding a filter to wp_mail_from_name enables us to change the sender’s name.

Modifying Existing WordPress System Emails

Welcoming New Users

This is the content of the default WordPress email.

As mentioned, WordPress has a bunch of built-in emails that can be easily controlled (using hooks, of course). Let’s modify the default greeting email that WordPress sends out to new users. This email is sent out using a so-called “pluggable function.� This function is supplied by WordPress, but, contrary to the usual core functions, you are allowed to overwrite it with your own code.

The function in question is called wp_new_user_notification(). To modify it, all we need to do is create a function with the same name. Due to the method by which WordPress calls pluggable functions, there will not be any conflict, even though you are creating a function with the same name. Below is the function that I wrote. See the explanation and preview of it further below.

function wp_new_user_notification($user_id, $plaintext_pass) {
	$user = new WP_User($user_id);

	$user_login = stripslashes($user->user_login);
	$user_email = stripslashes($user->user_email);

	$email_subject = "Welcome to MyAwesomeSite ".$user_login."!";

	ob_start();

	include("email_header.php");

	?>

	<p>A very special welcome to you, <?php echo $user_login ?>. Thank you for joining MyAwesomeSite.com!</p>

	<p>
		Your password is <strong style="color:orange"><?php echo $plaintext_pass ?></strong> <br>
		Please keep it secret and keep it safe!
	</p>

	<p>
		We hope you enjoy your stay at MyAwesomeSite.com. If you have any problems, questions, opinions, praise,
		comments, suggestions, please feel free to contact us at any time
	</p>

	<?php
	include("email_footer.php");

	$message = ob_get_contents();
	ob_end_clean();

	wp_mail($user_email, $email_subject, $message);

As you can see, the function is passed two arguments: the ID of the new user and the generated password. We will be using these to generate the variable parts of our message. On line 2, we’ve built a user object that will contain the data of the user in question. On line 7, we’ve created an email subject using the variable $email_subject.

Before we move on, let’s go back to our email_header.php file. Replace “The Subject of My Email� and “The subject of this email� (lines 04 and 22 if you’re looking at the code here) with <?php echo $email_subject ?>. We don’t want all of our subjects to be “The Subject of My Email,� so we need to pull that data from the email that we are building.

From lines 09 to 31, we are using a handy technique called “output buffering.� Because the content email_header.php is not stored inside a variable, it is included directly; this would result in it being printed right away, and we would not be able to use it in our function. To get around this problem, we output buffering. When it is turned on (using ob_start()), no output is sent from the script; instead, it is stored in an internal buffer.

So, first, we include the header, then we write our our message content, then include the footer. Because we are buffering the content, we can simply close our PHP tags and use regular HTML for our message, which I find much cleaner than storing all of it in a variable. On line 30, we pull the contents of the buffer into a variable; and on line 31, we discard the buffer’s content, since we don’t need it anymore.

With that done, we have all of the information needed to use wp_mail(). So, on line 33, we send our email to the user, which should look something like this:

Password Retrieval Emails

For some reason, WordPress doesn’t use the same pluggable functions to handle all emails. For example, to modify the look and feel of the password retrieval emails, we have to resort to hooks. Let’s take a look.

add_filter ("retrieve_password_title", "my_awesome_retrieve_password_title");

function my_awesome_retrieve_password_title() {
	return "Password Reset for MyAwesomeWebsite";
}

add_filter ("retrieve_password_message", "my_awesome_retrieve_password_message");
function my_awesome_retrieve_password_message($content, $key) {
	global $wpdb;
	$user_login = $wpdb->get_var("SELECT user_login FROM $wpdb-<users WHERE user_activation_key = '$key'");

	ob_start();

	$email_subject = imp_retrieve_password_title();

	include("email_header.php");
	?>

	<p>
		It likes like you (hopefully) want to reset your password for your MyAwesomeWebsite.com account.
	</p>

	<p>
		To reset your password, visit the following address, otherwise just ignore this email and nothing will happen.
		<br>
		<?php echo wp_login_url("url") ?>?action=rp&key=<?php echo $key ?>&login=<?php echo $user_login ?>
	<p>

	?>

	include("email_footer.php");

	$message = ob_get_contents();

	ob_end_clean();

	return $message;
}

First, we’ve added a filter to retrieve_password_title, which will modify the default value of the email’s title to our own. Then, we’ve added a filter to retrieve_password_message, which will modify the contents of the message.

On line 10, we’ve used the $wpdb object to query the database for the user’s name based on the key that was generated when the retrieval was initiated. We then do the same thing as before: we start the content buffering, pull our email header, add our message content, and pull our email footer.

One fantastic part about using hooks can be seen on line 14. Our password title needs to be “Password Reset for MyAwesomeWebsite.� We could well have typed that in, but instead we created a function (imp_retrieve_password_title()) that outputs exactly the same thing. It should be clear by now that all we are doing with these hooks is creating regular ol’ functions that can just be plugged into WordPress as actions (which run when initiated by something) or filters (which run and modify data when they are initiated).

This time, instead of using wp_mail(), all we need to do is return the message’s content. This is because we are creating a filter that modifies the contents of the password-retrieval email, nothing else. WordPress will do whatever it usually does to send that email, but now it will use our content.

Pluggable Function and Hooks

This question is not easily answered, because this is not too well documented yet. Your best bet is looking in the file pluggable.php (in your wp-includes folder) to see which emails are controlled from there. Remember not to edit this file; use the plugin we are creating here. You can scan the list of WordPress filters to find filters that control email content.

Right now, most emails are handled through pluggable functions; only the password-retrieval email and some WordPress MU emails are handled using hooks. This might change, as development is quite active, but I would guess that if any new emails are added, you will be able to use pluggable functions.

Here is a list of emails that you can modify using pluggable functions:

  • Notify authors of comments: wp_notify_postauthor()
  • Notify moderator of comments waiting for approval: wp_notify_moderator()
  • Notify administrator of password changes on the website: wp_password_change_notification()
  • Notify administrator of new registrations: wp_new_user_notification()

Adding New Emails To The System

So far, we’ve just been modifying what WordPress has to offer. Now it’s time to add some emails of our own! Let’s implement an email that will notify an author when you have published their post.

To accomplish this, we need to find the WordPress action hook that publishes a post when we press the “Publish� button. We then have to hook our own function into that, which will perform the task of sending the email.

Looking at the list of action hooks, we can see that the hook we are looking for is called {$new_status}_{$post->post_type}. This looks a bit different than what we’re used to, but it’s really very simple. A post can go through numerous statuses. It can be a draft, it can be private, published and so on. There are also a lot of potential post types, such as “Post� and “Page,� not to mention that you can create custom post types. This hook simply enables us to put a status and a post type together and then get the hook that runs when that post’s type changes to the indicated status. So, our hook will be called publish_post.

add_action("publish_post", "my_awesome_publication_notification");

function my_awesome_publication_notification($post_id) {
	$post = get_post($post_id);
	$author = get_userdata($post->post_author);

	$author_email = $author->user_email;
    $email_subject = "Your article has been published!";

	ob_start();

	include("email_header.php");

	?>

	<p>
		Hi, <?php echo $author->display_name ?>. I've just published one of your articles
		(<?php echo $post->post_title ?>) on MyAwesomeWebsite!
	</p>

	<p>
		If you'd like to take a look, <a href="<?php echo get_permalink($post->ID) ?>">click here</a>.
		I would appreciate it if you could come back now and again to respond to some comments.
	</p>

	<?php

	include("email_footer.php");

	$message = ob_get_contents();

	ob_end_clean();

	wp_mail($author_email, $email_subject, $message);

}

By now, this should be second nature to you. The only real difference here is that we have to retrieve the data of the post, and the author’s data on lines 4 and 5, so that we have the necessary data for the email.

One thing you might be wondering is how I know that my function takes the ID of this post as its argument. I cannot freely choose this value, of course; it is dictated by how WordPress is built. Every hook supplies different arguments; some even supply more than one. To find out what arguments are at your disposal, you will have to go into some core files.

I suggest browsing the hooks database, clicking on the hook that you need, and then clicking on “View hook in source� next to your version of WordPress (preferably the latest one). Once there, scroll down, and find the highlighted line, which is where the hook is called. It will be in the form of do_action( $tag, $arg_a, $arg_b, $etc ) or apply_filters( $tag, $arg_a, $arg_b, $etc ).

Extending Our Functions

Interestingly, the wp_mail() function itself is a pluggable function, so you can completely override how it works. This may be going a bit over the top, but if you need some serious email-sending power (for example, you want a system that notifies your 120,000 registered users about new posts), you can completely modify it to use your mass-mailer application.

Because we are using a template for email headers and footers, a lot can be done to extend our emails. We can distinguish between emails to staff and emails to users by using different header files; we can add the latest three posts to the bottom of each email by using footer templates; and so on.

We can add a table to our database that holds information about which users are emailed the most, who responds to emails, and so on. Whenever you plug a function into something, it can contain any sort of code you’d like. You could include code for increasing the email count for user #112 inside the function that sends them the email, for example. This is not a good practice (you should create separate functions and plug them both in), but getting to grips with the vast power that this methodology offers is important.

A Word Of Warning

While the method described here is great, I am not an expert in creating HTML emails. The code for the HTML email above is tested to work in Gmail and some other applications, but each email application handles email differently. Some strip out all CSS, some strip out just background colors, and so on.

Before using the template, please test it with the most common applications (Gmail, Yahoo Mail, Apple Mail, Outlook, Entourage, Thunderbird, etc.) to make sure it works as expected.

Conclusion

Hopefully by now you have learned how to modify the emails that WordPress sends out, how to create your own emails, and how to plug them into different actions.

I also hope that your knowledge of WordPress hooks has expanded, because they are the tool for creating great plugins and add-ons for WordPress, and the thinking behind them is a glimpse into the world of object-oriented programming.

If you have any questions or comments, let me know: I am at your disposal. Also, if you’ve created a similar system, do share your thoughts, I would be happy to hear how you’ve accomplished the same, or better!

(al)


© Daniel Pataki for Smashing Magazine, 2011.


WordPress Essentials: The Definitive Guide To WordPress Hooks





 



 


If you’re into WordPress development, you can’t ignore hooks for long before you have to delve into them head on. Modifying WordPress core files is a big no-no, so whenever you want to change existing functionality or create new functionality, you will have to turn to hooks.

wp-hooks-guide

In this article, I would like to dispel some of the confusion around hooks, because not only are they the way to code in WordPress, but they also teach us a great design pattern for development in general. Explaining this in depth will take a bit of time, but bear with me: by the end, you’ll be able to jumble hooks around like a pro.

Why Hooks Exist

I think the most important step in grasping hooks is to understand the need for them. Let’s create a version of a WordPress function that already exists, and then evolve it a bit using the “hooks mindset.�

   function get_excerpt($text, $length = 150) {
      $excerpt = substr($text,$length)
      return $excerpt;
   }

This function takes two parameters: a string and the length at which we want to cut it. What happens if the user wants a 200-character excerpt instead of a 150-character one? They just modify the parameter when they use the function. No problem there.

If you use this function a lot, you will notice that the parameter for the text is usually the post’s content, and that you usually use 200 characters instead of the default 150. Wouldn’t it be nice if you could set up new defaults, so that you didn’t have to add the same parameters over and over again? Also, what happens if you want to add some more custom text to the end of the excerpt?

These are the kinds of problems that hooks solve. Let’s take a quick look at how.

   function get_excerpt($text, $length = 150) {

      $length = apply_filters("excerpt_length", $length);

      $excerpt = substr($text,$length)
      return $excerpt;
   }

As you can see, the default excerpt length is still 150, but we’ve also applied some filters to it. A filter allows you to write a function that modifies the value of something — in this case, the excerpt’s length. The name (or tag) of this filter is excerpt_length, and if no functions are attached to it, then its value will remain 150. Let’s see how we can now use this to modify the default value.

   function get_excerpt($text, $length = 150) {

      $length = apply_filters("excerpt_length");

      $excerpt = substr($text,$length)
      return $excerpt;
   }

   function modify_excerpt_length() {
      return 200;
   }

   add_filter("excerpt_length", "modify_excerpt_length");

First, we have defined a function that does nothing but return a number. At this point, nothing is using the function, so let’s tell WordPress that we want to hook this into the excerpt_length filter.

We’ve successfully changed the default excerpt length in WordPress, without touching the original function and without even having to write a custom excerpt function. This will be extremely useful, because if you always want excerpts that are 200 characters long, just add this as a filter and then you won’t have to specify it every time.

Suppose you want to tack on some more text, like “Read on,� to the end of the excerpt. We could modify our original function to work with a hook and then tie a function to that hook, like so:

   function get_excerpt($text, $length = 150) {

      $length = apply_filters("excerpt_length");

      $excerpt = substr($text,$length)
      return apply_filters("excerpt_content", $excerpt);
   }

   function modify_excerpt_content($excerpt) {
      return $excerpt . "Read on…";
   }
   add_filter("excerpt_content", "modify_excerpt_content");

This hook is placed at the end of the function and allows us to modify its end result. This time, we’ve also passed the output that the function would normally produce as a parameter to our hook. The function that we tie to this hook will receive this parameter.

All we are doing in our function is taking the original contents of $excerpt and appending our “Read on� text to the end. But if we choose, we could also return the text “Click the title to read this article,� which would replace the whole excerpt.

While our example is a bit redundant, since WordPress already has a better function, hopefully you’ve gotten to grips with the thinking behind hooks. Let’s look more in depth at what goes on with filters, actions, priorities, arguments and the other yummy options available.

Filters And Actions

Filters and actions are two types of hooks. As you saw in the previous section, a filter modifies the value of something. An action, rather than modifying something, calls another function to run beside it.

A commonly used action hook is wp_head. Let’s see how this works. You may have noticed a function at the bottom of your website’s head section named wp_head(). Diving into the code of this function, you can see that it contains a call to do_action(). This is similar to apply_filters(); it means to run all of the functions that are tied to the wp_head tag.

Let’s put a copyright meta tag on top of each post’s page to test how this works.

   add_action("wp_head", "my_copyright_meta");

   function my_copyright_meta() {
      if(is_singular()){
         echo "";
      }
   }

The Workflow Of Using Hooks

While hooks are better documented nowadays, they have been neglected a bit until recently, understandably so. You can find some good pointers in the Codex, but the best thing to use is Adam Brown’s hook reference, and/or look at the source code.

Say you want to add functionality to your blog that notifies authors when their work is published. To do this, you would need to do something when a post is published. So, let’s try to find a hook related to publishing.

Can we tell whether we need an action or a filter? Sure we can! When a post is published, do we want to modify its data or do a completely separate action? The answer is the latter, so we’ll need an action. Let’s go to the action reference on Adam Brown’s website, and search for “Publish.�

The first thing you’ll find is app_publish_post. Sounds good; let’s click on it. The details page doesn’t give us a lot of info (sometimes it does), so click on the “View hook in source� link next to your version of WordPress (preferably the most recent version) in the table. This website shows only a snippet of the file, and unfortunately the beginning of the documentation is cut off, so it’s difficult to tell if this is what we need. Click on “View complete file in SVN� to go to the complete file so that we can search for our hook.

In the file I am viewing, the hook can be found in the _publish_post_hook() function, which — according to the documentation above it — is a “hook to schedule pings and enclosures when a post is published,â€� so this is not really what we need.

With some more research in the action list, you’ll find the publish_post hook, and this is what we need. The first thing to do is write the function that sends your email. This function will receive the post’s ID as an argument, so you can use that to pull some information into the email. The second task is to hook this function into the action. Look at the finished code below for the details.

   function authorNotification($post_id) {
      global $wpdb;
      $post = get_post($post_id);
      $author = get_userdata($post->post_author);

      $message = "
         Hi ".$author->display_name.",
         Your post, ".$post->post_title." has just been published. Well done!
      ";
      wp_mail($author->user_email, "Your article is online", $message);
   }
   add_action('publish_post', 'authorNotification');

Notice that the function we wrote is usable in its own right. It has a very specific function, but it isn’t only usable together with hooks; you could use it in your code any time. In case you’re wondering, wp_mail() is an awesome mailer function — have a look at the WordPress Codex for more information.

This process might seem a bit complicated at first, and, to be totally honest, it does require browsing a bit of documentation and source code at first, but as you become more comfortable with this system, your time spent researching what to use and when to use it will be reduced to nearly nothing.

Priorities

The third parameter when adding your actions and filters is the priority. This basically designates the order in which attached hooks should run. We haven’t covered this so far, but attaching multiple functions to a hook is, of course, possible. If you want an email to be sent to an author when their post is published and to also automatically tweet the post, these would be written in two separate functions, each tied to the same tag (publish_post).

Priorities designate which hooked function should run first. The default value is 10, but this can be changed as needed. Priorities usually don’t make a huge difference, though. Whether the email is sent to the author before the article is tweeted or vice versa won’t make a huge difference.

In rarer cases, assigning a priority could be important. You might want to overwrite the actions of other plugins (be careful, in this case), or you might want to enforce a specific order. I recently had to overwrite functionality when I was asked to optimize a website. The website had three to four plugins, with about nine JavaScript files in total. Instead of disabling these plugins, I made my own plugin that overwrote some of the JavaScript-outputting functionality of those plugins. My plugin then added the minified JavaScript code in one file. This way, if my plugin was deactivated, all of the other plugins would work as expected.

Specifying Arguments

The fourth argument when adding filters and actions specifies how many arguments the hooked function takes. This is usually dictated by the hook itself, and you will need to look at the source to find this information.

As you know from before, your functions are run when they are called by apply_filters() or do_action(). These functions will have the tag as their first argument (i.e. the name of the hook you are plugging into) and then passed arguments as subsequent arguments.

For example, the filter default_excerpt receives two parameters, as seen in includes/post.php.

   $post->post_excerpt = apply_filters( 'default_excerpt', $post_excerpt, $post );

The arguments are well named — $post_excerpt and $post — so it’s easy to guess that the first is the excerpt text and the second is the post’s object. If you are unsure, it is usually easiest either to look further up in the source or to output them using a test function (make sure you aren’t in a production environment).

   function my_filter_test($post_excerpt, $post) {
      echo "<pre>";
         print_r($post_excerpt);
         print_r($post);
      echo "</pre>";
   }
   add_filter("default_excerpt", "my_filter_test");

Variable Hook Names

Remember when we looked at the publish_post action? In fact, this is not used anymore; it was renamed in version 2.3 to {$new_status}_{$post->post_type}. With the advent of custom post types, it was important to make the system flexible enough for them. This new hook now takes an arbitrary status and post type (they must exist for it to work, obviously).

As a result, publish_post is the correct tag to use, but in reality, you will be using {$new_status}_{$post->post_type}. A few of these are around; the naming usually suggests what you will need to name the action.

Who Is Hooked On Who?

To find out which function hooks into what, you can use the neat script below, courtesy of WP Recipes. Use this function without arguments to get a massive list of everything, or add a tag to get functions that are hooked to that one tag. This is a great one to keep in your debugging tool belt!

function list_hooked_functions($tag=false){
 global $wp_filter;
 if ($tag) {
  $hook[$tag]=$wp_filter[$tag];
  if (!is_array($hook[$tag])) {
  trigger_error("Nothing found for '$tag' hook", E_USER_WARNING);
  return;
  }
 }
 else {
  $hook=$wp_filter;
  ksort($hook);
 }
 echo '<pre>';
 foreach($hook as $tag => $priority){
  echo "<br /><strong>$tag</strong><br />";
  ksort($priority);
  foreach($priority as $priority => $function){
  echo $priority;
  foreach($function as $name => $properties) echo "\t$name<br />";
  }
 }
 echo '</pre>';
 return;
}

Creating Your Own Hooks

A ton of hooks are built into WordPress, but nothing is stopping you from creating your own using the functions we’ve looked at so far. This may be beneficial if you are building a complex plugin intended for wide release; it will make your and other developers’ jobs a lot easier!

In the example below, I have assumed we are building functionality for users to post short blurbs on your website’s wall. We’ll write a function to check for profanity and hook it to the function that adds the blurbs to the wall.

Look at the full code below. The explanation ensues.

   function post_blurb($user_id, $text) {

      $text = apply_filters("blurb_text", $text);

      if(!empty($text)) {
         $wpdb->insert('my_wall', array("user_id" => $user_id, "date" => date("Y-m-d H:i:s"), "text" => $text), array("%d", %s", "%s"));
      }
   }

   function profanity_filter($text) {
      $text_elements = explode(" ", $text);
      $profanity = array("badword", "naughtyword", "inappropriatelanguage");

      if(array_intersect($profanity, $text_elements)) {
         return false;
      }
      else {
         return $text;
      }
   }

   add_filter("blurb_text", "profanity_filter");

The first thing in the code is the designation of the function that adds the blurb. Notice that I included the apply_filters() function, which we will use to add our profanity check.

Next up is our profanity-checking function. This checks the text as its argument against an array of known naughty words. By using array_intersect(), we look for array elements that are in both arrays — these would be the profane words. If there are any, then return false; otherwise, return the original text.

The last part actually hooks this function into our blurb-adding script.

Now other developers can hook their own functions into our script. They could build a spam filter or a better profanity filter. All they would need to do is hook it in.

Mixing And Matching

The beauty of this system is that it uses functions for everything. If you want, you can use the same profanity filter for other purposes, even outside of WordPress, because it is just a simple function. Already have a profanity-filter function? Copy and paste it in; all you’ll need to do is add the one line that actually hooks it in. This makes functions easily reusable in various situations, giving you more flexibility and saving you some time as well.

That’s All

Hopefully, you now fully understand how the hooks system works in WordPress. It contains an important pattern that many of us could use even outside of WordPress.

This is one aspect of WordPress that does take some time getting used to if you’re coming to it without any previous knowledge. The biggest problem is usually that people get lost in all of the filters available or in finding their arguments and so on, but with some patience this can be overcome easily. Just start using them, and you’ll be a master in no time!

(al)


© Daniel Pataki for Smashing Magazine, 2011.


WordPress Essentials: How To Create A WordPress Plugin





 



 


WordPress plugins are PHP scripts that alter your website. The changes could be anything from the simplest tweak in the header to a more drastic makeover (such as changing how log-ins work, triggering emails to be sent, and much more).

Whereas themes modify the look of your website, plugins change how it functions. With plugins, you can create custom post types, add new tables to your database to track popular articles, automatically link your contents folder to a “CDN� server such as Amazon S3… you get the picture.

Screenshot

Theme Or Plugin?

If you’ve ever played around with a theme, you’ll know it has a functions.php file, which gives you a lot of power and enables you to build plugin-like functionality into your theme. So, if we have this functions.php file, what’s the point of a plugin? When should we use one, and when should we create our own?

The line here is blurrier than you might think, and the answer will often depend on your needs. If you just want to modify the default length of your posts’ excerpts, you can safely do it in functions.php. If you want something that lets users message each other and become friends on your website, then a plugin would better suit your needs.

The main difference is that a plugin’s functionality persists regardless of what theme you have enabled, whereas any changes you have made in functions.php will stop working once you switch themes. Also, grouping related functionality into a plugin is often more convenient than leaving a mass of code in functions.php.

Creating Our First PlugIn

To create a plugin, all you need to do is create a folder and then create a single file with one line of content. Navigate to the wp-content/plugins folder, and create a new folder named awesomeplugin. Inside this new folder, create a file named awesomeplugin.php. Open the file in a text editor, and paste the following information in it:

<?php
   /*
   Plugin Name: Awesomeness Creator
   Plugin URI: http://my-awesomeness-emporium.com
   Description: a plugin to create awesomeness and spread joy
   Version: 1.2
   Author: Mr. Awesome
   Author URI: http://mrtotallyawesome.com
   License: GPL2
   */
?>

Of all this information, only the plugin’s name is required. But if you intend to distribute your plugin, you should add as much data as possible.

With that out of the way, you can go into the back end to activate your plugin. That’s all there is to it! Of course, this plugin doesn’t do anything; but strictly speaking, it is an active, functioning plugin.

Structuring PlugIns

When creating complex functionality, splitting your plugin into multiple files and folders might be easier. The choice is yours, but following a few good tips will make your life easier.

If your plugin focuses on one main class, put that class in the main plugin file, and add one or more separate files for other functionality. If your plugin enhances WordPress’ back end with custom controls, you can create the usual CSS and JavaScript folders to store the appropriate files.

Generally, aim for a balance between layout structure, usability and minimalism. Split your plugin into multiple files as necessary, but don’t go overboard. I find it useful to look at the structure of popular plugins such as WP-PageNavi and Akismet.

Naming Your PlugIn And Its Functions

When creating a plugin, exercise caution in naming the functions, classes and plugin itself. If your plugin is for generating awesome excerpts, then calling it “excerpts� and calling its main function “the_excerpt� might seem logical. But these names are far too generic and might clash with other plugins that have similar functionality with similar names.

The most common solution is to use unique prefixes. You could use “acme_excerpt,� for example, or anything else that has a low likelihood of matching someone else’s naming scheme.

Plugin Safety

If you plan to distribute your plugin, then security is of utmost importance, because now you are fiddling with other people’s websites, not just your own. All of the security measures you should take merit their own article, so keep an eye out for an upcoming piece on how to secure your plugin. For now, let’s just look at the theory in a nutshell; you can worry about implementation once you grasp that.

The safety of your plugin usually depends on the stability of its two legs. One leg makes sure that the plugin does not help spread naughty data. Guarding against this entails filtering the user’s input, escaping queries to protect against SQL injection attacks and so on. The second leg makes sure that the user has the authority and intention to perform a given action. This basically means that only users with the authority to delete data (such as administrators) should be able to do it. Guarding intention ensures that visitors aren’t misled by a hacker who has managed to place a malicious link on your website.

All of this is much easier to do than you might think, because WordPress gives you many functions to handle it. A number of other issues and best practices are involved, however, so we’ll cover those in a future article. There is plenty to learn and do until then; if you’re just starting out, don’t worry about all that for now.

Cleaning Up After Yourself

Many plugins are guilty of leaving a lot of unnecessary data lying around. Data that only your plugin uses (such as meta data for posts or comments, database tables, etc.) can wind up as dead weight if the plugin doesn’t clean up after itself.

WordPress offers three great hooks to help you take care of this:

  • register_activation_hook()
    This hook allows you to create a function that runs when your plugin is activated. It takes the path to your main plugin file as the first argument, and the function that you want to run as the second argument. You can use this to check the version of your plugin, do some upgrades between versions, check for the correct PHP version and so on.
  • register_deactivation_hook()
    The name says it all. This function works like its counterpart above, but it runs whenever your plugin is deactivated. I suggest using the next function when deleting data; use this one just for general housekeeping.
  • register_uninstall_hook()
    This function runs when the website administrator deletes your plugin in WordPress’ back end. This is a great way to remove data that has been lying around, such as database tables, settings and what not. A drawback to this method is that the plugin needs to be able to run for it to work; so, if your plugin cannot uninstall in this way, you can create an uninstall.php file. Check out this function’s documentation for more information.

If your plugin tracks the popularity of content, then deleting the tracked data when the user deletes the plugin might not be wise. In this case, at least point the user to the location in the back end where they can find the plugin’s data, or give them the option to delete the data on the plugin’s settings page before deleting the plugin itself.

The net result of all our effort is that a user should be able to install your plugin, use it for 10 years and then delete it without leaving a trace on the website, in the database or in the file structure.

Documentation And Coding Standards

If you are developing for a big community, then documenting your code is considered good manners (and good business). The conventions for this are fairly well established — phpDocumentor is one example. But as long as your code is clean and has some documentation, you should be fine.

I document code for my own benefit as well, because I barely remember what I did yesterday, much less the purpose of functions that I wrote months back. By documenting code, you force good practices on yourself. And if you start working on a team or if your code becomes popular, then documentation will be an inevitable part of your life, so you might as well start now.

While not quite as important as documentation, following coding standards is a good idea if you want your code to comply with WordPress’ guidelines.

Putting It Into Practice

All work and no play makes Jack a dull boy, so let’s do something with all of this knowledge that we’ve just acquired. To demonstrate, let’s build a quick plugin that tracks the popularity of our articles by storing how many times each post has been viewed. I will be using hooks, which we’ll cover in an upcoming installment in this series. Until then, as long as you grasp the logic behind them, all is well; you will understand hooks and plugins before long!

Planning Ahead

Before writing any code, let’s think ahead and try to determine the functions that our plugin will need. Here’s what I’ve come up with:

  • A function that registers a view every time an individual post is shown,
  • A function that enables us to retrieve the raw number of views,
  • A function that enables us to show the number of views to the user,
  • A function that retrieves a list of posts based on their view count.

Preparing Our Function

The first step is to create the folder and file structure. Putting all of this into one file will be fine, so let’s go to the plugins folder and create a new folder named awesomely_popular. In this folder, create a file named awesomely_popular.php. Open your new file, and paste some meta data at the top, something like this:

<?php
   /*
   Plugin Name: Awesomely Popular
   Plugin URI: http://awesomelypopularplugin.com
   Description: A plugin that records post views and contains functions to easily list posts by popularity
   Version: 1.0
   Author: Mr. Awesome
   Author URI: http://mayawesomefillyourbelly.com
   License: GPL2
   */
?>

Recording Post Views

Without delving too deep, WordPress hooks enable you to (among other things) fire off one of your functions whenever another WordPress function runs. So, if we can find a function that runs whenever an individual post is viewed, we are all set; all we would need to do is write our own function that records the number of views and hook it in. Before we get to that, though, let’s write the new function itself. Here is the code:

/**
 * Adds a view to the post being viewed
 *
 * Finds the current views of a post and adds one to it by updating
 * the postmeta. The meta key used is "awepop_views".
 *
 * @global object $post The post object
 * @return integer $new_views The number of views the post has
 *
 */
function awepop_add_view() {
   if(is_single()) {
      global $post;
      $current_views = get_post_meta($post->ID, "awepop_views", true);
      if(!isset($current_views) OR empty($current_views) OR !is_numeric($current_views) ) {
         $current_views = 0;
      }
      $new_views = $current_views + 1;
      update_post_meta($post->ID, "awepop_views", $new_views);
      return $new_views;
   }
}

As you can see, I have added phpDocumentor-style documentation to the top of the function, and this is a pretty good indication of what to expect from this convention. First of all, using a conditional tag, we determine whether the user is viewing a post on a dedicated page.

If the user is on a dedicated page, we pull in the $post object, which contains data about the post being shown (ID, title, posting date, comment count, etc.). We then retrieve the number of views that the post has already gotten. We will add 1 to this and then overwrite the orignal value with the new one. In case something goes wrong, we first check whether the current view count is what it should be.

The current view count must be set; it cannot be empty. And it must be numeric in order for us to be able to add 1 to it. If it does not meet these criteria, then we could safely bet that the current view count is 0. Next, we add 1 to it and save it to the database. Finally, we return the number of views that the post has gotten, together with this latest number.

So far, so good. But this function is never called, so it won’t actually be used. This is where hooks come in. You could go into your theme’s files and call the function manually from there. But then you would lose that functionality if you ever changed the theme, thus defeating the entire purpose. A hook, named wp_head, that runs just before the </head> tag is present in most themes, so we can just set our function to run whenever wp_head runs, like so:

add_action("wp_head", "awepop_add_view");

That’s all there is to the “mysticism� of hooks. We are basically saying, whenever wp_head runs, also execute the awepop_add_view function. You can place the code before or after the function itself.

Retrieving and Showing the Views

In the function above, I already use the WordPress get_post_meta() function to retrieve the views, so writing a separate function for this might seem a bit redundant. In this case, it might well be redundant, but it promotes some object-oriented thinking, and it gives us greater flexibility when further developing the plugin. Let’s take a look:

/**
 * Retrieve the number of views for a post
 *
 * Finds the current views for a post, returning 0 if there are none
 *
 * @global object $post The post object
 * @return integer $current_views The number of views the post has
 *
 */
function awepop_get_view_count() {
   global $post;
   $current_views = get_post_meta($post->ID, "awepop_views", true);
   if(!isset($current_views) OR empty($current_views) OR !is_numeric($current_views) ) {
      $current_views = 0;
   }

   return $current_views;
}

This is the same piece of code that we used in the awepop_add_view() function, so you could just use this to retrieve the view count there as well. This is handy, because if you decide to handle the 0 case differently, you only need to change it here. You will also be able to extend this easily and provide support for cases when we are not in the loop (i.e. when the $post object is not available).

So far, we have just retrieved the view count. Now, let’s show it. You might be thinking this is daft — all we need is echo awepop_get_view_count() . "views", no? That would certainly work, but what if there is only 1 view. In this case, we would need to use the singular “view.â€� You might also want the freedom to add some leading text or some other tidbit, which would be difficult to do otherwise. So, to allow for these scenarios, let’s write another simple function:

/**
 * Shows the number of views for a post
 *
 * Finds the current views of a post and displays it together with some optional text
 *
 * @global object $post The post object
 * @uses awepop_get_view_count()
 *
 * @param string $singular The singular term for the text
 * @param string $plural The plural term for the text
 * @param string $before Text to place before the counter
 *
 * @return string $views_text The views display
 *
 */
function awepop_show_views($singular = "view", $plural = "views", $before = "This post has: ") {
   global $post;
   $current_views = awepop_get_view_count();

   $views_text = $before . $current_views . " ";

   if ($current_views == 1) {
      $views_text .= $singular;
   }
   else {
      $views_text .= $plural;
   }

   echo $views_text;

}

Show a List of Posts Based on Views

To show a list of posts based on view count, we create a function that we can place anywhere in our theme. The function will use a custom query and loop through the results, displaying a simple list of titles. The code is below, and the explanation follows.

/**
 * Displays a list of posts ordered by popularity
 *
 * Shows a simple list of post titles ordered by their view count
 *
 * @param integer $post_count The number of posts to show
 *
 */
function awepop_popularity_list($post_count = 10) {
   $args = array(
      "posts_per_page" => 10,
      "post_type" => "post",
      "post_status" => "publish",
      "meta_key" => "awepop_views",
      "orderby" => "meta_value_num",
      "order" => "DESC"
   );

   $awepop_list = new WP_Query($args);

   if($awepop_list->have_posts()) {
      echo "
    "; } while ( $awepop_list->have_posts() ) : $awepop_list->the_post(); echo "
  • ".the_title('', '', false)."
  • "; endwhile; if($awepop_list->have_posts()) { echo "
"; } }

We start by passing a bunch of parameters to the WP_Query class, in order to create a new object that contains some posts. This class will do the heavy lifting for us: it finds 10 published posts that have awepop_views in the meta table, and orders them according to this property in descending order.

If posts meet this criterion, we create an unordered list element. Then, we loop through all of the posts that we have retrieved, showing each title as a link to the relevant post. We cap things off by adding a closing tag to the list when there are posts to show. Placing the awepop_popularity_list() function anywhere in your theme should now generate a simple list of posts ordered by popularity.

As an added precaution, place the call to this function in your theme, like so:

if (function_exists("awepop_popularity_list")) {
   awepop_popularity_list();
}

This ensures that if the plugin is disabled (and thus the function becomes undefined), PHP won’t throw a big ol’ error. It just won’t show the list of most popular posts.

Overview

By following the theory laid down in this article and using only a handful of functions, we have created a rudimentary plugin to track our most popular posts. It could be vastly improved, but it shows the basics of using plugins perfectly well. Moreover, by learning some patterns of WordPress development (plugins, hooks, etc.), you are gaining skills that will serve you in non-WordPress environments as well.

You should now be able to confidently follow tutorials that start with “First, create a WordPress plugin…� You now understand things not just on a need-to-know basis, but at a deeper level, which gives you more flexibility and power when coding your own plugins. Stay tuned for the upcoming article on hooks, actions and filters for an even more in-depth resource on the innards of plugins.

(al)


© Daniel Pataki for Smashing Magazine, 2011.


WordPress Essentials: Interacting With The WordPress Database





 



 


While you already use many functions in WordPress to communicate with the database, there is an easy and safe way to do this directly, using the $wpdb class. Built on the great ezSQL class by Justin Vincent, $wpdb enables you to address queries to any table in your database, and it also helps you handle the returned data. Because this functionality is built into WordPress, there is no need to open a separate database connection (in which case, you would be duplicating code), and there is no need to perform hacks such as modifying a result set after it has been queried.

$wpdb class
The $wpdb class modularizes and automates a lot of database-related tasks.

In this article, I will show you how to get started with the $wpdb class, how to retrieve data from your WordPress database and how to run more advanced queries that update or delete something in the database. The techniques here will remove some of the constraints that you run into with functions such as get_posts() and wp_list_categories(), allowing you to tailor queries to your particular needs. This method can also make your website more efficient by getting only the data that you need — nothing more, nothing less.

Getting Started

If you know how MySQL or similar languages work, then you will be right at home with this class, and you will need to keep only a small number of function names in mind. The basic usage of this class can be best understood through an example, so let’s query our database for the IDs and titles of the four most recent posts, ordered by comment count (in descending order).

<?php
   $posts = $wpdb->get_results("SELECT ID, post_title FROM wp_posts WHERE post_status = 'publish'
   AND post_type='post' ORDER BY comment_count DESC LIMIT 0,4")
?>

As you can see, this is a basic SQL query, with some PHP wrapped around it. The $wpdb class contains a method (a method is a special name for functions that are inside classes), named get_results(), which will not only fetch your results but put them in a convenient object. You might have noticed that, instead of using wp_posts for the table’s name, I have used $wpdb->posts, which is a helper to access your core WordPress tables. More on why to use these later.

The $results object now contains your data in the following format:

Array
(
   [0] => stdClass Object
      (
         [ID] => 6
         [post_title] => The Male Angler Fish Gets Completely Screwed
      )

   [1] => stdClass Object
      (
         [ID] => 25
         [post_title] => 10 Truly Amazing Icon Sets From Germany
      )

   [2] => stdClass Object
      (
         [ID] => 37
         [post_title] => Elderberry Is Awesome
      )

   [3] => stdClass Object
      (
         [ID] => 60
         [post_title] => Gathering Resources and Inspiration With Evernote
      )

)

Retrieving Results From The Database

If you want to retrieve some information from the database, you can use one of four helper functions to structure the data.

get_results()

This is the function that we looked at earlier. It is best for when you need two-dimensional data (multiple rows and columns). It converts the data into an array that contains separate objects for each row.

<?php
   $posts = $wpdb->get_results("SELECT ID, post_title FROM wp_posts WHERE post_status = 'future'
   AND post_type='post' ORDER BY post_date ASC LIMIT 0,4")

   // Echo the title of the first scheduled post
   echo $posts[0]->post_title;
?>

get_row

When you need to find only one particular row in the database (for example, the post with the most comments), you can use get_row(). It pulls the data into a one-dimensional object.

<?php
   $posts = $wpdb->get_row("SELECT ID, post_title FROM wp_posts WHERE post_status = 'publish'
   AND post_type='post' ORDER BY comment_count DESC LIMIT 0,1")

   // Echo the title of the most commented post
   echo $posts->post_title;
?>

get_col

This method is much the same as get_row(), but instead of grabbing a single row of results, it gets a single column. This is helpful if you would like to retrieve the IDs of only the top 10 most commented posts. Like get_row(), it stores your results in a one-dimensional object.

<?php
   $posts = $wpdb->get_col("SELECT ID FROM wp_posts WHERE post_status = 'publish'
   AND post_type='post' ORDER BY comment_count DESC LIMIT 0,10")

   // Echo the ID of the 4th most commented post
   echo $posts[3]->ID;
?>

get_var

In many cases, you will need only one value from the database; for example, the email address of one of your users. In this case, you can use get_var to retrieve it as a simple value. The value’s data type will be the same as its type in the database (i.e. integers will be integers, strings will be strings).

<?php
   $email = $wpdb->get_var("SELECT user_email FROM wp_users WHERE user_login = 'danielpataki' ")

   // Echo the user's email address
   echo $email;
?>

Inserting Into The Database

To perform an insert, we can use the insert method:

$wpdb->insert( $table, $data, $format);

This method takes three arguments. The first specifies the name of the table into which you are inserting the data. The second argument is an array that contains the columns and their respective values, as key-value pairs. The third parameter specifies the data type of your values, in the order you have given them. Here’s an example:

<?php
   $wpdb->insert($wpdb->usermeta, array("user_id" => 1, "meta_key" => "awesome_factor", "meta_value" => 10), array("%d", %s", "%d"));

   // Equivalent to:
   // INSERT INTO wp_usermeta (user_id, meta_key, meta_value) VALUES (1, "awesome_factor", 10);
?>

If you’re used to writing out your inserts, this may seem unwieldy at first, but it actually gives you a lot of flexibility because it uses arrays as inputs.

Specifying the format is optional; all values are treated as strings by default, but including this in the method is a good practice. The three values you can use are %s for strings, %d for decimal numbers and %f for floats.

Updating Your Data

By now, you won’t be surprised to hear that we also have a helper method to update our data — shockingly, called update(). Its use resembles what we saw above; but to handle the where clause of our update, it needs two extra parameters.

$wpdb->update( $table, $data, $where, $format = null, $where_format = null );

The $table, $data and $format parameters should be familiar to you; they are the same as before. Using the $where parameter, we can specify the conditions of the update. It should be an array in the form of column-value pairs. If you specify multiple parameters, then they will be joined with AND logic. The $where_format is just like $format: it specifies the format of the values in the $where parameter.

$wpdb->update( $wpdb->posts, array("post_title" => "Modified Post Title"), array("ID" => 5), array("%s"), array("%d") );

Other Queries

While the helpers above are great, sometimes performing different or more complex queries than the helpers allow is necessary. If you need to perform an update with a complex where clause containing multiple AND/OR logic, then you won’t be able to use the update() method. If you wanted to do something like delete a row or set a connection character set, then you would need to use the “general� query() method, which let’s you perform any sort of query.

$wpdb->query("DELETE FROM wp_usermeta WHERE meta_key = 'first_login' OR meta_key = 'security_key' ");

Protection And Validation

I hope I don’t have to tell you how important it is to make sure that your data is safe and that your database can’t be tampered with! Data validation is a bit beyond the scope of this article, but do take a look at what the WordPress Codex has to say about “Data Validation� at some point.

In addition to validating, you will need to escape all queries. Even if you are not familiar with SQL injection attacks, still use this method and then read up on it later, because it is critical.

The good news is that if you use any of the helper functions, then you don’t need to do anything: the query is escaped for you. If you use the query() method, however, you will need to escape manually, using the prepare() method.

$sql = $wpdb->prepare( 'query' [, value_parameter, value_parameter ... ] );

To make this a bit more digestible, let’s rewrite this basic format a bit.

$sql = $wpdb->prepare( "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value ) VALUES ( %d, %s, %d )", 3342, 'post_views', 2290 )
$wpdb->query($sql);

As you can see, this is not that scary. Instead of adding the actual values where you usually would, you enter the type of data, and then you add the actual data as subsequent parameters.

Class Variables And Other Methods

Apart from these excellent methods, there are quite a few other functions and variables to make your life easier. I’ll show you some of the most common ones, but please do look at the WordPress Codex page linked to above for a full list of everything that $wpdb has to offer.

insert_id()

Whenever you insert something into a table, you will very likely have an auto-incrementing ID in there. To find the value of the most recent insert performed by your script, you can use $wpdb->insert_id.

$sql = $wpdb->prepare( "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value ) VALUES ( %d, %s, %d )", 3342, 'post_views', 2290 )
   $wpdb->query($sql);

   $meta_id = $wpdb->insert_id;

num_rows()

If you’ve performed a query in your script, then this variable will return the number of results of your last query. This is great for post counts, comment counts and so on.

Table Names

All the core table names are stored in variables whose names are exactly the same as their core table equivalent. The name of your posts table (probably wp_posts) would be stored in the $posts variable, so you could output it by using $wpdb->posts.

We use this because we are allowed to choose a prefix for our WordPress tables. While most people use the default wp, some users want or need a custom one. For the sake of flexibility, this prefix is not hardcoded, so if you are writing a plug-in and use wp_postmeta in a query instead of $wpdb->postmeta, your code will not work on some websites.

If you want to get data from a non-core WordPress table, no special variable will be available for it. In this case, you can just write the table’s name as usual.

Error Handling

By calling the show_errors() or hide_errors() methods, you can turn error-reporting on or off (it’s off by default) to get some more info about what’s going on. Either way, you can also use the print_error() method to print the errors for the latest query.

$wpdb->show_errors();
   $wpdb->query("DELETE FROM wp_posts WHERE post_id = 554 ");

   // When run, because show_errors() is set, the error message will tell you that the "post_id" field is an unknown
   // field in this table (since the correct field is ID)

Building Some Basic Tracking With Our New $wpdb Knowledge

If you’re new to all of this, you probably get what I’m going on about but may be finding it hard to implement. So, let’s take the example of a simple WordPress tracking plug-in that I made for a website.

For simplicity’s sake, I won’t describe every detail of the plug-in. I’ll just show the database’s structure and some queries.

Our Table’s Structure

To keep track of ad clicks and impressions, I created a table; let’s call it “tracking.� This table records user actions in real time. Each impression and click is recorded in its own row in the following structure:

  • ID
    The auto-incremented ID.
  • time
    The date and time that the action occurred.
  • deal_id
    The ID of the deal that is connected to the action (i.e. the ad that was clicked or viewed).
  • action
    The type of action (i.e. click or impression).
  • action_url
    The page on which the action was initiated.
  • user_id
    If the user is logged in, their ID.
  • user_ip
    The IP of the user, used to weed out any naughty business.

This table will get pretty big pretty fast, so it is aggregated into daily statistics and flushed periodically. But let’s just work with this one table for now.

Inserting Data Into Our Tables

When a user clicks an ad, it is detected, and the information that we need is sent to our script in the form of a $_POST array, with the following data:

Array
(
   [deal_id] => 643
   [action] => click
   [action_url] => http://thisiswhereitwasclicked.com/about/
   [user_id] => 223
   [user_ip] = 123.234.223.12
)

We can then insert this data into the database using our helper method, like so:

$wpdb->insert('tracking', array("deal_id" => 643, "action" => "click", "action_url" => "http://thisiswhereitwasclicked.com/about/",
"user_id" => 223, "user_ip" => "123.234.223.12"), array("%d", %s", "%s", "%d", "%s"));

At the risk of going on a tangent, I’ll address some questions you might have about this particular example. You may be thinking, what about data validation? The click could have come from a website administrator, or a user could have clicked twice by mistake, or a bunch of other things might have happened.

We decided that because we don’t need real-time stats (daily stats is enough), there is no point to check the data at every insert. Data is aggregated into a new table every day around midnight, a low traffic time. Before aggregating the data, we take care to clean it up, taking out duplicates and so on. The data is, of course, escaped before being inserted into the table, because we are using a helper function; so, we are safe there.

Just deleting in bulk all at once the ones that are made by administrators is easier than checking at every insert. This takes a considerable amount of processing off our server’s shoulders.

Deleting Actions From a Blacklisted IP

If we find that the IP address 168.211.23.43 is being naughty-naughty, we could blacklist it. In this case, when we aggregate the daily data, we would need to delete all of the entries by this IP.

$sql = $wpdb->prepare("DELETE FROM tracking WHERE user_ip = %s ", '168.211.23.43');
   $wpdb->query($sql);

You have probably noticed that I am still escaping the data, even though the IP was received from a secure source. I would suggest escaping your data no matter what. First of all, proper hackers are good at what they do, because they are excellent programmers and can outsmart you in ways that you wouldn’t think of. Also, I personally have done more to hurt my own websites than hackers have, so I do these things as a safety precaution against myself as well.

Updating Totals

We store our ads as custom post types; and to make statistical reporting easier, we store the total amount of clicks that an ad receives separately as well. We could just add up all of the clicks in our tracking database for the given deal as well, so let’s look at that first.

$total = $wpdb->get_var("SELECT COUNT(ID) WHERE deal_id = 125 ");

Because getting a single variable is easier than always burdening ourselves with a more complex query, whenever we aggregate our data, we would store the current total separately. Our ads are stored as posts with a custom post type, so a logical place to store this total is in the postmeta table. Let’s use the total_clicks meta key to store this data.

$wpdb->update( $wpdb->postmeta, array("meta_value" => $total), array("ID" => 125), array("%d"), array("%d") );

   // note that this should be done with update_post_meta(), I just did it the way I did for example's sake

Final Thoughts And Tips

I hope you have gained a better understanding of the WordPress $wpdb class and that you will be able to use it to make your projects better. To wrap up, here are some final tips and tricks for using this class effectively.

  • I urge you to be cautious: with great power comes great responsibility. Make sure to escape your data and to validate it, because improper use of this class is probably a leading cause of hacked websites!
  • Ask only for the data that you need. If you will only be displaying an article’s title, there is no need to retrieve all of the data from each row. In this case, just ask for the title and the ID: SELECT title, ID FROM wp_posts ORDER BY post_date DESC LIMIT 0,5.
  • While you can use the query() method for any query, using the helper methods (insert, update, get_row, etc.) is better if possible. They are more modular and safer, because they escape your data automatically.
  • Take care when deleting records from a WordPress (or any other) database. When WordPress deletes a comment, a bunch of other actions also take place: the comment count in the wp_posts table needs to be reduced by one, all of the data in the comment_meta table needs to be deleted as well, and so on. Make sure to clean up properly after yourself, especially when deleting things.
  • Look at all of the class variables and other bits of information in the official documentation. These will help you use the class to its full potential. I also recommend looking at the ezSQL class for general use in your non-WordPress projects; I use it almost exclusively for everything I do.

Further Reading

(al)


© Daniel Pataki for Smashing Magazine, 2011.


Better Image Management With WordPress

Advertisement in Better Image Management With WordPress
 in Better Image Management With WordPress  in Better Image Management With WordPress  in Better Image Management With WordPress

With the advent of sophisticated and user-friendly content management systems like WordPress, textual content has become increasingly easier to manage. The architecture of these systems aims to deliver a well-formed code foundation; this means that if you are a good writer, then your content will be just as awesome as the structure and quality of the code that runs it.

Gallery-room in Better Image Management With WordPress

However, media handling is, by nature, not the greatest. In many cases, images are used merely to make the website look good, not to supplement the content. Little care is usually taken to make these elements as useful as their textual counterparts. They are often tacked on as an afterthought; the owner thinks, “If all of my posts have an image, surely I should find something quickly for this next one as well.�

Because the content of images cannot be parsed by search engines, making sure they are rich in meta information before publishing them is important. Here are a few ways to enrich your blog using some common sense, best practices and the power of WordPress.

Understanding And Using Images

To get the most out of your graphic content, you’ll need to be familiar with how they work in HTML. To put an image on a page, you would add an image tag, with the appropriate attributes, like so:

<img title="A duck" src="http://myimages.com/theimage.jpg" alt="A mallard duck landing in the water" >

As you can see, the tag has three attributes that contain information about the image:

  • src is the URL source of the image file;
  • alt, or alternative, text is shown when an image can’t load (whether because of a loading error, text-only browser, etc.);
  • title is the title attribute, where you can add a short description of the image, which will pop up after hovering over the image for a second.

The src and alt attributes are both required; the HTML is invalid without them. However, HTML is not a strict language. Your post will still render just fine if you leave out the alt text, which is one of the negative aspect of loose languages: it doesn’t force best practices.

Why Use Alt and Title Attributes?

The most useful aspect of alt and title is that they allow you to add text-based information to an element on your website that would otherwise be invisible to search engines. If you sell umbrellas, Google won’t see that one particular image on your page is of the coolest umbrella it’s ever seen. You’ll have to add that information yourself.

Also, alt attribute can be a huge help to the disabled, because this is how they know what is in an image. So, use the title attribute to write something snappy about the image, and use the alt attribute to describe it. Sticking with our umbrella example, the incorrect way to do this would be:

<img title="Awesome umbrella" src="awesomeumbrella.jpg" alt="The most awesome umbrella ever" >

And the correct way would be:

<img title="Awesome umbrella" src="awesomeubrella.jpg" alt="A matte black cane umbrella with a spruce handle and a chrome tip" >

Remember, the alt attribute is descriptive not only for the visually impaired, but for Google as well. Your website might even rank better if it’s image-heavy.

While not as critical, it is probably worth optimizing the file name as well. The name o290rjf.jpg won’t get in the way showing the image, but super-sleek-umbrella.jpg is a parsable bit of text, and there is a chance that some search engines would take it into account. Also, if someone downloads the image from your website, they will be able to find it more easily in their “Downloads� folder. And user satisfaction translates into more visits.

Adding Images Properly With WordPress

WordPress allows you to attach media to posts very easily through the “Add media� modal window, which you can access by clicking one of the icons over the editing toolbar in a post. You can select multiple images and upload them to the post with a click. Because this is so easy, adding the meta attributes is often overlooked and regarded as a hassle.

When uploading images, make sure to fill out the form which is displayed. Add the title and alt attribute at a bare minimum, but also consider filling in the caption and description fields. If you want a short, nicely formatted caption to appear under the image (which is a good idea), type one in. We’ll look later at harnessing the description field, so writing a paragraph or so about the image might be a good idea.

Once done, all you need to do is insert the image, and the correct HTML tag will be plopped in by WordPress automatically. By taking an extra minute, you will have added a sizable bit of text to your image, making it SEO-friendly and in turn making your website that much more informative. If this is all you have time for, then you have done the most important step. But let’s look at some more advanced image-handling techniques.

Managing Image Sizes

If you display an image at a size of 450×300 pixels, then having an image file of roughly the same size is a good idea. If the source file is 2250×1500 pixels, the image will show up just fine, but instead of loading a 50 KB image, you would be loading a 500 KB image, while achieving the same effect.

WordPress is super-smart, though, taking care of this for you by churning out different sizes for each image you upload. See the dimensions it creates by going to the media settings in the back end. You can modify these once you have the final layout, which I would advise.

For an image-centric website, you might want to add a couple of more sizes, to make sure you never serve an image that is bigger than needed. By putting the following code in your theme’s functions.php file, you create two extra sizes:

add_image_size( 'large_thumb', 75, 75, true );
add_image_size( 'wider_image', 200, 150 );

The first line defines an image that is cropped to exactly 75×75 pixels, and the second line defines an image whose maximum dimension is 200×150, while maintaining the aspect ratio. Note the name given in the first argument of the function, because you will be referring to it when retrieving the images, which you can do like so:

wp_get_attachment_image_src( 325, 'wider_image');

The first argument is the ID of the attachment that we want to show. The second argument is the size of the image.

Rebuilding Your Thumbnails

If you have been blogging for a while now, you probably have a ton of images. Adding an image size now will not create new thumbnails of your existing images. If you specify an image size—for example, our wider_image format—WordPress will fetch a resolution that is close to it, but it won’t create a thumbnail especially for this size.

Using a plug-in, however, you can go back and regenerate the thumbnails to make sure that all of the images are optimized, thus minimizing server load. I can personally vouch for AJAX Thumbnail Rebuild, which goes through all of your images and regenerates the selected sizes for you.

Using Featured Images

A featured image can capture the message of a post. Featured images have many uses: for adding flare in a magazine-style layout, underlining a point made in an article, or substituting for an article’s title (in the sidebar, for example).

Featured images have been built into WordPress since version 2.9, so you don’t need any special plug-ins. If you are using the new default WordPress theme, TwentyTen, or the cutting-edge TwentyEleven (which is right now only in development versions), then featured images are already enabled. Otherwise, you might need to switch them on manually. To enable them, just open your theme’s functions.php file, paste in the code below, and voila!

add_theme_support( 'post-thumbnails' );
set_post_thumbnail_size( 115, 115 )

The first line of code tells WordPress to enable featured images, while the second sets the default size for featured thumbnails. The set_post_thumbnail_size() bit works just like the add_image_size() function we looked at above. You can give it a width, a height and, optionally, a third boolean parameter (true or false) to indicate whether it should be an exact crop.

Once that’s done, go into the back end and edit a post. You should see a featured image widget in the right sidebar; click it to add an image. Or navigate to the media section of the post, view an image’s details, and click the “Use as featured image� link.

The only thing left to do is make these featured images show up! You will need to edit the code for the loop in your theme’s files, which is usually found in index.php or in some cases in loop.php. Look for something like this:

<?php while ( have_posts() ) : the_post(); ?>
The code to display a post is inside here, it can be quite long
<?php endwhile; ?>

Wherever you want to show the images, add the following in the loop:

<?php the_post_thumbnail(); ?>

In some cases, you may want to show the featured image at a size different than the default. If so, you can pass the desired size as an argument, like so:

<?php the_post_thumbnail("wider_image"); ?>

You can name a size that you have previously created using add_image_size(), as I have done above, or you can use an array to specify a size on the fly: array(225, 166).

Creating Galleries

The easiest way to show multiple images in a post is to upload the images to the post and then use the gallery shortcode to display them all.

Gallery-settings in Better Image Management With WordPress

Simply open the “Upload/insert� media screen, click on “Galleries,� and scroll down to the gallery settings. Make sure the links point to the attachment pages (more on this later), and then insert the gallery. Now, thumbnails of all the images you have uploaded to that post will be displayed, each linked to its attachment page.

Including and Excluding Images

You can easily include images from other posts or exclude certain images from the current post by modifying the gallery shortcode. If you switch the editor to the HTML view, you should see [ gallery ] where the gallery would show up. You can add options to it using the following format: [ gallery option_1="value" option_2="value" ].

To include a specific image, you will need to know its attachment ID. You can find that by going to the “Media� section of the WordPress admin area, finding the image you need, hovering over it, and reading the target from the URL or status bar. It should be something like http://webtastique.net/wp-admin/media.php?attachment_id=92&action=edit. The number after attachment_id is what you need.

You can include multiple items like so: [ gallery include="23,39,45" ]. And exclude items the same way: [ gallery exclude="87,11"].

Excluding the Featured Image

Sometimes you will want to use all of the images attached to a post except the featured one. You could find the ID of the image and enter it in the exclude options of the gallery shortcode every time, but that would be a hassle (especially if you change the featured image later). Let’s automate this.

Regrettably, the only way to do this is by replacing a core function in WordPress with our own, using the remove_shortcode() and add_shortcode() functions. The large chunk of code below may be off-putting, but implementing it is as easy as copying, pasting and adding two lines of code. The reason we need to add all this is that we can’t just go around editing a WordPress core file; we need to replace core functions with built-in functions.

First, open your theme’s functions.php file (if it doesn’t exist, simply create it), and add the following code to it:

// remove the  WordPress function
remove_shortcode('gallery', 'gallery_shortcode');
// add our own replacement function
add_shortcode('gallery', 'myown_gallery_shortcode');

This removes the gallery_shortcode() function that WordPress uses to display galleries and replaces it with our own function, called myown_gallery_shortcode().

The code below is almost exactly the same as the default, but we are adding a line to exclude our featured image. Paste the code below into the functions.php file, and then read the explanation further down:

function myown_gallery_shortcode($attr) {
	global $post, $wp_locale;

	static $instance = 0;
	$instance++;

	// Allow plugins/themes to override the default gallery template.
	$output = apply_filters('post_gallery', '', $attr);
	if ( $output != '' )
		return $output;

	// We’re trusting author input, so let’s at least make sure it looks like a valid orderby statement
	if ( isset( $attr['orderby'] ) ) {
		$attr['orderby'] = sanitize_sql_orderby( $attr['orderby'] );
		if ( !$attr['orderby'] )
			unset( $attr['orderby'] );
	}
	extract(shortcode_atts(array(
		'order'      => 'ASC',
		'orderby'    => 'menu_order ID',
		'id'         => $post->ID,
		'itemtag'    => 'dl',
		'icontag'    => 'dt',
		'captiontag' => 'dd',
		'columns'    => 3,
		'size'       => 'thumbnail',
		'include'    => '',
		'exclude'    => $default_exclude
	), $attr));

	$default_exclude = get_post_thumbnail_id($post->ID);
	$exclude .= ",".$default_exclude; 

	$id = intval($id);
	if ( 'RAND' == $order )
		$orderby = 'none';

	if ( !empty($include) ) {
		$include = preg_replace( '/[^0-9,]+/', '', $include );
		$_attachments = get_posts( array('include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );

		$attachments = array();
		foreach ( $_attachments as $key => $val ) {
			$attachments[$val->ID] = $_attachments[$key];
		}
	} elseif ( !empty($exclude) ) {
		$exclude = preg_replace( '/[^0-9,]+/', '', $exclude );
		$attachments = get_children( array('post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
	} else {
		$attachments = get_children( array('post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
	}

	if ( empty($attachments) )
		return '';

	if ( is_feed() ) {
		$output = "\n";
		foreach ( $attachments as $att_id => $attachment )
			$output .= wp_get_attachment_link($att_id, $size, true) . "\n";
		return $output;
	}

	$itemtag = tag_escape($itemtag);
	$captiontag = tag_escape($captiontag);
	$columns = intval($columns);
	$itemwidth = $columns > 0 ? floor(100/$columns) : 100;
	$float = is_rtl() ? 'right' : 'left';

	$selector = "gallery-{$instance}";

	$output = apply_filters('gallery_style', "
		
		


\n";

	return $output;
}

In lines 18 through 29, WordPress is determining the default attributes. By default, nothing is excluded; so under this bit of code, we add two more lines, and that’s it:

$default_exclude = get_post_thumbnail_id($post->ID);
$exclude .= ",".$default_exclude;

The first line here finds the featured image of the post in question, while the second appends it to the exclude list. The rest of the code is the same as the default.

Using Attachment Pages

Colorblocks in Better Image Management With WordPress

In my opinion, attachment pages are the single best tool for creating richer, more informative image-driven websites. They enable you to create separate pages for each and every media item you have, affording you considerably more power in managing them.

Attachment pages exist in WordPress by default, but people seem to rarely link to them. Linking thumbnails directly to their full-sized versions (i.e. without the website framework) is much more common. I am not a huge fan of this because it throws the user into a completely new environment without prior warning. Attachment pages allow you to show the user a wealth of information about the image; and for those who need a bigger version, you can display download links for different sizes.

Enabling Attachment Pages

As stated, you don’t need to do anything to enable attachment pages. Just make sure to link your images to them instead of to the original files. For galleries, link to the attachment page using the radio buttons before inserting them. When inserting a single image, point the link’s URL field to the “Post URL� by clicking the relevant button below it.

Styling Attachment Pages

If your theme doesn’t have an attachment.php file, then single.php will handle the display of attachment pages by default. If you have a decent theme, chances are this will work fine without your needing to touch any code. When clicking on an image, you should arrive on a page that shows the title and description of the image and the image itself.

To add additional information to this page, you will need an attachment.php file. I suggest duplicating single.php and going from there, because in most cases it will have most of what you need.

Adding Image Data

To make the attachment pages more informative, add a bunch of meta data to your images. To help with this, I have created a plug-in especially for Smashing Magazine readers, which you can download from the WordPress Plugins page, or just search for “media custom fields� in WordPress’ back end where you “Add new� plug-ins.

This plug-in lets you create your own custom fields, like the photographer’s name, coordinates, color palette, etc. What you add is up to you. You can easily manage all of the information on the plug-in’s admin page.

In the video below, I’ll walk you through how I did this on my own blog. You’ll learn about basic usage and see an example.


“Better Media Management With WordPress Using the Media Custom Fields Plugin,� by Daniel Pataki.

Creative Attachment Page Uses

Download Links for Image Sizes

Using the add_image_size() function mentioned above, you could create five or six image sizes and show Flickr-style download options that allow users to choose the dimensions of their preference. This is helpful when showcasing desktop backgrounds and large photographs. So, let’s do that:

// If we are on an attachment page, the $post object will be available and the $post->ID variable will contain the ID of the image in question.

// Find the meta data field from the postmeta table, which contains the sizes for a given image. This is the '_wp_attachment_metadata' field, which contains a serialized array. Take care, because if you use 'true' as the third parameter, the function will unserialize the string for you, so that you don’t need to do it.
$image_meta = get_post_meta( $post->ID, '_wp_attachment_metadata', true);

// Put all the image sizes and file names into an array for ease of use
$image_sizes = $image_meta['sizes'];
$image_sizes['original']['width']  =  $image_meta['width'];
$image_sizes['original']['height'] =  $image_meta['width'];
$image_sizes['original']['file']      =  $image_meta['file'];

// Display a list of links for these images
echo '
<h3>This image is available in the following formats</h3>

';
echo '
    '; foreach ( $image_sizes as $size_name => $size ) { $url = wp_get_attachment_image_src( $post->ID, $size_name ); $anchortext = $size['width'] . 'x' . $size['height']; echo "".$anchortext.""; } echo '
';

Adding Color Palettes

By adding some creativity to the mix, you can come up with some nifty features. The screencast above and the code below shows you how to display color blocks of the dominant colors in each of your photos.

Screen-shot-2011-02-11-at-1 21 12-PM in Better Image Management With WordPress

To accomplish this, you will first need to create a custom field using the Media Custom Fields plug-in and name it something like “Color Palette.� Remember to look at the field name that the system generates; it is displayed in parentheses next to the title you chose. It should be something like tqmcf_color-palette.

Once that’s done, edit the image you’d like, and add the following in the custom field: color_1,color_2,color_3, where colors_x should be hex values. In my case, I entered the following string: f0e9bf,e4dc99,000000.

Open up the attachment.php file in a code editor. Wherever you want to display the colors, you’ll need to add something like this:

// Retrieve the field value from the database
$color_palette = get_post_meta( $post->ID, 'tqmfc_color-palette', true );

// Turn the string into an array of values, where each value is one of the colors
$colors = explode( ',', $color_palette );

echo '
<h2>Logo Colors</h2>
';

// Loop through all the colors and create the color blocks, which will actually be links pointing the the color's page on Colourlovers.com
foreach ($colors as $color) {
    $link = 'http://www.colourlovers.com/color/'.$color.'/';
    echo '';
}

You will also need to style the link element so that it shows up. Because anchors are inline elements by default, if they have no content, they won’t show up. Here’s the CSS I used, but you’ll need to change it to match your website:

.color-block {
    display: block;
    float: left;
    height: 20px;
    margin-right: 3px;
    width: 30px;
}

Conclusion

As you can see, even with minimal effort, you can create a much more robust system for storing and showing images. And with some copying and pasting, you can take it one step further.

The first and most important step is to add meta data like alt text to images, give them meaningful file names and so on. By doing so, you lay a foundation for any media management system. You can easily add other meta data to your files by using the Media Custom Fields plug-in for WordPress.

With this foundation in place and a few simple code tweaks, you can show images based on any of the custom fields you wish, displaying relevant and interesting information about them. Creating download buttons for multiple sizes and creating multiple color palettes are only the tip of the iceberg. The techniques showcased here can be used for so much more!

(al)


© Daniel Pataki for Smashing Magazine, 2011. | Permalink | Post a comment | Smashing Shop | Smashing Network | About Us
Post tags: ,


  •   
  • Copyright © 1996-2010 BlogmyQuery - BMQ. All rights reserved.
    iDream theme by Templates Next | Powered by WordPress