Is it worth considering a bulk URL entry option, where a list of redirects is entered into a single text area, with each pair of redirects being specified on each line? This is very useful when I have more than half a dozen redirects to add. eg:

From URL	To address (optional Type, 301 assumed)
oldurl.htm	new-address.php
oldurl2.htm	new-address2.php
oldurl3.htm	new-address3.php
contact.htm	about.php	404

(optional delimiter, tab, comma, semicolon)

Comments

essenceofginger’s picture

Would love to see this too. I need to add over 500 301s as a result of migrating a site from another platform to Drupal, doing them manually one by one is almost certainly a no-go; putting them in the .htaccess is less than ideal as I'd like to take advantage of the module's expiry function.

So... +1 for this request!

nicholasThompson’s picture

Status: Active » Closed (won't fix)

See: http://drupal.org/project/path_redirect

I *believe* it has an import feature - if not, the data is stored in a single table and would be a relatively trivial task to import a CSV into it.

essenceofginger’s picture

Yup, that's what exactly we tried to do. We were a bit stumped with the MD5 hash though; seeming as it's not clear how they're generated, we tried to insert them blank. It wouldn't work (there's a unique key constraint on the hash field); so generating a unique MD5 hash for each entry by calculating the MD5 of the source URL seemed to do the trick. Job done!

Script (credit to Dave Tibbs):

#!/bin/bash

while read line; do
fromurl=$(echo $line | cut -f1 -d,)
tourl=$(echo $line | cut -f2 -d,)
md5hash=$(echo -n $line | md5sum | awk {'print $1'})
mysql drupal -Ne "insert into redirect (hash,type,source,source_options,redirect,redirect_options,language,status_code) values ('$md5hash','redirect','$fromurl','a:0:{}','$tourl','a:0:{}','und',0);"
done < $1

To run: ./parse_csv.sh [filename]

Hope this helps anyone else!

StephenWard’s picture

For those in search of a (very) quick and (very) dirty solution, I wrote this quick script for adding bulk redirects to client sites prior to launching them. Just drop the following code into a temporary file in your Drupal root, navigate to it, and submit a list of redirects. The list should be one redirect per line with the old URL (sans everything up to the base directory) followed by a comma and the new path.

<?php

define('DRUPAL_ROOT', getcwd());
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

if (isset($_POST['redirects'])){
  $redirects = explode("\n", $_POST['redirects']);
  foreach ($redirects as $redirect){
    $redirect_info = explode(',', $redirect);
    $redirect = new stdClass();
    $redirect->rid = $redirect->hash = $redirect->override = '';
    $redirect->source_options = $redirect->redirect_options = array();
    $redirect->type = 'redirect';
    $redirect->language = 'und';
    $redirect->status_code = 0;
    $redirect->source = trim($redirect_info[0]);
    $redirect->redirect = trim($redirect_info[1]);
    redirect_save($redirect);    
  }
}

?>

<html>
<head>
  <title>Bulk Redirect</title>
</head>
<body>
  <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
    <textarea name="redirects"></textarea>
    <input type="submit" value="Submit">
  </form>
</body>
</html>

I'm using Drupal 7 for this and it seems to work fine; it may need to be tweaked for Drupal 6. I'd love to see something more elegant added to the module itself, but for now, this script suits my purposes.

wmfinck’s picture

StephenWard thank you, wish I could buy you a beer!

elmarquis’s picture

Issue summary: View changes

Thanks, StephenWard. Did exactly what I needed. A one-off bulk import of 301 redirects.

I occasionally got some errors, so I made one small change to add some error handling and list the ones which were successful and ones which failed.
Most of the time an error was due to a duplicate entry.

Will share the code here in case it helps anyone.

<?php
define('DRUPAL_ROOT', getcwd());
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
if (isset($_POST['redirects'])){
  $redirects = explode("\n", $_POST['redirects']);
  $success = "<h1>Success</h1>";
  $errors = "<h1>Errors</h1>";
  foreach ($redirects as $redirect){
    $redirect_info = explode(',', $redirect);
    $redirect = new stdClass();
    $redirect->rid = $redirect->hash = $redirect->override = '';
    $redirect->source_options = $redirect->redirect_options = array();
    $redirect->type = 'redirect';
    $redirect->language = 'und';
    $redirect->status_code = 0;
    $redirect->source = removeForwardSlash(trim($redirect_info[0]));
    $redirect->redirect = removeForwardSlash(trim($redirect_info[1]));
    try {
      redirect_save($redirect);
      $success.=$redirect->source.', '.$redirect->redirect.'<br/>';
    }
    catch (Exception $e){
      $errors.=$redirect->source.', '.$redirect->redirect.'<br/>';
    }
  }
  echo $success;
  echo $errors;
}
function removeForwardSlash($str){
  return ltrim($str, '/');
}
?>
<html>
<head>
  <title>Bulk Redirect</title>
</head>
<body>
  <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
    <textarea name="redirects"></textarea>
    <input type="submit" value="Submit">
  </form>
</body>
</html>

deardagny’s picture

Thanks @StephenWard and @elmarquis. This was a huge help. I owe you beers as well.

Channel Islander’s picture

Hi guys,

Thanks for the script, but I have to report to anyone considering it that it will not work if your source URLs have query strings and/or your aliases have fragment anchors.

Redirect module stores those URL elements in a data hash in the source_options and redirect_options fields in the DB; this script retains them on the URL paths when storing those [via call to redirect_save() ] and thus the redirects do not work.

Channel Islander’s picture

D'oh, I should have known there would be a module if I just looked harder for it.

https://www.drupal.org/project/path_redirect_import seems to be the solution for this task.