Throughout this series, we've been taking a look at how WordPress can be used for building web applications.
Up to this point, we've established that WordPress is a foundation - rather than a framework - and we've talked a bit about how we need to avoid trying to shoehorn WordPress into another type of design pattern than that of its native type.
To that end, we've established that WordPress uses an event-driven design pattern, and that this is represented best with its system of actions and filters.
Although the overall purpose of this series is to provide a survey of how WordPress can be used for web application development, I think it's important to take a look at a few practical examples of how powerful the hook system really is in order to understand just how much we - as developers - can customize WordPress to fit our needs.
So in this article, we're going to take a look at some code that represents some common actions that can be achieved using WordPress hooks, as well as some slightly non-standard functionality.
Ultimately, by the end the article, you should have a clear understanding of why leveraging the event-driven nature of WordPress is key in building applications, and why we shouldn't try to make WordPress and its underlying patterns into something that they're not.
Hooks: Actions and Filters
In the previous article, we gave two definitions - one specifically for actions and one specifically for hooks:
Actions are events in the WordPress page lifecycle when certain things have occurred – certain resources are loaded, certain facilities are available, and, depending on how early the action has occurred, some things have yet to load.
Filters are functions that WordPress passes data through during certain points of the page lifecycle. They are primarily responsible for intercepting, managing, and returning data before rendering it to the browser or saving data from the browser to the database.
This is key in understanding the two types of WordPress events because there are going to be times where you want to pre-empt a process, follow-up a process, or manipulate information prior to rendering it to the screen.
Knowing the difference in actions and filters is key in building applications, plugins, and themes in WordPress.
To that end, we're going to pause the discussion on why WordPress can be used for web applications, and take a practical look at several actions and filters to make sure that we all understand how the event system works, the types of things that we can do with it, and hopefully get creativity flowing as to how these can be used for creating a more customized experience.
Common Actions
First, we'll take a look at several actions each of which increases in complexity from the one prior in order to help demonstrate how powerful actions can become.
1. Adding a JavaScript File to the Header
This action is so common that it's likely rote among even the most intermediate of developers. Still, the point remains: This is an example of a classical WordPress action that's used in nearly every type of theme that's out there.
In short, it takes advantage of the wp_enqueue_scripts
hook. This fires during the page loading sequence and allows you to tell WordPress what source files it should include as well as where it should include it (as in, in the header or the footer).
function example_add_theme_scripts() { wp_enqueue_script( 're-example-script', get_stylesheet_directory_uri() . '/js/example.js', array( 'jquery' ), '1.0.0', FALSE ); } add_action( 'wp_enqueue_scripts', 're_add_theme_scripts' );
This is easy enough to understand, right?
Grab the script in the theme's example.js file from the JavaScript directory, make sure that it's marked as being dependent on jQuery being loaded first, note that it's version 1.0.0 of the script, and we do not want to load it in the footer.
2. Customize the Read More Link
Out-of-the-box, WordPress provides the ability to add a 'Read More...' or a 'Continue Reading...' link which is achieve by using the <!--more-->
tag in the post editor.
You can style it using native styles, but let's say that you want to add additional code that will make it fit in more nicely with your theme, be easier to integrate with a responsive design, or something similar.
You can then use the following action:
function example_add_more_link_class( $link, $text ) { $html = '<div class="more-link-wrapper">'; $html .= '<div class="more-link">' . $link . '</div>'; $html .= '</div>'; return $html; } add_action( 'the_content_more_link', 'example_add_more_link_class', 10, 2 );
Notice that we're hooking into the_content_more_link
which accepts the anchor and the text of the anchor for the more link.
Within the function, we then wrap the actual link within its own div
container so that we can have greater control over styling the link.
3. Retrieve a Person's Name via Ajax
This particular example assumes that you're using Ajax in your project and that you've already set up the proper facilities to make sure you can make asynchronous requests.
This also assumes that the data that's being sent from the client-side to the server-side is the ID of a user for whom you want to return his or her name.
function example_get_user_name() { $user = null; if ( isset( $_GET['user_id'] ) && 0 < strlen( trim( $_GET['user_id'] ) ) ) { $user = get_user_by( 'id', $_GET['user_id'] ); if ( FALSE == $user ) { echo $user->first_name; } else { echo '-1'; } } // end if die; } // end re_get_employee_by_name add_action( 'wp_ajax_example_get_user_name', 'example_get_user_name' ); add_action( 'wp_ajax_nopriv_example_get_user_name', 'example_get_user_name' );
So in the above example, we first check to make sure the user_id
is set in the $_GET
collection, and, if so, then it will attempt to retrieve the user from that ID.
If the user exists, then it will echo the first name of the user back to the client; otherwise, it will echo a '-1
'. This then gives us the flexibility to respond appropriately on the client-side.
Common Filters
Just as we did with the aforementioned actions, we'll take a look at several filters each of which will slightly increase in complexity so that we're able to see some of the things that we're able to do with filters that grant us greater flexibility within our WordPress projects.
1. Appending Content to a Single Post
Though the title of this particular action should be clear enough, let's say that you want to add a sentence to the bottom of each post on your blog, but you only want to do it on single posts.
This can be achieved with the following code:
function example_append_post_content( $content ) { if ( is_single() ) { $html = '<div class="post-suffix">'; $html .= 'This content will appear at the end of a post.'; $html .= '</div>'; $content .= $html; } return $content; } add_filter( 'the_content', 'example_append_post_content' );
This is easy enough to understand, right?
the_content
filter passes the actual content of the post to the hooked function. From there, we're free to manipulate the data in any way that we see fit.
In our case, we first check to see if it's a single page. If so, then we'll add a post-suffix
container with a single sentence, append it to the content, then return it.
If it's not a single post, then the content will be returned as normal.
2. Redirect Users After Logging In
Another type of filter that you may want to take advantage of is redirecting users after they've logged into the application.
For example, perhaps if they are an administrator, they should be directed to the post dashboard; otherwise, they should be redirected to the home page of the site.
To achieve this, we can take advantage of the login_redirect filter:
function example_login_redirect( $redirect_to, $request, $user ) { return ( isset( $user->roles ) && is_array( $user->roles ) && in_array( 'administrator', $user->roles ) ) ? home_url( '/wp-admin/' ) : home_url(); } // end soi_login_redirect add_filter( 'login_redirect', 'example_login_redirect', 10, 3 );
In the code above, we've provided a custom filter into the login_redirect
hook that performs the following:
- If the user is an administrator, redirect them to the dashboard
- Otherwise, direct them to the
home_url
of the site.
Easy enough.
Although it is a relatively simple example, it should get you thinking about more of the advanced things you can do based on the user's roles and/or capabilities.
For example, rather than just redirecting them to certain aspects of the application, you'd be able to show them various pieces of information based on, say, their roles.
3. Customizing Emails
This particular example is a little more complicated because the add_filter
calls come within the context of another function that has a third-party caller.
Specifically, we're going to be sending an email but we want to make sure that we've customized the content type, the from content, and the from name prior to sending the content.
To do this, we first need to define a function:
function example_exmail_user( $input ) { // Code removed from brevity. // Assume $message is defined as the content of the email add_filter( 'wp_mail_content_type', create_function( '', 'return "text/html";' ) ); add_filter( 'wp_mail_from', 'example_mail_from' ); add_filter( 'wp_mail_from_name', 'example_mail_from_name' ); if ( wp_mail( $input['email-address'], 'Your Account Has Been Created!', $message ) ) { // Redirect back home wp_redirect( home_url() ); } else { // Specify a page to which to direct upon an error } exit; } function example_mail_from( $email ) { return '[email protected]'; } function example_mail_from_name( $name ) { return 'Example Web App'; }
After that, we need to define functions that are hooked into the filter that are specified above. Namely...
wp_mail_content_type
wp_mail_from
wp_mail_from_name
As you can see, filters can get complicated relatively quickly, but they are powerful and if you understand what you're doing, and how all of the pieces fit together, so to speak, then you can really do some amazing stuff.
Just Scratching the Surface
As with most tutorials and examples on this site, we're just scratching the surface of what can be done using the WordPress hook system.
Of course, these examples are meant to be just that - examples for how powerful actions and filters can be when it comes to customizing the WordPress experience.
Although this particular article and the example code are meant to serve as a practical example of some of the things that you can do, they aren't meant to be the definitive guide to working with hooks.
Instead, they are meant to show how we can begin taking advantage of what's available in the WordPress API when building a web application.
Up Next...
In the next article, we're going to begin looking at several facilities provided by WordPress right out of the box. We'll see how they are useful in building web applications, how to leverage them for our specific work, and how they can be useful in building web applications.
After that, we'll take a look at how many of these features work well within the context of a web application, and how we can use hooks to further customize the behavior that they provide.
Comments