有没有办法拦截一个视图创建的NID列表并将其用作另一个视图的过滤器?


8

在Drupal经验方面,我正尝试使用Drupal和Views API在自定义代码级别解决站点设计难题。像往常一样,我看似简单的解决问题的尝试向我展示了我还不知道的多少!

我有一个节点引用字段,它指向由许多不同的内容类型和这些类型的子类别使用的“相关事实”内容。虽然我可以创建关系并显示视图的“相关事实”,但是仍然存在问题。首先,我希望将相关事实放在一个单独的块中,并为视图提供的整个文章列表显示一个相关事实的列表。对于具有相同“相关事实”参考的多个对象,视图不会处理任何重复项。另外,我将不得不为每种内容类型和子类别分别生成大量的“相关事实”视图。

如果我可以创建一个单独的相关事实视图,该视图可以接受一组nids作为参数,那么可以简化相关事实视图。所以我的问题是如何解决这个问题。虽然从内部来看可能是可行的,但我正在寻求一个自定义模块php解决方案,因此我需要实现以下目标:

  1. 提取任何“内容类型”视图的结果作为参数列表。除了显示查看结果之外,我还需要加载正在显示的NID列表。

  2. 调用相关事实视图,并将其列表传递给它,以用作“相关事实”视图中的过滤器或上下文过滤器。

附加信息:

使用这种策略,我首先定义了一个视图,然后尝试从中提取结果。这种尝试导致在视图对象中查找结果时出现问题(请参阅此问题)。获得结果后,我将需要生成另一个视图,以这些结果作为过滤器。我已经看到从代码实现的视图是包含所有参数都已编码的包含文件的视图,但是没有找到定义和生成视图并使用php函数处理结果的示例。任何示例或链接将不胜感激。

迄今:

有两个答案解决了应用视图结果并将其作为上下文过滤器放置在另一个视图中的过程。但是我仍然面临这样的问题,即拥有数十种内容类型,每种类型中至少包含十二种视图内容窗格变体。除了将每个视图直接链接到相关事实之外,我将需要让我的任何view1内容视图将其结果传递给一个单独的“相关事实”视图。

CONTENT TYPE    SUB-CATEGORY       RELATED FACT (nid)
    Type 1 --------- General Info       101, 105 
                     Specifications     103, 105
                     Inspections        102 
                     Quality  
                     etc...   
   Type 2 ----------General Info       101, 106
                    Specifications     102, 103 
                    Cost factors       107
                    etc... 

View1查找特定的内容类型,并包含各种子类别文章,这些文章按子类别字段中的值排序。另外,它包含有关相关事实的节点参考字段。查看一个用于内容类型和子类别的过滤器,并具有用于显示的暴露字段和具有相关事实引用节点的隐藏字段。

View2过滤“相关事实”文章,并包含针对nid的上下文过滤器设置(尽管该设置适用于URL)

使用Letharion的答案中的代码,第6行中的foreach循环正在编译商品ID的列表,而不是相关事实ID的列表(这些商品引用了相关事实,但是相关事实没有对商品的节点引用) 。我需要从每个节点的事实字段中提取相关的事实ID。我已经将事实字段包括在View1定义中,但是由于命令dpm($ node);找不到结果。已经崩溃了,我不知道值在数组中的存储位置。

由于将为不同的内容类型克隆多个View1,所以我认为使用hook_views_post_execute并对其进行如下编码可能是有意义的:

function mymodule_views_post_execute (&$sourceview) {

  $nids = '';
  foreach($sourceview->result as $node) {
    $nids += $node->nid . ',';  //I need field name for $node->facts

  }

  $nids = rtrim($nids, ',');
  $view = views_get_view('get_related');

  //dpm($nids);  // Fatal error: Cannot unset string offsets...

  $view->execute_display('panel_pane_1', array($nids));
  }

最后,我不确定是否必须将视图的显示定向到正确的位置,还是通过将相关的事实内容窗格通过面板UI放置在面板位置中,然后让面板主题化处理其余的内容来完成。


2
这是Drupal 7吗?如果是这样,我建议使用EntityFieldQuery检索满足您条件的节点列表。
贝丝2012年

您能否指出一些使用此API的示例代码。我对Drupal编码世界是陌生的,需要遵循一个真实世界类型的示例来解决问题。
Ashlar 2012年

drupal.org/node/1343708是一个名为“如何使用EntityFieldQueries”的页面。
贝丝2012年

Answers:


3

就在我的头顶上

对于视图“ get_nids”和“ get_related”,get_related接受一个nid参数,该参数设置为接受多个值。此选项隐藏在配置窗口底部的“更多”下。

选项1:

$view = views_get_view('get_nids');
// Repeating query, ensure the View is set to cache the results.
$view->preview('display_machine_name', array($arg1, $arg2));

$nids = '';
foreach($view->result as $node) {
  $nids += $node->nid . ',';
}
$nids = rtrim($nids, ',');
$view = views_get_view('get_related');
$view->execute_display('display_machine_name', array($nids));
print $view->render();

选项2:

向get_nids添加“上下文”显示类型,并将该上下文作为参数传递给get_related的内容窗格显示。不幸的是,我不得不猜测Views上下文缺乏将多个结果压缩到单个上下文中的支持,因此可能需要Ctools中的功能请求。

选项3:

Beth在评论中有一个很好的建议,即使用EntityFieldQuery,因为当您需要纯代码解决方案时,也可以与MongoDB一起使用。尽管视图具有以下优点:大多数工作可以在UI中完成,这通常很方便。


遵循views_db_object中-> execute方法的代码(Views.inc第1060行)。我在读取自变量(array($ nid))的方法代码中看不到任何内容。另外,如何配置“ get_related”视图以接受array($ nids)参数中的过滤器值?是否将过滤器设置为“相关内容”和上下文过滤器以接受NID?
Ashlar 2012年

抱歉,您绝对正确,应该是execute_display,添加了有关要回答的上下文过滤器的信息。:)
Letharion 2012年

我添加了更多信息来解决显示问题中相关事实的内容的问题。请参阅“因此远”。
Ashlar 2012年

抱歉,我不明白问题出在哪里。根据您的帖子,节点引用字段在您的内容类型之间共享,因此“ get_nids”视图将收集所有引用的实体。但是,如果不是这样,则需要在第一个视图上循环。
Letharion 2012年

1
嗯!我认为我很困惑,可能会使事情变得比需要的复杂。谢谢
Ashlar 2012年

2

在节点中查找字段并返回NID列表是EntityFieldQueries出生时要做的事情。(另请参见:关于该主题的我自己的问题)。

来自我的代码的一个示例,该示例在提交Webform时运行,在其中查找“ Quiz Anzwer Key”类型的节点,以查找具有“ Quiz Reference”字段的字段,并在其中填充当前正在验证的Webform的NID。 :

    $arg = arg();
    $nid = $arg[1]; //this finds us the NID of the current page
    $query = new EntityFieldQuery;  // this EntityFieldQuery searches through Entities for Nodes that point to the current Webform.
    $result = $query
        ->entityCondition('entity_type', 'node') // find nodes
        ->propertyCondition('status', 1) // that are published
        ->propertyCondition('type', 'quiz_answer_key')  // of type Quiz Answer Key
        ->fieldCondition('field_answer_quiz', 'nid', $nid, '=') // that point to the current node in their Quiz reference field
        ->execute(); // do the query
    $results        = $query->ordered_results; //grab the results

然后,如果要实际从节点中的字段加载值,则可以从所需的节点node_load中获取更多信息,如下所示:

    $ans_key_id     = $results[0]->entity_id;
    $ans_node       = node_load($ans_key_id);       //once the correct node has been identified, load the contents of that node and suss out the answers 

现在$ans_node是一个数组(或对象,我忘记了),其中包含节点中所有字段中的所有信息。瞧!


0

好的,编码解决方案(区域很少),但是这里有一个:

  1. 创建一个获取所有nid输出的视图,将这些nid作为逗号分隔列表,您可以通过使用字段作为输出并将样式设置设置为Style Unfomatted,行样式字段->使nid字段内联并使用来实现以逗号作为分隔符。
  2. 在您的模块中创建一个函数,该函数调用此视图并获取输出
  3. 创建第二个视图(或显示)时,将此函数用作实际执行显示输出的第二个视图中的参数,因此在参数下,参数应为node:nid,应将要执行的操作设置为“提供默认值”,然后然后使用PHP代码设置调用您的函数:return mymodule_get_nids(); 确保选中“允许每个参数使用多个术语”复选框

第2步代码

function mymodule_get_nids() {
    $view = views_get_view('getmynids')) // View name
        $view->set_display('mynids'); // Display name
        $view->execute();
        if ($view->result) {
         return $view->preview(); // Can't remember if this needs to be echo or return try both.
        }
    }
}

这应该是一个单独的答案吗?或编辑??


我正在寻找编码解决方案。我将澄清这个问题。
Ashlar 2012年

如果我错了,请纠正我,但据我所知,这什至无法解决问题,因为Ashlar希望同时从多个关系中提取数据,而附件只会“当前”一?(自从我使用附件以来
已有一段

谢谢你的努力。我添加了更多信息来解决显示问题中相关事实的内容的问题。请参阅“因此远”。
Ashlar 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.