Get default permalink structure from pretty URL’s

When a single post is clicked on from a category page or for that matter any page, you can get the URL of that referrer and parse it to get the query string. But this only works with the default permalink structure

Example when the referrer is a category page:

A var_dump( parse_url( wp_get_referer() ) ); gives the following output with the default permalink structure

array(4) {
  ["scheme"]=>
  string(4) "http"
  ["host"]=>
  string(9) "localhost"
  ["path"]=>
  string(11) "/wordpress/"
  ["query"]=>
  string(5) "cat=7"
}

With the same var_dump() with permalinks set to /%postname%/, this is what you get

array(3) {
  ["scheme"]=>
  string(4) "http"
  ["host"]=>
  string(9) "localhost"
  ["path"]=>
  string(32) "/wordpress/category/uit-my-lewe/"
}

I can use the path from the second block of code with get_category_by_path(), I can get the category objects

My problem is, how do I go about this for taxonomy terms.

I’ve done a test. I have a custom taxonomy event_cat. If I rewrite it to event-slug, I get the following path using /%postname%/ as permalink structure

/wordpress/event-slug/5-star/

and

event_cat=5-star

using the default structure

Automatically my taxonomy name won’t be in the URL, just my term’s slug. So, this will not be a very fail safe method getting objects from the term.

My question is, how do I properly get the default permalink structure get the query string, or the query string or the taxonomy and term name from the /%postname%/ permalink structure

2

First of all I have to say that wp_get_referer() is not 100% reliable because it relies on $_SERVER['HTTP_REFERER'] that is not 100% reliable, from php.net docs:

The address of the page (if any) which referred the user agent to the current page. This is set by the user agent. Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature. In short, it cannot really be trusted.

Alternative Solution

If you can add to post url a query argument that says where the post comes from, it will be more reliable and you don’t need to parse an url to get a term object.

Example:

add_filter('post_link', function($permalink) {
  if (is_category() && ($cat = get_queried_object())) {
    $permalink = esc_url(add_query_arg(array('catfrom' => $cat->term_id), $permalink));
  }
  return $permalink;
});

Doing so, post permalinks clicked from a category page will send you to an url like

http://example.com/wordpress/post-name?catfrom=12

And you can easily understand where the user comes from without relying on $_SERVER['HTTP_REFERER'] and without any other effort.

your question

Get query information starting from an url is something that WordPress does inside the WP::parse_request() method.

That method is intended to be used only once and only for “main” url (the url an user is viewing) and not for arbitrary urls.

Few months ago I wrote the Url To Query plugin with the aim to do same thing for arbitrary urls.

What I did was to take WP::parse_request(), and refactor it to a more sane OOP code and make it work with arbitrary urls (e.g. the url to process is received as arguments instead of be taken from $_SERVER var).

Using my plugin you can

$args = url_to_query('/wordpress/event-slug/5-star/');

var_dump($args); // array( 'event_slug' => '5-star' );

So you obtain the query arguments (something that you can straight pass to new WP_Query) starting from an url, that is exactly what WP::parse_request() does.

In your case you could probably check the args array with no need to actually run a query.

This can surely work, however I think that the additional effort needed to parse the url and the unreliability of $_SERVER['HTTP_REFERER'] makes the first solution better for your scopes.

Leave a Comment