WordPress: Refresh permalink structure with flush_rewrite_rules()

This is a quick one, but file it away in your brain and some day you’ll thank me. Have you noticed that when you create a new custom post type that you’ve gotta hit the admin settings and re-save your permalink structure? You don’t have to change anything, just saving it again will do the trick, but it’s an annoying little step.

If you’re creating post types programmatically (inside your plugin, whatever), you might need a way to automatically flush your rewrite rules. Enter the simple function flush_rewrite_rules().

flush_rewrite_rules( $hard );

The function only accepts one parameter, a boolean true/false for $hard, which will decide whether to actually update the rules in the .htaccess file or just soft flush the rewrite_rules transient. The default is true, meaning you’ll get a full flush.

Even if you’re not working with post types, you’ll sometimes run into scenarios when you need to flush. I’ve got a project going right now where I’ve dropped the author prefix in the URL, giving each user a top level page (domain.com/user). I noticed that these rules weren’t being created upon registration and a simple flush_rewrite_rules() in my registration hook fixed things up.

It’s worth noting that this is an “expensive” process, meaning you shouldn’t just run it all willy nilly. Only call this when you absolutely need it. If you’re not sure if you need it, you probably don’t. But six months from now when you can’t figure out why some users are hitting 404s, come back for a high five.

Advice for the new WordPress developer

Best practices are called that because they’ve first been repeated again and again. In my many years of WordPress work, I’ve picked up a couple best practices that I wish I would’ve found sooner.

None of the following advice is ground breaking, it’s just all stuff that is constantly on a developer’s plate while working on a project. Maybe stuff that hasn’t always been there- stuff that exists outside the normal tutorial and how-to. I’ve written this rambling guide to hopefully help some new developers pick up some skills that might otherwise fall through the cracks.

Use a text editor, source control, etc

This might seem like a pretty simple one, so I won’t spend much time on it, but I thought it might be worth mentioning that a smart developer always uses a proper text editor or IDE, and a developer that doesn’t like to repeat work should be using some sort of source control, be it Git, SVN, or even a simple check in/out.

When you edit inside /wp-admin (or even when freestylin’ in a text editor), it’s really possible that you do something wrong. I do it all the time. When I do, I find great comfort in reverting changes to my last known happy place. Save some stress and hair, keep your code backed up.

Don’t make child themes

This is probably a point that might start some arguments, but I say bring it on. This may sound weird, but best practices for a professional might not be the best for beginners. The way you learn to do things is often not exactly the way you end up implementing things in the final version, but that journey is invaluable, especially for a new developer.

While a lot of developers and consultants will swear by child themes, I’d bet money that most of them didn’t start with child themes. I can admit that once you’re comfortable with PHP and theme structure, child themes are a fine preference, but I think when learning you should stick to tinkering right inside someone else’s code. Why?

Because someone smarter than you has already written a ton of great code. Go ahead and jump right into those template files and get dirty. If you’d like to build on their code with a child theme, you’ll at minimum need to know how to use PHP hooks, filters, and actions. Need another reason?

Automattic doesn’t use child themes on WordPress.com. They’ve built their own starter theme, _s (aka “Underscores”), and it’s meant for hacking, not birthing children themes. Each time they begin a new theme, they directly edit this starter, not hook into it. They even call the theme The 1,000 Hour Head Start. And those are hours from folks soooo much smarter than me.

If _s doesn’t suit your fancy, give Bones a try. Bones comes in multiple flavors: responsive, classic, and Genesis. All are filled with robust documentation and meant for direct editing, a great way to learn how things work. When you’re done, simply wash, rinse, and repeat.

Looking at code written by someone else is the main way I learn. Be it themes, plugins, or tutorials on blogs (like this one!). Once you’ve mastered that, feel free to make a child theme. Hook and filter until you’re blue in the face, just don’t do it before you know the guts like the back of your hand.

Don’t stop at the post and page

When I started with WordPress I spent a lot of time wrestling posts into new things. Portfolio items, events, movies, people. I’d add tags and categories and I’d query and I’d filter and things would eventually look like an interstate overpass exchange.

Custom post types and custom meta data are the secret sauce in all my WordPress work. I’m no longer shackled to the post or page, I can have movies and recipes. I’m no longer stuck adding markup to my post body, I can enter each specific bit of information into its own box.

I won’t explain the whole shebang now, I’ll just say to go get comfortable with custom post types and with custom meta data. I believe in meta data so much I wrote a 45 page ebook about it.

Extending WordPress beyond the post and post body is the main thing people are talking about when they mention doing things like a CMS. It used to be a hassle, now it just takes a few minutes at the top of your project. Do it.

Making a plugin is way easier than you’d think

Speaking of custom functionality, let’s talk about plugins. When I started making custom WordPress sites, I was pretty happy just dipping my toe into the WordPress themes folder. From there it was possible to change the styling, make custom templates, even add custom functionality like fields and post types.

But changing themes was a pain. For years I dealt with it, because I figured writing a plugin was complex. WRONG. Writing a custom plugin is about as difficult as making a custom page template. You include a tiny bit of custom markup near the top of a file (which you can even copy and paste), and WordPress does the rest.

In fact, here is the custom heading you’ll need to create a plugin. Simply create a file called something like my-plugin.php, start it with the following, then drop in your functions, shortcodes, includes, etc.

<?php 
/* 
Plugin Name: Name Here
Description: Description Here
Version: 0.1 
Author: ClarkLaB 
Author URI: http://clarklab.com 
*/ 

// do something here! make some cool_functions();

Once you're comfortable with making plugins, you can easily hop from theme to theme without losing things like custom post types, meta boxes, and more. And if you need to go the extra mile, perhaps at the fault of a clumsy client, you can load plugins in /mu-plugins/ to make their include mandatory. No way to disable them, nice and dummy-proof.

Bill Erickson uses such a method with his Core Functionality Plugin, which he's of course shared for you here. Following our theme of using code from folks smarter than us, let's follow his lead and make sure to put our must have functionality tucked away somewhere safe.

Get involved in your local WordPress scene

At the risk of revealing my true colors here, I love to get together with folks and talk about nerdy shit. I go to electronics conferences, I speak at WordPress meetups, and I meet a lot of great people while doing so.

Unless you work in a full-time environment surrounded by WP gurus, you deserve a sounding board for your developing skills. Simply finding some like-minded folks to bounce around ideas and best practices and favorite plugins off of will greatly improve your skillset.

For years while writing PHP code I sat alone (well, in a technical sense), reading blogs and posting in forums. In the past year or so, I've started to get involved in the Austin WordPress Meetup Group and I won't be stopping any time soon. There's a place for everyone. If you're learning, there is plenty to soak up there. If you think you are a pro, reciting your reasoning to a group of others will only help sharpen your resolve.

WordPress is calling this the year of the meetup, which should be reason enough to give it a try. Go to a meetup, go to a WordCamp, find your other nerds.

Learn from your mistakes

Aside from the corny title, this might be the most important bit of info here. When you take the time to learn something, the next time you do it you'll only do it better. And with code, you'll have the exact answer you're looking for.

If you're making themes and writing code, consider signing up for a GitHub account to share Gists or writing or blog or running a Tumblr- just do something that allows you to keep track of your past conquests. I often find myself writing blog posts specifically so I will remember it, sharing with you guys is just a bonus. Not only is reusing and expanding on code a great way to get things done, you can usually do so in a fraction of the time.

It's OK to learn on a client's dime, but know your limits

At Dev Day during WordCamp Austin 2012, an interesting topic came up. Someone asked about learning on the clock, and how to bill for that time. The consensus of the room seemed to be that as long as you've got a reasonable amount of skill and speed on your side, learning on the clock is a fine deal for both the developer AND client. How so?

When you tackle a project and run into a problem that needs solving, always remember that someone else has already found and fixed this specific issue. Not only is being able to find and apply that fix a skill worth paying for, you're only able to do so based on the 1,000's of hours of work you've already poured into your skillset. So your current client is getting a benefit that your past client paid for, and your next client will benefit from the time this client paid for. It's the circccle of lifffe! and any good client should realize he's scoring a deal to have custom solutions achieved specifically for his project.

That's not to say that you should take any project willy nilly and figure it out as you go. It means that a skilled developer can plan out 90% of his or her plan and freestyle the rest during the project. It does not mean that you should take a job with little idea how to complete it.

Ask questions but learn to Google

There are a lot of great WordPress forums and places to get your question answered. You can try the official WordPress support forums, StackExchange, Forrst, or the Austin WordPress Google Group. I'm even a paid member on ThemeHybrid, a community run by Justin Tadlock. The answers there are top notch and the members are super talented.

To be honest, though, you can usually find a solution to your problems with some exhaustive googling. Lots of times I'll be in the middle of the hunt, give up, ask a question, only to find a solution minutes later with some further snooping.

I love starting a good discussion and seeing how other developers do things, but never underestimate the power of teaching yourself to do things. The internet is the best text book ever written, especially where WordPress is concerned. There's more documentation and tutorials than you can shake a stick at. Take advantage of it!

I've even gone on job interviews and said "I'm really good at the internet." I explained that hitting walls and finding solutions are major part of my process, part of the process I'm damn good at. I got the job.

You target is always moving

As you continue to learn, your target will always be moving. A triumph one week will be code you're re-writing the next. This constant improvement and growth is one of the most thrilling things about being a developer and I hope this post helps set up some good habits for those of you looking to learn more.

WordPress front-end post form using wp_insert_post

At WordCamp Austin, I hosted an awesome Q&A session about the underbelly of Android and Me. One of the most requested bits of code was the form action utilizing wp_insert_post().

(I was leading a session on wp_insert_post() at the time, the slides for which you can find here.)

If you’re not aware, we recently launched a featured on Android and Me called Threads. Threads allow users with enough points (oh yeah, our blog runs on a point system, too- take notes!) to create a post directly from the front-end of the site, never seeing /wp-admin. While my production implementation is quite a bit more complex than this, below I’ve shared a stripped down version of the functionality. Join me at the bottom for some extra, dirty details. Continue reading

Change the default avatar in WordPress

If you’ve ever wanted to change the default avatar in WordPress, all you need is a quick filter in functions.php that inserts and names your new avatar. Once you add the markup below, you’ll see your new avatar type listed in wp-admin > Settings > Discussion along with the choices like Identicons and MonsterID. The code:

<?php 
add_filter( 'avatar_defaults', 'newavatar' );  
function newavatar ($avatar_defaults) {  
$myavatar = get_bloginfo('template_directory') . '/images/avatar.png';  
$avatar_defaults[$myavatar] = "Pigs";  
return $avatar_defaults; }

This is a pretty simple one. Our function newavatar() is hooked to the avatar_defaults, and we simply add our new avatar choice, which includes a path to the image URL along with a title (pigs!). At the end, we return the defaults, which has been impregnated with our new custom avatar, and no one is ever the wiser!

WordPress comment hacks: User-only comments, restrict by user age and more

In a recent promo for Android and Me, we created a bunch of giveaways, each with a specific limitation on entry. We had 25 days worth of prizes, and each day held a different challenge. We used comments as the main way to enter, and on certain days we wanted to restrict entry to certain groups of users.

Some days we only wanted users who had added their Twitter account to the profile (a piece of user meta), some days we wanted only members of a certain age to be eligible (a piece of user meta compared to a set value), and overall, we wanted all comments to be from registered users only (private comments on certain WordPress posts).

To accomplish all these things, I came up with the simple hack of creating a slew of conditional checks that surround comment_form(). If you’re not familiar, it’s a function that outputs the comment form itself and is usually found near the bottom of comments.php. It’s a pretty easy way to control who is commenting, taking away the form. Take a peek a the heavily commented code below (no pun intended) and join me after for some play by play.

<?php 
//start by checking for a couple of key pieces of info
$current_user = wp_get_current_user();
$private_comments = get_post_meta($post->ID, 'private_comments', true);
$meta_lock = get_post_meta($post->ID, 'meta_lock', true);
$time_lock = get_post_meta($post->ID, 'time_lock', true);

//if the post has the custom field 'meta_lock'
if ($meta_lock) {
  //check the current user for that meta field
  $user_meta_key =  get_user_meta($current_user->ID, $meta_lock, true);
    if ($current_user->ID AND $user_meta_key) {
      //display the comment form
      comment_form();
      //give an error message (add some flare!)
    } else { echo 'Special users only!'; }

//if the post has the custom field 'time_lock'	
} elseif ($time_lock) {
  //get the age of the user and prepare the age limits
  $user_age=date("Y-m-d", strtotime($current_user->user_registered));
  $age_limit = strtotime($time_lock);
  $account_age = strtotime($user_age);
  
  //if the current user is OLDER than the set limit
  if ($current_user->ID AND $account_age <= $age_limit) {
    //display the comment form
    comment_form();
  //give an error message (add some flare!)
  } else { echo 'Users older than '.$tegra_time.' only!'; }

//if the post has the field 'private_comments'	
} elseif ($private_comments) {
  //check if the user has an ID (aka is signed in)
  if ( $current_user->ID ) {
    //display the comment form
    comment_form();
  //give an error message (add some flare!)
  } else { echo 'Users only!'; }

//no special conditions met, just display the comment form  
} else { comment_form(); }

Jeeeez that's a scary wall of text! Ok, not really, but compared to just the single line comment_form() we started with it looks pretty major. What we're doing is actually pretty simple. Anytime the template would normally call comment_form, we're getting in the way and checking some settings first.

What settings? Things we set on a post per post (or page) basis, using custom fields. If you'd like to turn on user-only comments, set a custom field 'private_comments' with any value (I usually just go with 'true'). If you'd like to restrict comments based on whether or not a user has a certain meta field, on your post set a custom field with the key 'meta_lock' and a value matching whatever user meta you'd like to filter by. This can be a user's real name, website link, bio, etc. It's a great way to push your users to fill out certain fields of their profile.

One of the funnest challenges we did was based on user age, something you'll see in the snippet above as age_lock. To use it, simply set a custom field on your post with a YYYY-MM-DD format (one year before today's date, for example). When comments.php is rendered, it'll compare the date the user registered with the date you've entered in the field 'age_lock'.

These few examples are really just to get the juices flowing, and to introduce you to the simple hack of conditionally displaying the comment form. There are an infinite number of things you could check or compare, so if you explore and find something killer make sure you come back and share it with us.

So far, I think my favorite use of this technique was tracking user tweets with the service Rowfeeder, which I then used to export a full list of Twitter usernames. Since our accounts let users link their Twitter handle, I was able to check which WordPress accounts had successfully Tweeted and then conditionally allow them to comment. Total score!

Sort WordPress users by custom meta value with get_users

I’ll be honest. This one took me a while. I spent a lot of time looking for a solution but there doesn’t seem to be a whole bunch of discussion around user queries in plain ol’ WordPress. I guess most of the big user action has moved on to bbPress and BuddyPress.

For those of us with a sizable user base contained only inside WordPress however, actually doing things with users takes a bit of elbow grease. I’m sure all the same possibilities exist, but people don’t seem to talk or write about them as often, which is where this guide comes in.

Today we’re going to look at getting WordPress to sort users by a custom meta value, something that would be useful if your users have any sort of scores, totals, or custom profile fields.

Over on Android and Me, all users have a point total. We then rank all users by that point total and assign everyone a percentile rank. To call up thousands of users based on a custom meta value seemed daunting, and it was, until I got a bit more familiar with WP_User_Query.

WP_User_Query was introduced in WordPress 3.1 and brings us an easy and flexible way to query our user database. We’ll be using the function get_users, which is basically a wrapper for WP_User_Query. You’ll notice the function includes an ‘orderby’ parameter, but the only options given are:

orderby – Sort by ‘nicename’, ‘email’, ‘url’, ‘registered’, ‘display_name’, or ‘post_count’.

Notice we’re missing ‘meta_key’ or ‘meta_value’, so we’re on our own when it comes to ordering these guys by a custom field. Also of note is ‘post_count’, which I could totally see coming in handy on certain community blogs (MAKE A NOTE!). Now that we know what we’re after and what tools we’ll need to make it happen, it’s time we get started.

The Code

<?php 
//these are the arguments for the get_users function below
$args  = array(
  'fields' => 'all_with_meta',
  'meta_query' => array(
    array(
    'key' => 'points', // the meta field (or key) we want to target
    'value' => '2',    // the value we want to target (optional)
    'compare' => '>='  // comparison method (optional:  =, >, <, etc)
    )
));

//get_users calls WP_User_Query and returns an array of matching users
$users = get_users($args);

//custom function for comparing the data we want to sort by
function cmp($a, $b){
  if ($a->points == $b->points) {
    return 0;
  }
  return ($a->points > $b->points) ? -1 : 1;
}

//usort sorts our $users array with our function cmp()
usort($users, 'cmp');

//leaving an array of $users sorted by the value of meta 'points'
foreach ($users as $user) {  
  // do something rad!
}

I've commented the code above so hopefully you were able to follow along in the actual markup, but if you'd like a short summary: here we go!

I start off with a short list of arguments, or options, that get_users() needs to return the users I want. A full list of parameters can be found on the get_users page in the Codex. The key here is meta_query, which lets me specify the user meta field I'd like to target and compare. I so happen to be calling up users based on their point totals, so I call any user with points above or equal to 2 (any below that I can assume is a scrub and just rank at the bottom of the pile to save some query juice).

Once I've got my $args, I go ahead and run get_users($args). Doing so will return a full list of users that match the arguments, all handily stored in the array $users.

But what's that? They aren't sorted? While we were allowed to compare points while calling the users, no actual sorting took place. This is where we get a bit tricky. Instead of relying on WordPress to sort the users for us, something the Codex says isn't possible right now, we're going to bust out PHP's usort along with a simple custom function for comparing the points.

Our custom function, cmp(), is just a little check that runs that compares the point total of a user with the other point totals in the array. If the totals are the same, the function returns '0'. If they are different, the function returns a '1' or '-1'. That simple math is enough to let usort crunch through thousands of users in seconds, something I'd spent a couple weeks trying to figure out how to make WordPress do for me. Oh well, you know how that goes.

Now that we've got $users in order by the meta field 'points', all that's left is to do something rad. Simply use a foreach (PHP's version of The Loop) to run through the users in the array and accomplish something. In my case, it was doing even a bit more math to calculate each user's percentile in order to show what everyone's point totals really meant in relation to one another.

I know not everyone's blog has a point system, but if you've got any amount of users or even multiple authors this might come in handy. I used WP_User_Query all over the place on the WordUp Austin site. On Android and Me, I list the author pictures in the sidebar. Now, if I wanted to, I could order them by post count or point totals.

Slowly but surely I'm accumulating bits of community-focused solutions like this one and soon I'll be able to say with complete certainty that my WordPress install would slay any bbPress or BuddyPress install you can toss at it.

Intelligent caching of changing data with the WordPress Transients API

Recently I built a shortcode for displaying data from the Android Market. You can see it in action on Android and Me. To make the magic happen, I query the AppAware API for a couple key bits of data, mainly the app icon, title, developer name, etc.

After a while, I realized that even without a rate limit being imposed by AppAware, some of my calls were failing. To lighten the load, I turned to the WordPress Transients API, a super simple way of saving (or caching) data for later use. Because saving a transient stores the data locally, you won’t need to make as many external calls, which is good for you and for your API partners.

What is the Transients API?

If you’re an experienced developer and you’re familiar with the concept of caching, you can probably skip this section. The code samples are below. But if you don’t know a thing about saving data locally, WordPress says: the Transients API offers a simple and standardized way of storing cached data in the database temporarily by giving it a custom name and a timeframe after which it will expire and be deleted. Also of note is that Transients are inherently sped up by caching plugins, where normal options are not.

For this reason, transients should be used to store any data that is expected to expire, or which can expire at any time. Transients should also never be assumed to be in the database, since they may not be stored there at all.

This makes transients the perfect solution to storing data you would otherwise call from a 3rd party. Ideally, when you need the data, you’ll first check to see if the transient exists. If it does, you use that data. If it doesn’t, you call for a fresh version of that data, when you then not only use, but save and timestamp for later use. Sound simple enough? Continue reading

Using PHP to find a discount on a price in WordPress

In today’s version of programming 101, we’re going to learn how to find the discount on a deal price. It’s pretty standard fare, but as someone who isn’t the sharpest mathematician, I figured this might be worth sharing, if for no other reason that I’ll probably need to look it up at some point in the future.

For bonus points, my example will be pulling the prices from a custom field on a WordPress post using get_post_meta. If you’re not running WordPress, you could just include the plain text prices in the script (where I set $deal_price and $old_price).

If you recall math class, to find a percentage you first divide the new price by the old price. Then to find the discount, you subtract from one and multiply by 100, leaving you with the actual percentage discount on the original price (rounding to zero decimal places).

Again, this is a simple one, I just wanted to log it for posterity’s sake.

How to create a vanity URL in WordPress with a simple page redirect

Hey guys, I’ve got a super simple WordPress tip for you today that has come in handy numerous times over the years. In this age of short URLs, there are often times when you’ll need a top-level, “pretty” URL on your main domain that points to a longer, more complex URL.

For example, we are about to start an affiliate campaign with WPEngine, and my affiliate linked looked like this: http://wpengine.com?a_aid=4e6fc813411ff, which isn’t very pretty. I’d much rather link to a nice looking URL such as http://androidandme.com/wpe, which will read better in banners, in videos, and when being said aloud.

To get this done, we’re just going to make a simple custom page template that uses a simple PHP command to tell the browser that the page has moved. Take the following code and save it inside your main template folder as page-redirect.php:

<?php
/*
Template Name: Redirect
*/

$redirect_url = get_post_meta($post->ID, 'redirect_url', true);
if ($redirect_url) {
Header( 'HTTP/1.1 301 Moved Permanently' ); 
Header( 'Location: '.$redirect_url.'' ); 
}
?> 

If you’ve made a custom page template before, that top part probably looks familiar to you. It’s the special bit of markup that lets WordPress know that you’ve defined a new page template, which will make our new template selectable from the ‘Edit Page’ screen in /wp-admin.

After that, we call up a custom field, “redirect_url”, which contains the long and ugly URL we want to point the browser to. Following the retrieval of that value, we use a PHP header function to send the user along to the new page.

Using your new custom template

To actually use this new custom template, there are just a few quick steps. When creating a new page, make sure that you select your custom template. There will be a drop-down in the right column where you can select your “Redirect” template (see image).

Also make sure that your set your page slug to something pretty. If you’re page is titled “Hey check out my new link”, your url slug will be hey-check-out-my-new-link. Don’t do that. Make the slug something simple, like “wpe”.

All that’s left now is to enter your long, ugly URL into a custom field labeled with the key of “redirect_url”. If you’ve never done it before, fear not, because it’s a much simpler process than people make it out to be. All you need to do is locate the “Custom Fields” box on the “Edit Page” screen and enter a key and value pair. The key is the title, “redirect_url”, and the value is the new URL, in this case: http://wpengine.com?a_aid=4e6fc813411ff

The great thing about this technique is it will work with any URL and doesn’t require a plugin. We use the technique lots of times internally, linking to our own specific posts with long URLs. As I mentioned above, it’s a great technique for video or a podcast, where you’ve actually got to say aloud Don’t forget to check out androidandme.com/wpe for a great deal on WordPress hosting.

Ultra handy PHP Google Analtyics API Class by Doug Tan

Over the past few weeks I’ve been using a PHP Google Analytics API Class that I’ve really been enjoying and figured I should make a post to share it with all of you. The class is just a single PHP file that does a lot of heavy lifting for you and lets you query Google Analytics with just a few lines of PHP.

I’ve been using the Analtyics API in a couple different projects, the main one being Metric. After you’ve included the PHP class, you can call all up pageviews reports (and much more) with some markup along the lines of:

[php]
<?php
include "googleanalytics.class.php";
try {
$ga = new GoogleAnalytics(‘{email}’,'{password}’);
$ga->setProfile(‘{GA Profile ID}’);
$ga->setDateRange(’2005-01-01′, date(‘Y-m-d’));
$report = $ga->getReport(
array(‘dimensions’ => urlencode(‘ga:pagePath’),
‘metrics’ => urlencode(‘ga:pageviews’),
‘sort’ => ‘-ga:pagePath’,
)
);

// do something with $report
?>
[/php]

This isn’t really meant to be a full-on lesson or anything, I was mainly just posting to share PHP Google Analytics API Class“>the link. So bookmark it. You might need it sometime.