By silkAdmin


2013-03-09 10:07:54 8 Comments

I want to change all paths for a given content type.

For example is would change all node of type "image" that are currently at

/[some_token]/[nid]

to

/photo/[nid]

I am using path auto and I have lots of node (70k), what would be the way to go ?

5 comments

@Jeremy John 2014-06-02 19:48:31

For Drupal 7, this is simple. You'll need the modules Views Bulk Operations, Administration Views. Tutorial here: https://drupal.org/node/1326928

@Druvision 2014-01-19 11:11:50

Like @alias suggested, you can Create an SQL query that will go over the url_alias table and create whatever aliases you want.

Note: for a small number of nodes, the answer is much much simpler:

  1. Go to admin/config/search/path/patterns to define the new URL pattern for that content type.
  2. Open the admin/content page.
  3. Filter by a specific node type.
  4. Check the checkbox above the content item to select all the items of the certain type.
  5. Select the 'update URL alias' operation.
  6. Press 'Update'.

Update URL alias of nodes of a certain type

Two other options if you have a medium number of nodes:

  1. Temporarily change the number of nodes per page hardcoded in core. This will allow you to use the option above with more then 20 nodes at a time.

  2. Create a VBO content admin view to allow the user to select more then 20 nodes on a same time, then select which action to execute.

@optimusprime619 2013-03-12 14:12:45

Though the query has been answered I'd like to share the methods which I've tried for building bulk url aliases with path auto module based on my experience hoping this serves of use to someone looking for a similar concern of aliasing content of huge magnitude in a generic manner:

Drush method example to alias 1000 published nodes of specific type in loop of 50 nodes

drush eval '$start=0;$limit_count=50;$break_at=1000;
while (1) { $resource = db_query("SELECT nid FROM node WHERE type=\"MY_NODE_TYPE_TO_UPDATE\" AND status=1 LIMIT $start, $limit_count");
while($result = db_fetch_object($resource)) $nodes[] = $result->nid;
pathauto_node_operations_update($nodes);
foreach ($nodes as $nid) print "\n $nid";
print "\n Completed aliasing set of $limit_count nodes";
unset($nodes);
$start += $limit_count;
if ($start >= $break_at) break;
}'

Creating an auto-refresh page (by setting meta tag) to perform bulk aliasing refreshing itself every 10 seconds Referenced from the drupal.org pathauto bulk generation page

<?php
  include_once './includes/bootstrap.inc';
  include_once './sites/all/modules/pathauto/pathauto.inc';
  include_once './sites/all/modules/pathauto/pathauto_node.inc';    
  drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
?>

<html>

<head>
<meta http-equiv="refresh" content="10">
</head>

<body>
Created new URL aliases at <strong><?php print date('r') ?></strong> :: Restarting in 10 seconds ...
</body>

</html>
<?php
  variable_set('pathauto_max_bulk_update', 1000); // Or how many nodes you think you have :)
  variable_set('pathauto_transliterate', TRUE);
  node_pathauto_bulkupdate();
?>

While in my case the alias update was for approximately 100k nodes with some complex tokens created with my custom module (which resulted in a lot of tears) the drush method turned out to be extremely slow, while the meta tag method running in prolonged period appeared to choke the server.

Another method which seemed to work to a certain extent in a better manner was using Drupal's Batch API.

Sample Batch API code to update all published MY_NODE_TYPE nodes

/**
 * Callback function for regenerating MY_NODE_TYPE alias batch job
 */
function regenerate_MY_NODE_TYPE_alias_form() {
  $form = array();
  $form['#submit'][] = 'regenerate_MY_NODE_TYPE_alias_form_submit';
  $confirmation_question = 'Are you sure you wish to regenerate the alias of all MY_NODE_TYPE nodes?';
  return confirm_form($form, $confirmation_question, $path = 'admin', $description = NULL, $yes = "Confirm and Regenerate MY_NODE_TYPE Node alias", $no = "Cancel", $name = 'confirm_regeneration');
}

/**
 * form submit function for MY_NODE_TYPE alias generation batch job
 *
 * @see regenerate_MY_NODE_TYPE_alias_form()
 */
function regenerate_MY_NODE_TYPE_alias_form_submit() {
  $batch = array(
    'init_message' => t('Regeneration of MY_NODE_TYPE alias in progress'),
    'operations' => array(),
    'finished' => '_regenerate_MY_NODE_TYPE_node_alias_complete',
    'error_message' => t('MY_NODE_TYPE alias Batch has encountered an error.'),
    'title' => t('Rebuilding MY_NODE_TYPE alias'),
  );
  $batch['operations'][] = array('_regenerate_MY_NODE_TYPE_node_alias', array());
  watchdog("form_submit", "MY_NODE_TYPE alias batch array initialized, before calling batch_set");
  batch_set($batch);
}

/**
 * Function responsible for regeneration of MY_NODE_TYPE nodes' titles
 */
function _regenerate_MY_NODE_TYPE_node_alias(array &$context) {
  if (!isset($context['sandbox']['progress'])) {
    $context['results'][] = '';
    $context['sandbox']['progress'] = 0;
    $context['sandbox']['start_value'] = 0;
    // select all published MY_NODE_TYPE nodes
    $context['sandbox']['max'] = db_result(db_query("SELECT COUNT(nid) FROM {node} WHERE `type` = '%s' AND `status` = 1", 'MY_NODE_TYPE'));
    watchdog("Alias max_value", "Alias Batch maximum value set " . $context['sandbox']['max']);
  }
  watchdog("alias regeneration", "Current progress value is " . $context['sandbox']['progress']);
  $fetch_limit = 100;
  $nid_rs = db_query_range("SELECT `nid` FROM {node} WHERE `type` = '%s' AND `status` = %d", $args = array('MY_NODE_TYPE', 1), $from = $context['sandbox']['progress'], $fetch_limit);

  while ($MY_NODE_TYPE_nid_arr = db_fetch_array($nid_rs)) {
    $context['results'][] = $MY_NODE_TYPE_nid_arr['nid'];
    $MY_NODE_TYPE_nodes[] = $MY_NODE_TYPE_nid_arr['nid'];
  }
  // call pathauto mass update method with the array of nodes retrieved
  pathauto_node_operations_update($MY_NODE_TYPE_nodes);
  $context['sandbox']['progress'] += 100;
  $context['message'] = t("Now processing node %nid. (%progress of %total)", array('%nid' => $MY_NODE_TYPE_nid_arr['nid'], '%progress' => $context['sandbox']['progress'], '%total' => $context['sandbox']['max']));
  if ($context['sandbox']['progress'] >= $context['sandbox']['max']) {
    $context['finished'] = 1;
  }
  else {
    $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
  }
}

/**
 * @function success handler for MY_NODE_TYPE alias generation
 */
function _regenerate_MY_NODE_TYPE_node_alias_complete($success, $results, $operations) {
  drupal_set_message("Completed batch operation");
  if ($success) {
    $message = count($results) . ' MY_NODE_TYPEs processed.';
    // $message .= theme('item_list', $results);  // lists all nodes that were processed
    drupal_set_message($message);
  }
  else {
    $error_operation = reset($operations);
    $message = t('An error occurred while processing %error_operation with arguments: @arguments', array('%error_operation' => $error_operation[0], '@arguments' => print_r($error_operation[1], TRUE)));
    watchdog('alias batch_error', $message);
    drupal_set_message($message, 'error');
  }
}

@Aiias 2013-03-09 11:08:11

One approach for solving this would be to add an update script, see hook_update_n(), to one of your custom modules and then execute it at update.php.

Within the update script, you could run an update query like

$ret = array();
$ret[] = update_sql("UPDATE {url_alias} a LEFT JOIN {node} n ON a.src = CONCAT('node/'. n.nid) SET a.dst = CONCAT('photo/', n.nid) WHERE n.type = 'image'");
return $ret;

This would update all existing URL aliases of nodes of type 'image'. I have not tested this query, so you should test it or confirm it locally before deploying it.

@Sidney Gijzen 2013-03-09 10:58:04

I think you can just use Pathauto for that. Rename the URL pattern and use the Bulk update function to regenerate all aliases. You can also do this through the content overview screen (/admin/content) by filtering out the content type "image", select all and choose "Update URL alias" from the drop down menu.

Related Questions

Sponsored Content

1 Answered Questions

[SOLVED] Drupal 8 - Pathauto taxonomy terms in content paths

  • 2019-03-04 21:02:07
  • Stan
  • 108 View
  • 1 Score
  • 1 Answer
  • Tags:   8 path-aliases

3 Answered Questions

[SOLVED] Update url-aliase for nodes of a specific content type

  • 2015-01-09 14:07:58
  • sgoelz
  • 1575 View
  • 1 Score
  • 3 Answer
  • Tags:   7 path-aliases

3 Answered Questions

[SOLVED] how to block internal Drupal paths for anonymous users?

  • 2013-10-30 18:01:24
  • camcam
  • 699 View
  • 0 Score
  • 3 Answer
  • Tags:   7 path-aliases

3 Answered Questions

[SOLVED] Auto URL Aliasing for Custom Menu Paths with Term Id

2 Answered Questions

1 Answered Questions

How to create views with date field of a content type?

  • 2014-01-04 08:09:20
  • Surendra Prasad
  • 84 View
  • 0 Score
  • 1 Answer
  • Tags:   views 6

1 Answered Questions

[SOLVED] Node paths with custom prefix based on taxonomy

1 Answered Questions

[SOLVED] Module to allow multiple paths for a single node?

  • 2012-03-13 14:10:03
  • EmmyS
  • 1524 View
  • 2 Score
  • 1 Answer
  • Tags:   6 path-aliases uri

1 Answered Questions

[SOLVED] Is there a way to have two aliases to a user's profile page?

  • 2011-09-08 21:08:01
  • gmercer
  • 103 View
  • 0 Score
  • 1 Answer
  • Tags:   path-aliases

1 Answered Questions

[SOLVED] is using non English words for paths recommended?

  • 2011-07-19 16:13:07
  • Nick.h
  • 210 View
  • 1 Score
  • 1 Answer
  • Tags:   7 path-aliases

Sponsored Content