¿Hay alguna manera de interceptar una lista de NID creados por una vista y usarlos como filtro para otra vista?

8

Estoy en el punto de la experiencia de Drupal donde estoy tratando de resolver los desafíos de diseño del sitio a nivel de código personalizado usando las API de Drupal y Views. Como de costumbre, ¡mi intento aparentemente simple de resolver un problema me ha demostrado cuánto aún no sé!

Tengo un campo de referencia de nodo que apunta a un contenido de "hechos relacionados" utilizado por muchos tipos de contenido y subcategorías diferentes para cada uno de estos tipos. Si bien puedo crear una relación y mostrar los "hechos relacionados" para una vista, hay problemas. Por un lado, quiero que los hechos relacionados se coloquen en un bloque separado y que muestren una lista única de hechos relacionados para la lista completa de artículos proporcionados por la vista. Las vistas no manejan ningún duplicado para múltiples nid con la misma referencia de "hechos relacionados". Además, tendría que generar vistas separadas de "hechos relacionados" para cada tipo de contenido y subcategoría, que será un número bastante grande.

Si pudiera crear una vista de hechos relacionados separada que pueda aceptar una lista de nids como argumento, la vista de hechos relacionados podría simplificarse. Entonces mi pregunta es cómo hacer esto. Si bien es posible desde dentro de las vistas, estoy buscando una solución php de módulo personalizado , por lo que necesito lograr lo siguiente:

  1. Extraiga los resultados de cualquiera de las vistas de 'tipo de contenido' como una lista de argumentos. Además de mostrar los resultados de la vista, necesito cargar la lista de NID que se muestran.

  2. Llame a la vista de hechos relacionados y pásele la lista de nid para usar como filtro o filtro contextual en la vista de 'hechos relacionados'.

Información Adicional:

Usando esta estrategia, comencé definiendo una vista e intentando extraer los resultados de ella. Este intento condujo a un problema para encontrar los resultados en el objeto de vista ( vea esta pregunta ). Una vez que obtenga los resultados, tendré que generar otra vista que tenga esos resultados como filtros. He visto vistas implementadas desde el código como archivos de inclusión donde se codifican todos los parámetros, pero no he encontrado ejemplos que definan y generen una vista y manipulen los resultados usando una función php. Cualquier ejemplo o enlace sería apreciado.

Hasta ahora:

Dos respuestas han abordado el proceso para aplicar los resultados de una vista y colocarla en otra vista como filtro contextual. Pero todavía me enfrento al problema de tener docenas de tipos de contenido con al menos una docena de variaciones en el panel de visualización de contenido en cada uno. En lugar de vincular directamente cada vista con los hechos relacionados, necesitaré que cualquiera de mis vistas de contenido view1 pase sus resultados a una sola vista separada de 'hechos relacionados'.

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 encuentra un tipo de contenido específico y contiene varios artículos de subcategoría ordenados por el valor en un campo de subcategoría. Además, contiene un campo de referencia de nodo para hechos relacionados. Vea uno de los filtros para un tipo de contenido y una subcategoría y tiene campos expuestos para mostrar y un campo oculto con los nodos de referencia de hechos relacionados.

View2 filtra los artículos de "hechos relacionados" y contiene un conjunto de filtros contextuales para nid (aunque la configuración se aplica a la URL)

Usando el código en la respuesta de Letharion, el bucle foreach en la línea 6 está compilando una lista de ID de artículos, no los identificadores de hechos relacionados (los artículos contienen una referencia a hechos relacionados, pero los hechos relacionados no tienen una referencia de nodo a artículos) . Necesito extraer los identificadores de hechos relacionados del campo de hechos en cada nodo. He incluido el campo de hechos en la definición de View1, pero no puedo encontrar el resultado desde el comando dpm ($ node); se ha estado bloqueando y no sé dónde se almacenan los valores en la matriz.

Como habrá más de una View1 clonada para diferentes tipos de contenido, pensé que podría tener sentido usar hook_views_post_execute y lo he codificado de la siguiente manera:

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

Finalmente, no estoy seguro de si tengo que dirigir la visualización de la vista a la ubicación adecuada o si esto se hace simplemente colocando el panel de contenido de hechos relacionados en la ubicación del panel a través de la interfaz de usuario de paneles y dejar que los paneles manejen el resto.

Sillar
fuente
2
¿Es este Drupal 7? Si es así, recomendaría usar EntityFieldQuery para recuperar una lista de nodos que cumplan con sus criterios.
beth
¿Puede señalar algún código de ejemplo donde se utiliza esta API? Soy nuevo en el mundo de la codificación Drupal y necesito seguir un ejemplo de tipo del mundo real para resolver las cosas.
Ashlar
drupal.org/node/1343708 es una página llamada "Cómo usar EntityFieldQueries".
beth

Respuestas:

3

Justo al lado de la parte superior de mi cabeza

Con las vistas 'get_nids' y 'get_related', get_related toma un nidargumento, que está configurado para aceptar múltiples valores. Esta opción está oculta en "más", en la parte inferior de la ventana de configuración.

Opción 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();

Opcion 2:

Agregue un tipo de visualización de "contexto" a get_nids y pase ese contexto como argumento a una pantalla de panel de contenido de get_related. Desafortunadamente, tendría que adivinar que los contextos de Vistas carecen de soporte para comprimir múltiples resultados en un solo contexto, por lo que puede requerir una solicitud de función en Ctools.

Opcion 3:

Beth tiene una excelente sugerencia en un comentario, que utiliza EntityFieldQuery , para cuando desee una solución de código puro, que también funcionaría con MongoDB . Sin embargo, las vistas tienen la ventaja de que la mayor parte del trabajo se puede realizar en una interfaz de usuario, lo que a menudo es conveniente.

Letharion
fuente
Siguiendo el código en views_db_object para el método -> execute (Views.inc line 1060). No veo nada en el código del método que lea el argumento (array ($ nid)). Además, ¿cómo configuro la vista 'get_related' para aceptar los valores de filtro en el argumento de matriz ($ nids)? ¿Establezco filtros para 'contenido relacionado' y filtros contextuales para aceptar NID?
Ashlar
Lo sentimos, tienes toda la razón, debería haber sido execute_display , agregando información sobre el filtro contextual para responder. :)
Letharion
Agregué más información para terminar el tema de mostrar el contenido de los hechos relacionados en la pregunta. Por favor vea "Hasta ahora".
Ashlar
Lo siento, no entiendo dónde está el problema. Según su publicación, el campo de referencia de nodo se comparte entre sus tipos de contenido y, como tal, la vista 'get_nids' reunirá todas las entidades referidas. Sin embargo, si no, se necesitaría un bucle sobre la primera vista.
Letharion
1
Hmm! Creo que estaba confundido y podría estar haciendo esto más complicado de lo que debería ser. Gracias
Ashlar
2

Buscar campos dentro de un nodo y devolver una lista de NID es exactamente lo que nació para hacer EntityFieldQueries . (Ver también: mi propia pregunta sobre el tema ).

Un ejemplo de mi código, que se ejecuta al enviar el formulario web, y en el que busco nodos de tipo "Clave de respuesta de prueba" para encontrar uno (s) con el campo "Referencia de prueba" completado con el NID del formulario web que se está validando actualmente :

    $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

Luego, si realmente desea cargar valores de los campos en los nodos, usaría node_loadpara obtener más información de los nodos que desee, de esta manera:

    $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 

Ahora $ans_nodees una matriz (u objeto, lo olvido) que contiene toda la información en todos los campos del nodo. Voilá!

beth
fuente
0

Ok, una solución codificada (hay pocas) pero aquí hay una:

  1. Cree una vista que obtenga todos los nid de salida de estos nid como una lista limitada por comas, puede hacer esto utilizando campos como su salida y configurando su configuración de estilo en Estilo no ordenado, campos de estilo de fila -> haga que el campo de nid esté en línea y use Una coma como separador.
  2. En su módulo, cree una función que llame a esta vista y obtenga la salida
  3. Cree su segunda vista (o pantalla) use esta función como argumento en su segunda vista que realmente muestra la salida, por lo que, bajo argumentos, el argumento debe ser nodo: nid, la Acción a tomar debe establecerse en "proporcionar predeterminado" y usted luego use la configuración del código PHP para llamar a su función: return mymodule_get_nids (); asegúrese de que la casilla de verificación "permitir múltiples términos por argumento" esté marcada

Paso 2 código

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

¿Debería ser esta una respuesta separada? o una edición?

Andre
fuente
Estoy buscando soluciones codificadas. Aclararé la pregunta.
Ashlar
Por favor, corríjame si me equivoco, pero por lo que puedo decir, esto ni siquiera resolvería el problema, ya que Ashlar está tratando de obtener datos de múltiples relaciones al mismo tiempo, mientras que los archivos adjuntos solo serán los "actuales" ¿uno? (Pasó un tiempo desde que hice uso de archivos adjuntos, así que podría estar equivocado)
Letharion
Gracias por tu esfuerzo. Agregué más información para terminar el tema de mostrar el contenido de los hechos relacionados en la pregunta. Por favor vea "Hasta ahora".
Ashlar