admin管理员组

文章数量:1300165

I've been working on this for a couple of days now. There have been many similar solutions here on this site, but none of them have worked out for me, or they nearly do, but then something else breaks.

For example, I tried this method: Using Custom Fields in Custom Post Type URL

But when I finally got it working, every page on the site which wasn't specifically an "accommodation" CPT returned 404 pages.

What I'm trying to do is to rewrite the URLs for accommodation pages from: /accommodation/%accommodation%/

to: /%country%/%region%/%accommodation%/

I also need to do the same for Region CPTs (/region/%region%/ => /%country%/%region%/) but haven't managed to get the accommodation rewrites fully working yet.

As part of the build, I have an ACF custom field for Post Object, which returns the post ID of selected country and region CPTs; this is already used in the build to pull in related content, etc. So for that reason, it makes sense to use these ACF fields to determine the values that need to go into the URL structure.

Here's what I'm working with at the moment:

function change_accommodation_post_type_link( $url, $post, $leavename ) {
    if ( 'accommodation' == $post->post_type ) {
        $country_object = get_field('accommodation_country');
        $region_object = get_field('accommodation_region');
        $country = get_post_field( 'post_name', get_post($country_object));
        $region = get_post_field( 'post_name', get_post($region_object));
        
        $url = site_url('/') . $country . '/' . $region . '/' . $post->post_name . '/';
    }

    return $url;
}

function try_accommodation_before_page_in_parse_request( $wp ) {
    global $wpdb;

    if ( is_admin() ) return;

    if ( array_key_exists( 'name', $wp->query_vars ) ) {
        $post_name = $wp->query_vars['name'];

        $id = $wpdb->get_var( $wpdb->prepare(
            "SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND post_name = %s ",
            'accommodation', $post_name
        ) );

        if ( $id ) {
            $wp->query_vars['accommodation'] = $post_name;
            $wp->query_vars['post_type'] = 'accommodation';
        }

    }
}
add_action( 'parse_request', 'try_accommodation_before_page_in_parse_request' );

add_filter( 'post_type_link', 'change_accommodation_post_type_link', 10, 3 );

Based on this:

This works in as far as it changes the URL in the back-end, and it doesn't break any other pages, but it doesn't work. For example, the "Evergreen" accommodation URL is changed to /costa-rica/tortuguero/evergreen/ but that returns a 404. I have to manually put /accommodation/evergreen/ into the URL bar to see the post.

This is my first time playing with URLs/permastructs, but this is fundamental to the client, and I'm running out of options (and time).

Any help you can provide would be greatly appreciated!

EDIT:

If it helps, here's the code I had which almost worked, using wp_rewrite:

function add_rewrite_rules(){
    global $wp_rewrite;

    $wp_rewrite->add_permastruct('accommodation', '%country%/%region%/%accommodation%/', false);
    $wp_rewrite->add_permastruct('region', '%region-country%/%region%/', false);
}

function permalinks($permalink, $post, $leavename){
    $post_id = $post->ID;

    if ($post->post_type != 'accommodation' && $post->post_type != 'region' || empty($permalink) || in_array($post->post_status, array('draft', 'pending', 'auto-draft'))) {
        return $permalink;
    } else if($post->post_type = 'accommodation') {
        $country_object = get_field( 'accommodation_country');
        $region_object = get_field( 'accommodation_region');
        $country = get_post_field( 'post_name', get_post($country_object));
        $region = get_post_field( 'post_name', get_post($region_object));

        $permalink = str_replace('%country%', $country, $permalink);
        $permalink = str_replace('%region%', $region, $permalink);

        return $permalink;

    } else if($post->post_type == 'region') {

        $region_country_object = get_field('region_country');
        $region_country = get_post_field( 'post_name', get_post($region_country_object));

        $permalink = str_replace('%region-country%', $region_country, $permalink);
        
        return $permalink;
    }
}

add_action('init', 'add_rewrite_rules');
add_filter('post_type_link', 'permalinks', 10, 3);

This code worked for both CPTs but every page on the site then returned a 404 error. Is there some way I could maybe tweak this and have it working?

本文标签: permalinksWordpress URL rewrites using Advanced Custom Field