I’m working through a migration from Drupal to a WP multisite network, I’ve got a post meta field that contains the URL of the old post (mostly to maintain social counts and such) that I’m using for the permalink structure. I’m doing this with the following:

add_filter('post_link', 'migration_permalinks', 10, 3 );

function migration_permalinks( $permalink, $post, $leavename ) { 

    if( ($post->post_type == 'post' ) && ( $the_link = get_post_meta( $post->ID, '_the_old_site_permalink', true) ) ) {
        $url = parse_url( $the_link );
        $permalink = site_url() . $url['path'];
    }

    return $permalink;
}

The issue I run into is that if the post title contains an apostrophe, (not a straight single quote '), the post URL does not work. Encoded, that converts to %E2%80%99 . In the browser address bar, if I change the apostrophe to a straight single quote, the URL works and the post displays. The existing Drupal site contains the apostrophe (%E2%80%99) without issue.

Maintaining the URL as is is pretty important because I don’t want any existing links to the page to 404 when the migration occurs. Why is the link not working when it contains an apostrophe?

1 Answer
1

I guess your problem is that when using the apostrophe in the url, WordPress rewrite rules recognize the post name containing the apostrophe.

You can verify that using print_r( $wp_query->query );.

If my guess is correct, the ‘name’ query param contain %E2%80%99, so WP will look in the db for a post whose slug contains the encoded apostrophe, but (by default) post slugs before being saved are filtered with sanitize_title and so %E2%80%99 is stripped out and the post is not found.

You can force WP to save %E2%80%99 in the slug, but I’m afraid that will explode in your face first or later, because WordPress always expect a sanitized slug.

If mantaining the url is important, you can use a filter on 'parse_query' to sanitize_title the ‘name’ query var:

add_action( 'parse_query', function( WP_Query $query ) {
  if ( ( $name = $query->get('name') )  ) {
    $query->set( 'name', sanitize_title($name) );
  }
} );

An then the url with apostrophe should work.

Leave a Reply

Your email address will not be published. Required fields are marked *