Get current screen what?

Hey there guys, Jimbo1337 here.

So today I wanted to talk about an interesting problem that I encountered on one of the many many WordPress-sites that I manage. The site in question is a WordPress multisite installation with a main theme and a bunch of child themes that override some different stuff. For derp reasons I had to add an extra global config-variable to know exactly where in the development cycle the site existed. Ergo, I had to know if the site was on the development or production server and do some stuff based on this.

How this is handled is of course top top secret but what I tried in this case was to add a php-file in the main theme root folder simply called settings.php where I declared my variable. I then included this at the top of my theme functions file and did my stuff and it seemingly worked just fine. Though problems arised some few months later when someone tried to access the multisite network admin page. WordPress threw an error message for reasons we could not understand.

Fatal error: Call to undefined function get_current_screen() in /network/settings.php on line 27

So what the f does this mean? I have no idea but apparently you cannot include a file named settings.php from your theme root if you want your network admin to be functional. But take notice, the error is thrown in a completly different file that we have no control over. When i renamed my file to config.php the problem disappeared so my best guess is that some weird global wordpress stuff is happening here. It is somewhat questionable if you want to put a config file like this in your theme root but it was a quick fix on my part. If you put it in a folder I think it’s completely fine.

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

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