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.

  • 1
    Fantastic, was digging around a bit and found stackoverflow.com/questions/5897758/… which mentioned the post_name setting the slug and tested that manually adding the %E2%80%99 to the field in the db resulted in it working. Thanks for your solution, it works like a charm! :) May 16, 2014 at 18:49
  • @TomHarrigan you're welcome :)
    – gmazzap
    May 16, 2014 at 18:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.