Drupal:如何以编程方式为已在节点保存上具有别名的节点创建URL别名?

时间:2011-01-26 22:54:31

标签: drupal

我有一个自定义模块,它实现了hook nodeapi,以便在创建或更新节点时执行某些代码。

基本上我想根据节点保存或更新时自动生成的别名创建别名。

现在我正在使用对path_set_alias的调用,我只想用特定类型的内容“product”来做这件事。

这是我的nodeapi电话,让我开始

function product_url_helper_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {

 if($node->type == 'product'){
  switch($op){

     case 'insert':
      _create_alternate_url($node);

     break;

     case 'update':
      _create_alternate_url($node);
     break;

     case 'view':
       //do nothing
     break;

  default:
  break;

  }
 }

 return;
}

然后我有了这个函数,我正试图为我保存第二个URL别名。

function _create_alternate_url($node){
$aliasExists = db_fetch_object(db_query("SELECT count(dst) as total FROM {url_alias} WHERE dst = 'alternate/".$node->path."'"));
if($aliasExists->total == 0){

    $product_url = $node->path;
 $alternate_url = "alt/" . $node->path;
 $default_node_path = "node/" . $node->nid;

    path_set_alias($default_node_path, $alternate_url, 0, '');

  drupal_set_message("Created Alternate path for Product: " . $node->title . " <br/> Path <a href='/" . $default_node_path ."'>" . $default_node_path . "</a> is now aliased by <a href='/" . $alternate_url . "'>". $alternate_url ."</a>");
 }

虽然这不会设置别名,但它只是创建了产品原始别名的副本。所以,如果我开始使用我的产品“绿蕨”。我会保存它,它会使用pathauto生成产品/ green-fern然后调用我的模块代码并创建一个别名“alt / products / green-fern”并仍然让它指向“node / nid”路径

但是,当我运行此代码时,会在数据库中创建副本。所以我保存了Green Fern一次,突然间我在数据库的url_alias末尾看到两个重复的记录。 “产品/绿色蕨类植物”和“产品/绿色蕨类植物”

我觉得我正以一种过于复杂的方式思考这个问题。我的客户知道他们在为同一节点制作多个别名时获得的搜索引擎优化命中,他们只是希望它能够做到这一点。 HALP!

4 个答案:

答案 0 :(得分:5)

JR,改进你在Drupal7中的代码,db_querys很贵。更好的方法是使用lookup_path drupal函数:

$urlAlias = drupal_lookup_path('alias',"node/".$node->nid . '/prices');

如果urlAlias没有值,那么此url没有别名,所以我们可以安全地创建它:

if( urlAlias == '' )
path_set_alias($default_node_path, $alternate_url, 0, '');

答案 1 :(得分:2)

Pathauto正在检测节点的重复别名,并使用默认内容类型模式覆盖自定义别名。默认情况下,pathauto将创建一个新别名,并在执行更新操作时删除旧别名。

如果您在管理界面/admin/config/search/path/settings上将“更新操作”选项切换为“创建新别名。保持现有别名正常运行”,则不会覆盖自定义别名。

答案 2 :(得分:1)

很难说出你喜欢别名的复杂程度,但pathauto模块似乎是解决问题的简单方法。它允许您根据令牌自动生成别名。

作为奖励,它可以很好地放置path_redirect模块,该模块将在重复的别名上设置303重定向(或您想要的任何重定向)。这会在一定程度上缓解您的搜索引擎优化问题。

编辑:

您是否确定未经编辑的代码正确调用函数? path_set_alias的相关部分是:

  if ($pid) {
    // An existing alias.
    // *** You set pid to 0, so this doesn't fire ***
  }
  else if ($path && $alias) {
    // Check for existing aliases.
    if ($alias == drupal_get_path_alias($path, $language)) {
      // There is already such an alias, neutral or in this language.
      // Update the alias based on alias; setting the language if not yet done.
      db_query("UPDATE {url_alias} SET src = '%s', dst = '%s', language = '%s' WHERE dst = '%s'", $path, $alias, $language, $alias);
    }
    else {
      // A new alias. Add it to the database.
      // *** If your code is correct, this is the part that should fire. ***
      db_query("INSERT INTO {url_alias} (src, dst, language) VALUES ('%s', '%s', '%s')", $path, $alias, $language);
    }
  }

如果您正在使用测试网站,您还可以尝试在dpm()的{​​{1}}之前删除一些db_query,以找出代码的哪些部分实际解雇,以及进入他们的数据。

答案 3 :(得分:0)

您在代码中明确将pid设置为0。我想这个代码运行的第二个节点会返回一个错误。尝试在path_set_alias()来电中将0更改为NULL。