Custom permalink structure for custom post types

Hey guys, Jimbo here. So today I wanted to talk about custom permalink structures in WordPress. Specifically custom permalinks structures for custom post types (CPT). I’ve done some googling on the subject and I think the general internet don’t have so much info on this topic.

So, you have created a custom post types in WordPress, and now you want a specific permalink structure for that post type. This seems to be especially true for people that want their taxonomy terms to show in their permalinks. While this is definitely possible, it’s not really optimal since a post can always have multiple terms by default, hence not ideal for a permalink structure.

If you want a basic parent/child permalink structure you might be better of using the parent child functionality for your custom post type. The problem with this approach is that it gets kind of clunky to administrate if you have a lot of content. The upside is that WordPress automatically resolves the permalinks (if you have pretty permalinks enabled) to parent/child and so on for as man children and grandchildren you might have. If you know any plugins to improve the usability of the archive list in the WordPress-admin for complicated ancestor-structures please comment down below.

Enough of the lull lull, let’s create a permastruct for a CPT. I’m not completely sure what hook you SHOULD use to do this but you CAN use the init-action. I guess it would be possible to do it on the after_setup_theme-hook as well, though I don’t think I’ve tested this. Anyway, the last time I did it I hooked it to “init” and it worked. So, let’s say we have a custom post type registered as “jimbos_post_type” and we want to try and make use of a custom taxonomy in our permalink structure like so: “/jimbos-corner/custom-taxonomy/jimbos_post_type”. It would look something like this (put in functions.php):

// We hook our function to the init-action
add_action( 'init_rewrites', 'init' );

function init_rewrites() {
  // We will work with the global wp_rewrite object
  global $wp_rewrite;

  // Create your structure
  // jimbos-corner is our base slug and will be the same for every post
  // %taxonomy_term% is surrounded with percentage to easily find it and
  // replace it later on.
  // The last part of the url should be the registered name of your CPT,
  // that means WordPress automatically resolves this part to the post slug
  // and it will be editable on the post edit page
  // dont forget to surround with %
  $structure = '/jimbos-corner/%taxonomy_term%/%jimbo_post_type%';

  // For our %taxonomy_name% to fully function we must add it as a tag,
  // I'm not totally sure why this step is necessary but I cannot get it
  // work without it
  $wp_rewrite->add_rewrite_tag("%taxonomy_term%", '([^/]+)', "taxonomy_name=");

  // Lastly we add our permastruct and connect it to our CPT
  // First argument should be the registered post type name
  $wp_rewrite->add_permastruct('jimbos_post_type', $structure, false);
 }

If you now go to your wordpress-admin and one of your custom post type called “Test” you should see it has the following permalink:

/jimbos-corner/%taxonomy_term%/test/

Kinda awesome huh?

So the next step is to switch out the %taxonomy_term% part of our permalink into something that actually makes sense. To do this we will hook into a filter that fires just before permalinks are being outputted called post_type_link

add_filter( 'post_type_link', 'setup_permalinks', 10, 3 );
// When hooking to post_type_link we get two aruments
// The current post being processed and its current permalink
function setup_permalinks($permalink, $post) {
  // Remember, all posts on your installation will pass this function
  // But we only want to intercept those belonging to jimbos_post_type
  if ( get_post_type($post) === 'jimbos_post_type' ) {
    // Get all terms checked on current post
    // custom_taxonomy is the name of some custom taxonomy
    $post_terms = wp_get_post_terms($post->ID, 'custom_taxonomy');

    // If there is only one term ticked for this post, we will use its slug
    if ( count($post_terms) === 1 ) {
      $taxonomy_term = $post_terms[0]->slug;
    // If there is more than one, or none, we have a hardcoded fallback
    } else {
      $taxonomy_term = 'whatever';
    }

    // Make sure the permalink have %taxonomy_term% in it
    if ( strpos($permalink, '%taxonomy_term%') !== false ) {
      // Replace %taxonomy_term% to whatever reside in the $taxonomy_term variable
      $permalink = str_replace('%taxonomy_term%', $taxonomy_term, $permalink);
    }

  }
  return $permalink
}

As you can see above, this is where it gets problematic to use taxonomy terms in your permalinks, since there really is no good way of handling multiple terms. However this technique is applicable to other scenarios and it can really come in handy to have this knowledge in your arsenal.

If you now revisit your custom post named test, you should see that the %taxonomy_name% part is replaced by a term-slug or “whatever”. Although the actual link will not work since we have to flush the permalinks in order for WordPress to update its rewrite rules.

This can be done by simply going to Settings->Permalinks and click the blue Save button.

And that’s it, you should now have a custom permalink structure for you custom post type.

Something to note is that the WordPress codex on this topic is not really that informative as one would like but to give some more sources of reading, here are some links:

WP_Rewrite class

When should add_rewrite_tag() be used?

Tutorial that helped me do this the first time

The Cracklord

The cracklord is an overnatural and insane being from the deepest forrest of Crackerville, Crackzwood. It’s a crazy carnivore that eats every creature in its path with no remorse and no regrets. There are, though, very rare occasions on which cracklords will resort to eating fruits, berries and grasses (usually to aid digestion).

When hunting, the cracklord will conceal itself in bushes or long grasses close to their intended prey’s rear or side. They will gradually, silently sneak forward; stalking the animal, which is unaware of the hunter’s proximity.

207493

The Cracklord

When it is approximately 20 to 30 feet (between six and nine metres) away from its victim, it will lunge out from its hiding place in an impressive display of power and agility.

They are able to make jumps of more than 30 feet (nine metres), giving them a huge advantage over an animal that needs to escape this fierce enemy.

They pounce on their victim, using their strong hind legs to support the struggle with the prey and their front legs to pull the victim to the ground.

Once under control, the cracklord will snap the spinal cord just behind the head (for smaller catches) or grab the throat with its jaws (for larger prey) to ensure a speedy death.

It will then drag the kill to a secluded spot in which it can enjoy it in peace. What it does not finish, it will likely cover; returning to these leftovers later or the following day.

image-adaptive-full-medium

Unravel

Hej guys, Jimbo here.

So yesterday I was sitting infront of my TV and PS4 thinking “I wanna play something new”. I don’t feel like playing Rocket League, FIFA or Helldivers, I want a new experience.

So I started browsing the PSN-store and as many of you probably know, Far Cry Primal just got released and is of course on the front page. I took a good look at it and, I mean, it looks good, I’m sure it’s quite fun but for real though, I wasn’t sold on Far Cry 4. It got repetitive pretty quickly and I got tired of it just after a few days. So I felt I didn’t want to invest 60 dollar or whatever into a big game that I’ll probably play like 10% of.

Despite all of this I felt that my options were scarce since I really wanted to play a new game ASAP, but then I went to my recommendations and saw Unravel for about 20 euro and I said to myself, this is perfect. I like platformers, the game has been somewhat hyped, swedish made, I want to play this, and I wouldn’t regret it, this game was astonishing. I’m really impressed by it and I would like to thank the developers for making such a beautiful game.

The story, the visuals, the audio, the music, it was all great. The controls are good and the puzzels are really challenging at times but more often than not they´re not that hard. The game has some innovative mechanics involved since your character leaves a string of yarn behind him as he progresses that you can use to tie knots, make trampolines or climb back up to places you’ve fallen down from.

I would recommend this game to anyone, but if you’re looking for a really hard challenge or some hardcore gameplay then I think you should look elsewhere. Although if you want a beautiful game that you can play while kicking it back in your couch on a sunday, this is a must for you.

Go play it now.

Send your own HTTP status code in WordPress

Hey guys, the last few months I’ve been working on a rather complex WordPress-website with data flowing both from WordPress and the customers external database. The external database holds all of their products and are administrated from a completely different system. All I wanted to do was to fetch that data and display it in their WordPress page without losing the WordPress context.

In order to accomplish this I made a php file, products.php, and a WordPress-rewrite saying that if someone tries to access /products load products.php. Now this was seemingly working just fine, the page loaded, I had access to the WordPress context and I could fetch my data as I pleased from the customers product database.

However when I ran my site through a broken link checker app I found that all custom rewrites to files “outside” of WordPress threw 404-errors. I’m still not entirely sure why this happens but I guess the file doesn’t match any criteria in the handle_404 function in the WP-class when it loads.

When this problem was uncovered I was short on time and after half a day of googling I found the WordPress function status_header() where I can override whatever status WordPress thinks this page should send. So as a quick and dirty fix I just ran status_header( 200 ); just before I render my page resulting in a satisfactory status header.

In my opinion this solution is okay but of course it’s not optimal. There should be some way to make WordPress recognise files that doesn’t serve WordPress content. If I get time I will look deeper into the issue.

If you have similar experiences, don’t hesitate to comment and share your thoughts.

Sincerly
Jimbo