• Hello all,

    I have made myself a custom rewrite for a post type I’ve made. All ‘s well and all ‘s fine, but I run into a slight problem.

    When the post is auto saved, the permalink structure does not show correctly in the sample permalink under the title.

    It shows as https://loc.test-site.org/?post_type=matches&p=137 where with my code I expect it to be: https://loc.test-site.org/match/%d%/%m%/%Y%/%post-name%/

    If I save the post, it all works fine, but when it autosaves it’s not.

    Anyone have any idea how I can fix this?

    I use the code below to generate my new permalink

    function better_match_permalinks( $permalink, $post ) {
    	global $wp_rewrite;
    
    	$timestamp = get_field( 'match_datetime', $post->ID );
    
    	$structure = __( 'match', 'apollo' );
    	if( ! empty( $timestamp ) ) {
    		$structure .= date( '/d/m/Y', $timestamp );
    	} else {
    		$structure .= date( '/d/m/Y', strtotime( $post->post_date ) );
    	}
    	$structure .= '/%matches%/';
    	$wp_rewrite->add_rewrite_tag( "%matches%", '([^/]+)', "matches=" );
    	$wp_rewrite->add_permastruct( 'matches', $structure, false );
    
    	return $permalink;
    }

    I hope some one can help me out.

    Thanks

    Mark

Viewing 7 replies - 1 through 7 (of 7 total)
  • Thread Starter Mark Jansen

    (@mark-jansen)

    Ok, I found out perhaps the filter ‘get_sample_permalink_html’ could help me further, but I am a bit in the dark about some things.

    1. Why do I not get the structure I am building when I hook into post_type_link. Why is the link that I see different and also for example, when I hover over a link in a connected post (using Posts2Posts for that), I get the ‘ugly’ URL, not my custom permalink structure

    Perhaps if I understand that, I can fix this problem in a whole different way maybe. Maybe I am approaching this entirely wrong.

    2. get_sample_permalink_html gives me the entire html from the permalink, get_sample_permalink is also a function, but that one has no filter. Perhaps that is something that I am overlooking or is that’s intended?

    3. If I try to apply my custom permalink structure, see the code in my post above, it gives me 1970/01/01 as date. It looks like $post entirely disappears when autosave kicks in.

    So all in all, I am not that much wiser, but I hope I’m getting somewhere. Anyone who can give me another kick in the right direction?

    Moderator bcworkz

    (@bcworkz)

    How is your code called? Hooked into what? Or called from where? This influences the answer to why you are not seeing your permalink in ‘post_type_link’. And possibly why autosave is not picking it up.

    It’s somewhat common in WordPress for only higher level functions to have filters and the lower level functions that are called from within do not. I suppose the idea is you can either filter the higher function or write custom code that directly calls the lower function and manipulates the returned value, so no filter is required. In the case of get_sample_permalink() though, it does have a filter, it’s not as obvious but it’s there — ‘editable_slug’. Even if it doesn’t explain why autosave is not picking up your permalink, it may offer a way to resolve the issue?

    Thread Starter Mark Jansen

    (@mark-jansen)

    The hook is called in my custom plugin using the following line:

    add_filter( 'post_type_link', array( $this, 'better_match_permalinks' ), 10, 2 );

    Your explanation about the filters makes sense, but shame that in this case you get the entire HTML, where you really wouldn’t want that ?? (well I don’t :P)

    Hi Mark,

    Are you sure this code is working the way you want it to when using the save post button explicitly?

    A few things come to mind when looking at your code..

    1. You’re not actually manipulating the permalink variable. You are returned the same permalink as was given in the function parameters.

    2. I wouldn’t add rewrite rules in a filter, as the filter might be called multiple times on the same page load. You will only need to add those once, have a look at the WP_Rewrite class documentation for some examples.

    3. Are you using the Advanced Custom Fields plugin to get the match_datetime meta value? It might also be that PHP’s date() function is failing to format it. In that case, the third parameter of the ACF get_field function might come in handy.

    Hope that helps at least a little! Good luck.

    Thread Starter Mark Jansen

    (@mark-jansen)

    Thanks for your answer.

    1. Hm, strange, because the permalink seems to work fine. When ever I save the post, the sample-permalink shows up correctly and the permalink works. When I pull up the permalink in the frontend, it gives me the permalink I expect.

    I based my code on this tutorial:
    https://shibashake.com/wordpress-theme/custom-post-type-permalinks-part-2

    2. I thought the post_type_link filter was designed for this, that is why I used it. I’ll have a look at the documentation you posted.

    3. I am using ACF yes, but when it is autosaved, and I forgot to mention this is only when it’s a new post, it should use the $post->post_date because $timestamp will be empty. When I dump the $post variable to the screen, it shows up, but not on autosave, then it seems to be empty. Very strange.

    When I publish or draft the post, it works fine. It’ll either get the ACF date or the post date.

    Hi Mark,

    The tutorial you’re referring to adds the rewrite rules when the plugin is initialized. Notice the first sentence in his code snippet.

    // add to our plugin init function
    global $wp_rewrite;
    $gallery_structure = '/galleries/%year%/%monthnum%/%gallery%';
    $wp_rewrite->add_rewrite_tag("%gallery%", '([^/]+)', "gallery=");
    $wp_rewrite->add_permastruct('gallery', $gallery_structure, false);

    Then (point 3 in the tutorial) he returns a different permalink according to his own custom logic.

    My guess is that it will work just fine for both regular saves as auto saves if you fix that part of your code. ??

    As for the $post object being empty on autosaves, not sure about that. It’s just null?

    Thread Starter Mark Jansen

    (@mark-jansen)

    Big big big thank you Danny.

    Turns out I didn’t read the tutorial all that well and I had to create the structure in the init hook and the permalink itself in the post_type_link hook.

    It works now with the following code:

    add_action( 'init', array( $this, 'match_permalink_structure' ) );
    add_filter( 'post_type_link', array( $this, 'better_match_permalinks' ), 10, 3 );
    public function match_permalink_structure() {
    	global $wp_rewrite;
    
    	$structure = __( 'match', 'apollo' ) . '/';
    	$structure .= '%year%/%month%/%day%/';
    	$structure .= '%matches%/';
    
    	$wp_rewrite->add_rewrite_tag( "%matches%", '([^/]+)', "matches=" );
    	$wp_rewrite->add_permastruct( 'matches', $structure, false );
    }
    public function better_match_permalinks( $permalink, $post, $leavename ) {
    	$rewritecode = array(
            '%year%',
            '%month%',
            '%day%',
            $leavename ? '' : '%matches%',
        );
    
    	$timestamp = get_field( 'match_datetime', $post->ID );
    
    	if( ! empty( $timestamp ) ) {
    		$year = date( 'Y', $timestamp );
    		$month = date( 'm', $timestamp );
    		$day = date( 'd', $timestamp );
    	} else {
    		$year = date( 'Y', strtotime( $post->post_date ) );
    		$month = date( 'm', strtotime( $post->post_date ) );
    		$day = date( 'd', strtotime( $post->post_date ) );
    	}
    
    	$rewrite_replace = array(
    		$year,
    		$month,
    		$day,
    		$post->post_name,
    	);
    
    	$permalink = str_replace($rewritecode, $rewrite_replace, $permalink);
    
    	# Flush rewrite rules, so the changes are visible.
    	//flush_rewrite_rules();
    
    	return $permalink;
    }

    Thanks!

Viewing 7 replies - 1 through 7 (of 7 total)
  • The topic ‘Changing sample permalink’ is closed to new replies.