Есть ли способ перехватить список NID, созданных представлением, и использовать их в качестве фильтра для другого представления?


8

Я нахожусь в точке опыта Drupal, где я пытаюсь решить проблемы дизайна сайта на уровне пользовательского кода, используя Drupal и Views API. Как обычно, моя внешне простая попытка решить проблему показала мне, насколько я еще не знаю!

У меня есть поле ссылки на узел, которое указывает на контент «связанных фактов», используемый многими различными типами контента и подкатегориями для каждого из этих типов. Хотя я могу создавать отношения и отображать «связанные факты» для представления, существуют проблемы. Во-первых, я хочу, чтобы связанные факты были помещены в отдельный блок и отображать единый список связанных фактов для всего списка статей, представленных представлением. Views не обрабатывает дубликаты для нескольких nids с одинаковыми ссылками «связанные факты». Кроме того, мне пришлось бы создавать отдельные представления «связанных фактов» для каждого типа контента и подкатегории, которых будет довольно много.

Если бы я мог создать отдельное представление связанных фактов, которое может принимать список nids в качестве аргумента, представление связанных фактов могло бы быть упрощено. Итак, мой вопрос, как это сделать. Хотя это может быть возможно из представлений, я ищу нестандартное решение php модуля , поэтому мне нужно добиться следующего:

  1. Извлеките результаты любого из представлений типа контента в виде списка аргументов. Помимо отображения результатов просмотра, мне нужно загрузить список отображаемых NID.

  2. Вызовите представление связанных фактов и передайте ему список nids для использования в качестве фильтра или контекстного фильтра в представлении «связанные факты».

Дополнительная информация:

Используя эту стратегию, я начал с определения представления и попытался извлечь из него результаты. Эта попытка привела к проблеме с поиском результатов в объекте просмотра ( см. Этот вопрос ). Как только я получу результаты, мне нужно будет сгенерировать другое представление, которое будет использовать эти результаты в качестве фильтров. Я видел представления, реализованные из кода, как включающие файлы, в которых закодированы все параметры, но я не нашел примеров, которые определяют и генерируют представление и манипулируют результатами, используя функцию 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)

Используя код в ответе Летариона, цикл foreach в строке 6 формирует список идентификаторов статей, а не идентификаторов связанных фактов (статьи содержат ссылку на связанные факты, но связанные факты не имеют ссылки на статьи в узлах) , Мне нужно извлечь идентификаторы связанных фактов из поля фактов в каждом узле. Я включил поле фактов в определение 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));
  }

Наконец, я не уверен, должен ли я направлять отображение представления в правильное местоположение, или это делается просто путем размещения соответствующей панели содержимого фактов в расположении панели через интерфейс панели и позволяя тематике панелей обрабатывать остальное.


2
Это Drupal 7? Если это так, я бы рекомендовал использовать EntityFieldQuery для получения списка узлов, отвечающих вашим критериям.
Beth

Можете ли вы указать на пример кода, где используется этот API. Я новичок в мире кодирования Drupal и должен следовать примеру типа реального мира, чтобы разобраться.
Ашлар

drupal.org/node/1343708 - это страница под названием «Как использовать EntityFieldQueries».
Beth

Ответы:


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:

Добавьте тип отображения «context» в get_nids и передайте этот контекст в качестве аргумента для отображения панели содержимого get_related. К сожалению, я должен был бы предположить, что контексты Views не поддерживают сжатие нескольких результатов в один контекст, поэтому может потребоваться запрос функции в Ctools.

Вариант 3:

У Бет есть отличное предложение в комментарии, в котором используется EntityFieldQuery , когда вам нужно решение с чистым кодом, которое также будет работать с MongoDB . Преимущество представлений заключается в том, что большую часть работы можно выполнять в пользовательском интерфейсе, что часто бывает удобно.


После кода в views_db_object для метода -> execute (Views.inc строка 1060). Я не вижу ничего в коде метода, который читает аргумент (массив ($ nid)). Кроме того, как мне настроить представление 'get_related' для приема значений фильтра в аргументе массива ($ nids)? Нужно ли устанавливать фильтры на «связанный контент» и контекстные фильтры для принятия NID?
Ашлар

Извините, вы абсолютно правы, что должно было быть execute_display , добавлена ​​информация о контекстном фильтре для ответа. :)
Летарион

Я добавил больше информации, чтобы закончить проблему отображения содержания соответствующих фактов в вопросе. Пожалуйста, смотрите "Пока".
Ашлар

Извините, я не понимаю, где проблема. Согласно вашему сообщению, поле ссылки на узел является общим для ваших типов контента, и, таким образом, представление 'get_nids' соберет все ссылочные объекты. Если нет, однако, нужно было бы цикл по первому виду.
Летарион

1
Хм! Я думаю, что я был сбит с толку и, возможно, делаю это более сложным, чем нужно. Спасибо
Ashlar

2

Поиск полей в узле и возврат списка NID - это именно то, для чего был создан EntityFieldQueries . (Смотрите также: мой собственный вопрос по теме ).

Пример из моего кода, который запускается при отправке веб-формы и в котором я ищу узлы типа «Quiz Anzwer Key», чтобы найти один (ие) с полем «Ссылка на викторину», заполненный 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 в виде списка, ограниченного запятыми, вы можете сделать это, используя поля в качестве выходных данных и установив в качестве настроек стиля значение «Неформатированный», поля стиля строки -> сделать поле 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.
        }
    }
}

Должен ли это быть отдельный ответ? или редактировать ??


Я ищу кодовые решения. Я уточню вопрос.
Ашлар

Пожалуйста, исправьте меня, если я ошибаюсь, но, насколько я могу судить, это даже не решит проблему, так как Ашлар пытается получить данные из нескольких отношений одновременно, в то время как вложения будут только "текущими" один? (Прошло некоторое время с тех пор, как я использовал вложения, поэтому я мог ошибаться)
Летарион,

Спасибо за ваши усилия. Я добавил больше информации, чтобы закончить проблему отображения содержания соответствующих фактов в вопросе. Пожалуйста, смотрите "Пока".
Ашлар
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.