Support » Plugins » Hacks » My Custom Permalink Variable Plugin

  • Resolved saracup


    I developed a small plugin to be able to add a custom taxonomy as a string to a post. I’ve included the variable in a custom permalink string. This string is used by Apache to determine if external login is required. This part is working fine — the permalink is being changed, redirecting to Apache, and then causing the login to be prompted (it’s our institution’s flavor of PubCookie). I’ve tested other custom permalink structures, without variables, just to see that I had Permalinks set up correctly (mod_rewrite, etc.). So, in general, custom permalinks are functioning without 404 errors.

    However, once I put that particular string into the permalink, I am getting a 404. Here is the code for the plugin.

    function uvasom_restriction_init() {
        if (!taxonomy_exists('uvasomrestriction')) {
            register_taxonomy( 'uvasomrestriction', 'post',
    		   array(   'hierarchical' => TRUE, 'label' => __('UVA SOM Restriction'),
    				'public' => TRUE, 'show_ui' => TRUE,
    				'query_var' => 'uvasomrestriction',
    				'rewrite' => true,
    					'manage_terms' => 'manage_options',//or some other capability your clients don't have
    					'edit_terms' => 'manage_options',
    					'delete_terms' => 'manage_options',
    					'assign_terms' =>'edit_posts')
    $parent_term = term_exists( 'uvasomrestriction', 'uvasomrestriction' ); // array is returned if taxonomy is given
    $parent_term_id = $parent_term['term_id']; // get numeric term id
      'UVA Only', // the term
      'uvasomrestriction', // the taxonomy
        'description'=> 'Require UVA Netbadge credentials to read.',
        'slug' => 'privatenbauth-uva-only',
        'parent'=> $parent_term_id
    add_filter('post_link', 'uvasom_restriction_permalink', 10, 3);
    add_filter('post_type_link', 'uvasom_restriction_permalink', 10, 3);
    function uvasom_restriction_permalink($permalink, $post_id, $leavename) {
        if (strpos($permalink, '%uvasomrestriction%') === FALSE) return $permalink;
            // Get post
            $post = get_post($post_id);
            if (!$post) return $permalink;
            // Get taxonomy terms
            $terms = wp_get_object_terms($post->ID, 'uvasomrestriction');
            if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) $taxonomy_slug = $terms[0]->slug;
            else $taxonomy_slug = 'unrestricted';
        return str_replace('%uvasomrestriction%', $taxonomy_slug, $permalink);

    Debug is showing nothing. Here is the URL. Click on any post on the home page and you will get a 404:

    I’m sure it’s something obvious to a more trained eye. Please let me know, and thanks.

Viewing 12 replies - 1 through 12 (of 12 total)
  • Moderator bcworkz


    I don’t see anything obvious, I’m probably not trained enough 🙂

    What’s happening is the URL is not properly parsed, resulting in a query that’s impossible to fill. Hook the ‘posts_request’ filter and echo out the passed query string. Once when this issue cropped up for me, I found part of the query ended up reading “WHERE 1=0”! Hopefully your query will give a better clue to what went wrong. You can also check the query object by hooking ‘pre_get_posts’ to see where the query vars ended up. Between the two, hopefully you can deduce where the problem lies. Good luck!

    Thank you so much. I did use these hooks, but haven’t seen anything obvious yet. Will keep at it — there has to be a logical explanation. Again, thank you for taking the time! -Caty

    Moderator bcworkz


    If you would like to post the resulting query from ‘posts_request’ and the URL that initiated it, I’d be willing to see if I can make any sense of it. Also useful would be the var_dump from ‘pre_get_posts’ of the query object that resulted from the same URL. Please use for that one and just place the link here.

    If there’s any sensitive information in the data, I doubt it would change my understanding if you were to obfuscate the information.

    Thank you so much for your offer!

    This is the code that is looking for the posts within the custom taxonomy:

    SELECT SQL_CALC_FOUND_ROWS wp_[ID]_posts.* FROM wp_[ID]posts INNER JOIN wp_[ID]term_relationships ON (wp_[ID]posts.ID = wp_[ID]term_relationships.object_id) WHERE 1=1 AND ( wp_[ID]term_relationships.term_taxonomy_id IN (4) ) AND wp_[ID]posts.post_type = 'post' AND (wp_[ID]posts.post_status = 'publish' OR wp_[ID]posts.post_status = 'private') GROUP BY wp_[ID]posts.ID ORDER BY wp_[ID]posts.post_date DESC LIMIT 0, 1

    When I run the above query directly to the database, I get the post I want. So, it’s something with the permalinks, don’t you think?

    Once I click on a link that results from that query, I get this in the 404 page:

    SELECT wp_[ID]_posts.* FROM wp_[ID]_posts WHERE 1=1 AND (wp_[ID]_posts.ID = '0') AND wp_[ID]_posts.post_type = 'page' ORDER BY wp_[ID]_posts.post_date DESC

    When I run the above query directly in the database, I get zero records returned. Wondering why it’s asking for a post ID of ‘0’ and post_type of “page.”

    As for the var_dump from pre_get_posts, I confess to not being able to figure out how to make that happen. Do you have some sample code, and to what do I hook it?

    Again, thank you for being so willing to help!

    Okay, I added the following to my plugin code:

    echo '<pre>'; var_dump($query); echo '</pre>'; die;

    I get a white page that reads “NULL”

    So, it’s not finding the link in the database.

    In the database, the custom permalink pattern is recorded correctly in the wp_options table.

    Moderator bcworkz


    All that may not have meant anything to you, but it helped me, but not in the way you would think. The debugging steps I suggested are useful when no results are returned. I just learned now that this is not necessarily the same as a 404 error. So we need to look elsewhere for the cause of a 404 error.

    BTW, the (wp_[ID]_posts.ID = '0') AND wp_[ID]_posts.post_type = 'page' is normal for displaying a 404 page. I’m not sure how an ID of 0 really works, but it does.

    Let’s have a look at the ‘request’ filter. This tells us which permalink elements got assigned to which query vars. Hopefully it will be an indication of where things went wrong. Add this to your plugin code:

    add_filter('request', 'show_the_request');
    function show_the_request($vars) {
    	echo '<pre>';
    	echo '</pre>';
    	return $vars;

    Wow! Okay, so I put that in the plugin and it returns this:

        [page] =>
        [pagename] => privatenbauth-uva-only/funding-opportunity-test-post

    You can see it by clicking on this:

    Thank you! I am learning a lot about debugging techniques.

    Moderator bcworkz


    Whoa! That’s a very strange one! [pagename] should be only the post slug. The parser is supposed to separate query terms at every slash. You can imagine that if this were the only term and it consisted of only the slug, everything would work fine. I can’t even imagine how it’s not “seeing” this one slash. Which means, while we’ve identified the problem, I’m unsure what to do about it. Parsing slashes is a pretty basic low level operation.

    It appears the root WP install is in the ‘deansoffice’ folder, correct? If so, simply adding the taxonomy after ‘/deansoffice/’ should resolve the issue. This permalink should have worked: deansoffice/uvasomrestriction/privatenbauth-uva-only/funding-opportunity-test-post/ And a taxonomy/term query should list all posts with the term, but does not work either: deansoffice/uvasomrestriction/privatenbauth-uva-only/ Further more, this permalink should retrieve the post, but does not: deansoffice/funding-opportunity-test-post/

    Do you have some rewrite rules or other URL alterations at work here? It’s the only explanation I know for this behavior, and is likely how the slash is not “seen” by the parser.

    I wrote the following alternative approaches before I discovered the above mentioned behavior. I leave them here as something to consider if the above direction does not fully address all issues. For the time being, reading further is optional.

    Let’s take another look at your taxonomy. You say Apache is using the presence of the terms to decide whether credentials are needed or not. What if the terms were different than the permalink string? Will that mess up anything? Say the terms were private and open. Set up the permalink generation so that posts with the open term get a permalink with the public term and similarly for private.

    I’m sure you’re asking “Why?” It so happens that if a permalink containing a post slug has some random terms preceding it that the parser cannot recognize, those terms are ignored and only the slug is used to form the query. So if you make “privatenbauth-uva-only” a term not recognized by WP, Apache can still make use of it, but WP will ignore it.

    This does not address the problem, but it may cause the problem to not be an issue. Another possibility, which more directly addresses the problem, is to rename the taxonomy so it can be part of the permalink. I’m assuming you do not want ‘uvasomrestriction’ in the permalink. The normal way to make taxonomy permalinks is to include both the taxonomy and the term. Without the taxonomy, the parser typically does not know what to do with the term.

    It is possible to create a rewrite rule so that you do not need the taxonomy in the permalink. This means the term is identified by position in the URL. The problem with doing that is it’s difficult to have this situation work well with other possible permalinks because the parser will try to assign anything in that position to the taxonomy, even for permalinks completely unrelated to the taxonomy. Thus including the taxonomy is the most stable approach, but it can lead to an undesirable permalink. Changing the taxonomy name could at least minimize it’s impact on the final permalink.

    I want to thank you for all of your assistance and all the time spent. I’ve gone through the apache config, htaccess files, and vhost files for the two installations and they are identical. Yet the plugin works on one installation but not the other.

    I modified it to add a query string instead of adding the slashes and virtual directories to the permalink. That works, adding to the theory that there is something about the slash that WP is ignoring. Trouble is, you can edit the query string off of the URL and get the url without authenticating, thus, defeating its purpose.

    I am almost at the point where I am considering rebuilding the entire multinetwork environment for this domain but that seems utterly stupid. I am going to keep googling around to see if there is something I can do.

    Thank you, again, from the bottom of my heart. You have been most generous and patient.

    OH FOR GOODNESS SAKES! I amend this to say that I did indeed find the issue: Simple Multisite Sitemaps plugin was changing the permalink structure. I’ve de-installed it and now the 404s have gone away. I thought I had caught ALL the plugins but did it one more time before rebuilding the network.

    WOW! I learned so much through this screwup and am forever grateful to bcworkz for help and support and teaching me about how to use the request filter. AWESOME!

    Now to find a google sitemapping plugin that does not break my permalinks!

    Moderator bcworkz


    The fact you were able to find the source of the problem makes all my time and effort well worth it, though you simply having learned some things along the way would have been enough of a reward for me. Always glad to help.

    I’m relieved you did not find it necessary to rebuild everything! I wish I knew more about plugins and could suggest a sitemap solution, but I don’t. Best of luck in your search.

    This is now resolved. I will contact the developer of the Simple Multisite Sitemaps plugin to let them know about the permalinks conflict. Thanks to all!

Viewing 12 replies - 1 through 12 (of 12 total)
  • The topic ‘My Custom Permalink Variable Plugin’ is closed to new replies.