我正在尝试使用函数views_get_view_result()
获取视图的结果 - 并以一种我在Views界面中无法做到的方式对数组进行排序。到现在为止还挺好。我有一个$ rows变量,包含我需要的所有东西。
现在......我怎么把它还掉? :)在我需要这种之前,我使用了views_embed_view()
,但我不能再这样做了。
感谢你对此的任何帮助,感觉我已经接近破解了!
$important_var = important_function();
$result = views_get_view_result($view, $display, $args);
$result = sorting_function($result, $important_var);
//TODO: Put the result back into the view
答案 0 :(得分:18)
视图模块provides some hooks用于“外部”操作,就像Drupal核心一样。
您可以在自定义模块中实施hook_views_pre_render(&$view)
并操纵$view->result
中可用的结果数组:
/**
* Implementation of hook_views_pre_render()
*
* @param view $view
*/
function YourModuleName_views_pre_render(&$view) {
// Check if this is the view and display you want to manipulate
// NOTE: Adjust/Remove the display check, if you want to manipulate some/all displays of the view
if ('YourViewName' == $view->name && 'YourDisplayName' == $view->current_display) {
// EXAMPLE: Just reverse result order
// TODO: Replace with your desired (re)ordering logic
$view->result = array_reverse($view->result);
}
}
在视图生成过程的中间调用钩子,在组装完所有结果数据之后,但在实际输出被渲染之前,结果数组的更改将反映在视图最终输出中。
编辑:或者,您可以通过复制views_get_view_result()
函数的行为来“手动”处理视图,但不是返回结果,而是操纵它并继续渲染观点:
function yourModule_get_custom_sorted_view($display_id = NULL) {
// As the custom sorting probably only works for a specific view,
// we 'demote' the former $name function parameter of 'views_get_view_result()'
// and set it within the function:
$name = 'yourViewName';
// Prepare a default output in case the view definition can not be found
// TODO: Decide what to return in that case (using empty string for now)
$output = '';
// Then we create the result just as 'views_get_view_result()' would do it:
$args = func_get_args();
if (count($args)) {
array_shift($args); // remove $display_id
}
$view = views_get_view($name);
if (is_object($view)) {
if (is_array($args)) {
$view->set_arguments($args);
}
if (is_string($display_id)) {
$view->set_display($display_id);
}
else {
$view->init_display();
}
$view->pre_execute();
$view->execute();
// 'views_get_view_result()' would just return $view->result here,
// but we need to go on, reordering the result:
$important_var = important_function();
$view->result = sorting_function($result, $important_var);
// Now we continue the view processing and generate the rendered output
// NOTE: $view->render will call $view->execute again,
// but the execute method will detect that it ran already and not redo it.
$output = $view->render();
// Clean up after processing
$view->post_execute();
}
return $output;
}
注意:这是很多代码重复,因而容易出错 - 我不建议这样做,宁愿选择上面的钩子实现,试图找到一种方法来访问你的' $ important_var'来自那个。
答案 1 :(得分:10)
根据您的排序逻辑,您可能尝试使用hook_views_query_alter()直接在查询中实现排序。
这可能有点棘手,您可以熟悉views_query对象。
这是一个真实的例子,我根据页面的上下文应用了一个连接规则,然后另外添加了排序规则。
/**
* Implementation of hook_views_query_alter().
*/
function yourmodule_views_query_alter(&$view, &$query) {
if ($view->name == 'view_projects' && $view->current_display == 'panel_pane_4') {
if (arg(0) == 'node' && is_numeric(arg(1))) {
$node = node_load(arg(1));
if ($client_nid = $node->field_ref_client[0]['nid']) {
$query->table_queue['node_node_data_field_ref_client']['join']->extra = "field_ref_client_nid = " . $client_nid;
$query->add_orderby('node', NULL, 'DESC', 'node_node_data_field_ref_client_nid');
$query->add_orderby('node', 'created', 'DESC');
}
}
}
}
请参阅:http://drupalcontrib.org/api/function/hook_views_query_alter/6
答案 2 :(得分:3)
我使用这样的代码:
/**
* Implementation of hook_views_post_execute()
*
* @param view $view
*/
function YourModuleName_views_post_execute(&$view) {
// Check if this is the view and display you want to manipulate
// NOTE: Adjust/Remove the display check, if you want to manipulate some/all displays of the view
if ('YourViewName' == $view->name && 'YourDisplayName' == $view->current_display) {
// EXAMPLE: Just reverse result order
// TODO: Replace with your desired (re)ordering logic
$view->result = array_reverse($view->result);
}
}
hook_views_pre_render对我不起作用。
答案 3 :(得分:0)
我结合上面的例子并重写如下。在我的情况下,我不得不单独对项目进行排序。
注意:我没有包含加入条件,我没有尝试使用自定义字段。但我觉得你很容易弄明白。
/**
* Implementation of hook_views_query_alter().
*/
function yourmodule_views_query_alter(&$view, &$query) {
if ($view->name == 'your_view_name' && $view->current_display == 'your_pane_name') {
if ($query->orderby[0]['field'] == 'my_order_field') {
$query->orderby[0]['field'] = "FIELD(my_order_field, 'ord3','ord1','ord2')";
}
}
}