I have a huge problem! I am in the middle of migrating a drupal based online database to wordpress. In the old database every object (post) had downloadable qr code. Because the database is used for scientific purposes and users where allowed to use the downloaded qr code in their own publications for reference purposes. Since the system is five years old, some books have been printed using those qr codes, with the objects url embedded in the short code. It used the normal structure in drupal site-url/node/XXXX (where XXXX is the number of the content node) On the wordpress version the permalink structure is (and should be) for example like this: site-url/audio/name-of-the-post So for example https://soundandscience.de/node/1040 becomes https://soundandscience.de/audio/lautarchiv-recording-la-566-1-siebs-theodor-a-laute/

What I can do, because I use ACF a lot, is create a field where the node number of the old post can be stored (in this example case: 1040)

The post transference between drupal and wordpress will be handled manually (poor students)...

But is there a way to make it possible, for the old shortcodes in printed books to be redirected to the new correct post?

Best Martin

  • How many pages are you talking about? Might be the simplest to generate rewrite rules after all content has been migrated once and just put it in your server config (.htaccess e.g.). So /node/124534 -> /audio/foo-bar redirect is hardcoded there.
    – kero
    Sep 3, 2021 at 12:13
  • It is impractically to put a rule in the htaccess for every of the 2.500 posts… Sep 4, 2021 at 5:24
  • 1
    While it may be impractical, it will be much faster and much more simple to maintain than any solution with PHP and database involved. But happy to read that you found a solution
    – kero
    Sep 6, 2021 at 9:07

2 Answers 2


Here's an idea for you:

If you create a script for importing the content from Drupal, using the node ID as a suggested ID for the new WP post (Otto has explained how to do this here: How can I assign post a specific ID on creation?), this would lead to your nodes being accessible in the new site on https://yoursite.com/?p=XXX for each of them, which will be translated to the new URL structure. Then setting up a plugin like https://wordpress.org/plugins/redirection/ for a regex redirection of any request that comes for /node/XXX to be redirected to /?p=XXX you'll have what you are looking for without having to create custom fields. Beware that this would work if your website is clean of other posts at the moment of migrating your Drupal content, as the ID is added only as a suggestion and will not be the same, if it already exists in wp_posts table.

I'm pretty sure it would be faster to migrate the Drupal content programatically rather than having people to manually do this and then set the extra field that you speak of.

If you insist on having your content manually transferred or you can't go with my first suggestion, then you could go for another approach - intercepting the 404 handling in WordPress by using pre_handle_404 or template_redirect filters could allow you to parse the request for the node ID if it matches the pattern siteurl/node/XXX, find your right post with the sought ACF value (WP_Query with a meta_query in it) and redirect to the page that you want your visitors to end up on.

  • I lack the qualification to import the posts via script. They did a lot of strange things there. (For example every posts featured image was implemented via external url and there is a complicated bibliography structure…) And there will be more than 10 students from canada, france and germany who will do this, it is ok. But the 404 redirect idea seems promising. Since I give them only one acf field for this to put the node number in, and the system will do the rest if needed, it isn‘t too much work I hope. I will try to implement this. Thx for the idea!!! Sep 4, 2021 at 5:28

So. I decided to work with the following code (complete aware, that this can be optimized)

At first I get the url, which brings me to the 404 template. I check, if it contains the term "node", which indicates, it is a link pointing at an entry of the drupal version, than I split it up, until I get the number following the "node/". Then I make a new Query containing all possible post types for that procedure, checking if there is one, where the node number stored in an acf field matches. Finally I get the permalink of the found post and then I replace the html document via javascript.

/* 404 Template including redirect for old database entries


$re_link = $_SERVER['REQUEST_URI'];

if (strpos($re_link, 'node')) {
    $re_link_number = explode('/', $re_link);

$p_type = array('objects', 'texts', 'video', 'audio', 'pictures', 'instruments', 'essays', 'people', 'locations', 'sets', 'collections', 'companions');

$args = array(
    'post_type' => $p_type,
    'posts_per_page' => 10000,

$all = new WP_Query($args);

while ($all->have_posts()) : $all->the_post();
    if ((get_field('node_number') == $re_link_number[2]) && ($re_link_number[2] != '')) { ?>
        <script>window.location.replace("<?php echo get_permalink(); ?>");</script>
    <?php }
  • Sorry for the nonsense with the code pasting. This behaves in a strange manner. Sep 5, 2021 at 10:13
  • That looks like a reasonable solution - assuming you're redirecting to HTML pages i.e. you'd expect the users to be viewing these in a browser? - but you can query for the correct post directly rather than having to search for it. I think you just need a meta query for _node_number - IIRC ACF fields are just stored in meta with an _ prefix, but I'd look at the database to confirm that. However I think I'd still rather hook into the routing somehow to fix this without having to use a JavaScript redirect, but I don't know the code to suggest where to hook exactly.
    – Rup
    Sep 6, 2021 at 0:06

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.