【问题标题】:Drupal: How do I programatically create a URL alias for a node that already has an alias on node save?Drupal:如何以编程方式为节点保存时已具有别名的节点创建 URL 别名?
【发布时间】:2011-01-26 22:54:31
【问题描述】:

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

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

现在我正在使用对 path_set_alias 的调用,我只想对特定类型的内容“产品”执行此操作。

这是我的 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 生成 products/green-fern 然后在调用我的模块代码并创建别名“alt/products/green-fern”并仍然让它指向“node/nid”路径.

但是,当我运行此代码时,会在数据库中创建一个副本。所以我保存了一次 Green Fern,突然我在数据库中的 url_alias 末尾看到了两条重复的记录。 "products/green-fern" 和 "products/green-fern"

我觉得我正在以一种过于复杂的方式思考这个问题。我的客户知道他们在将多个别名指向同一个节点时获得的 SEO 命中,他们只是希望它这样做。哈!

【问题讨论】:

    标签: drupal


    【解决方案1】:

    JR,在 Drupal7 中改进您的代码,db_query 很昂贵。更好的方法是使用 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, '');
    

    【讨论】:

    • 顺便说一下,在drupal7中我们应该用path_save($args = array("source" => $non_alias_path, "alias" => $new_aliased_url);)来改变path_set_alias
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      作为奖励,它可以很好地与 path_redirect 模块配合使用,该模块将在重复别名上设置 303 重定向(或您想要的任何重定向)。这将在一定程度上减轻您对 SEO 的担忧。

      编辑:

      您是否超级确定您的未编辑代码正确调用了函数? 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);
          }
        }
      

      如果您在测试站点上工作,您也可以尝试在 node.module 中的 db_querys 之前删除一些 dpm()s,以找出代码的哪些部分实际触发,以及哪些数据是进入他们。

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-08-02
          • 2017-10-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多