Existe uma maneira de interceptar uma lista de NIDs criados por uma visualização e usá-los como um filtro para outra visualização?

8

Estou no ponto da experiência do Drupal em que estou tentando resolver os desafios de design do site no nível do código personalizado usando as APIs do Drupal e do Views. Como sempre, minha tentativa aparentemente simples de resolver um problema me demonstrou o quanto ainda não sei!

Eu tenho um campo de referência de nó que aponta para um conteúdo de "fatos relacionados" usado por muitos tipos e subcategorias de conteúdo diferentes para cada um desses tipos. Embora eu possa criar um relacionamento e exibir os "fatos relacionados" para uma visão, há problemas. Por um lado, quero que os fatos relacionados sejam colocados em um bloco separado e para exibir uma única lista de fatos relacionados para toda a lista de artigos fornecidos pela exibição. O Views não processa duplicatas para vários nids com a mesma referência de 'fatos relacionados'. Além disso, eu precisaria gerar visualizações separadas de 'fatos relacionados' para cada tipo e subcategoria de conteúdo, o que será um número bastante grande.

Se eu pudesse criar uma visão de fatos relacionados separada que pudesse aceitar uma lista de nids como argumento, a visão de fatos relacionados poderia ser simplificada. Então, minha pergunta é como fazer isso. Embora possa ser possível a partir de visualizações, estou procurando uma solução php de módulo personalizado , por isso, preciso obter o seguinte:

  1. Extraia os resultados de qualquer uma das visualizações 'tipo de conteúdo' como uma lista de argumentos. Além de exibir os resultados da exibição, preciso carregar a lista de NIDs que estão sendo exibidos.

  2. Chame a visualização de fatos relacionados e passe a lista de nids para usar como filtro ou filtro contextual na visualização de 'fatos relacionados'.

Informação adicional:

Usando essa estratégia, comecei definindo uma visão e tentando extrair os resultados dela. Essa tentativa levou a um problema ao encontrar os resultados no objeto de exibição ( consulte esta pergunta ). Depois de obter os resultados, precisarei gerar outra visualização que tenha esses resultados como filtros. Eu vi visualizações implementadas a partir do código como arquivos de inclusão, onde todos os parâmetros são codificados, mas não encontrei exemplos que definam e gerem uma exibição e manipulem os resultados usando uma função php. Quaisquer exemplos ou links serão apreciados.

Até agora:

Duas respostas abordaram o processo para aplicar os resultados de uma visualização e colocá-lo em outra visualização como um filtro contextual. Mas ainda enfrento o problema de ter dezenas de tipos de conteúdo com pelo menos uma dúzia de variações no painel de conteúdo de exibição em cada um. Em vez de vincular diretamente cada exibição aos fatos relacionados, precisarei que qualquer uma das minhas exibições de conteúdo da view1 passe seus resultados para uma única exibição separada de 'fato relacionado'.

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... 

A View1 localiza um tipo de conteúdo específico e contém vários artigos de subcategoria classificados pelo valor em um campo de subcategoria. Além disso, ele contém um campo de referência de nó para fatos relacionados. Visualize um filtro para um tipo de conteúdo e uma subcategoria e tenha campos expostos para exibição e um campo oculto com os nós de referência de fatos relacionados.

A View2 filtra artigos de "fatos relacionados" e contém um filtro contextual definido para nid (embora a configuração se aplique ao URL)

Usando o código na resposta de Letharion, o loop foreach na linha 6 está compilando uma lista dos IDs do artigo, não dos IDs dos fatos relacionados (os artigos mantêm uma referência a fatos relacionados, mas os fatos relacionados não têm uma referência de nó aos artigos) . Preciso extrair os IDs de fatos relacionados do campo de fatos em cada nó. Eu incluí o campo de fatos na definição View1, mas não consigo encontrar o resultado desde o comando dpm ($ node); está travando e não sei onde os valores estão armazenados na matriz.

Como haverá mais de um View1 clonado para diferentes tipos de conteúdo, pensei que faria sentido usar hook_views_post_execute e o codifiquei da seguinte maneira:

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));
  }

Por fim, não tenho certeza se preciso direcionar a exibição da exibição para o local adequado ou isso é feito simplesmente colocando o painel de conteúdo de fatos relacionados no local do painel por meio da interface do usuário de painéis e deixe que os temas dos painéis lidem com o resto.

Ashlar
fonte
2
É esta Drupal 7? Nesse caso, recomendo usar o EntityFieldQuery para recuperar uma lista de nós que atendem aos seus critérios.
beth
Você pode apontar para algum código de exemplo em que essa API é usada. Eu sou novo no mundo da codificação Drupal e preciso seguir um exemplo do tipo mundo real para descobrir as coisas.
Ashlar
drupal.org/node/1343708 é uma página chamada "Como usar o EntityFieldQueries".
beth

Respostas:

3

Apenas fora do topo da minha cabeça

Com as visualizações 'get_nids' e 'get_related', get_related usando um nidargumento, definido para aceitar vários valores. Esta opção está oculta em "mais", na parte inferior da janela de configuração.

Opção 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();

Opção 2:

Adicione um tipo de exibição "contexto" a get_nids e passe esse contexto como argumento para uma exibição no painel de conteúdo de get_related. Infelizmente, eu teria que adivinhar que os contextos do Views não têm suporte para compactar vários resultados em um único contexto, o que pode exigir uma solicitação de recurso no Ctools.

Opção 3:

Beth tem uma excelente sugestão em um comentário, que está usando EntityFieldQuery , para quando você quiser uma solução de código puro, que também funcione com o MongoDB . No entanto, as visualizações têm a vantagem de que a maior parte do trabalho pode ser feita em uma interface do usuário, o que geralmente é conveniente.

Letharion
fonte
Seguindo o código em views_db_object para o método -> execute (Views.inc linha 1060). Não vejo nada no código do método que leia o argumento (array ($ nid)). Além disso, como configurar a visualização 'get_related' para aceitar os valores de filtro no argumento array ($ nids)? Defino filtros para 'conteúdo relacionado' e filtros contextuais para aceitar NIDs?
quer
Desculpe, você está absolutamente certo, que deveria ter sido execute_display , adicionado informações sobre o filtro contextual para responder. :)
Letharion
Adicionei mais informações para concluir a questão da exibição do conteúdo dos fatos relacionados na pergunta. Por favor, veja "Até agora".
Ashlar
Desculpe, não entendo onde está o problema. De acordo com a sua postagem, o campo de referência do nó é compartilhado entre seus tipos de conteúdo e, como tal, a exibição 'get_nids' reunirá todas as entidades referidas. Caso contrário, seria necessário um loop sobre a primeira visualização.
Letharion
11
Hmm! Acho que fiquei confuso e pode estar tornando isso mais complicado do que precisa ser. Obrigado
Ashlar
2

Procurar campos em um nó e retornar uma lista de NIDs é exatamente o que o EntityFieldQueries nasceu para fazer. (Veja também: minha própria pergunta sobre o assunto ).

Um exemplo do meu código, que é executado após o envio do formulário da web, e no qual procuro nós do tipo "Chave Anzwer do questionário" para encontrar aquele (s) com o campo "Referência do questionário" preenchido com o NID do formulário da web atualmente em validação :

    $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

Então, se você deseja realmente carregar valores dos campos nos nós, use node_loadpara obter mais informações dos nós que deseja, da seguinte forma:

    $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 

Agora $ans_nodeé uma matriz (ou objeto, eu esqueço) que contém todas as informações em todos os campos do nó. Voilá!

beth
fonte
0

Ok, uma solução codificada (há poucas), mas aqui está uma:

  1. Crie uma exibição que obtenha todas as saídas do nid como uma lista de demarcada por vírgula; você pode fazer isso usando campos como saída e definindo suas configurações de estilo como Estilo não-avançado, campos de estilo de linha -> torne o campo nid inline e use uma vírgula como separador.
  2. No seu módulo, crie uma função que chama essa visualização e obtenha a saída
  3. Crie sua segunda visualização (ou exibição), use esta função como um argumento em sua segunda exibição que realmente produz a saída de exibição. Portanto, sob argumentos, o argumento deve ser o nó: nid, a Ação a ser executada deve ser definida como "fornecer padrão" e você então use a configuração de código PHP para chamar sua função: return mymodule_get_nids (); verifique se a caixa de seleção "permitir vários termos por argumento" está marcada

Código da etapa 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.
        }
    }
}

Esta deveria ser uma resposta separada? ou uma edição ??

Andre
fonte
Eu estou procurando soluções codificadas. Vou esclarecer a questão.
Ashlar
Por favor, corrija-me se estiver errado, mas até onde eu sei, isso nem resolveria o problema, pois Ashlar procura extrair dados de vários relacionamentos ao mesmo tempo, enquanto os anexos serão apenas os "atuais" 1? (Foi um tempo desde que fiz uso de anexos, porém, para que eu pudesse estar errado)
Letharion
Obrigado pelo seu esforço. Adicionei mais informações para concluir a questão da exibição do conteúdo dos fatos relacionados na pergunta. Por favor, veja "Até agora".
Ashlar