Come posso modificare il valore di un filtro e modificare l'output prima del rendering della vista?


15

Quando si utilizza Drupal 7 e Views 3, qual è il modo corretto di modificare un valore del filtro Views in modo che influisca sul contenuto che sta per essere visualizzato?

Ho provato tutto quanto menzionato qui per D6.

Anche se alcune persone sono riuscite a farlo funzionare, Merlin afferma che modificare display_options è il modo errato per raggiungere questo obiettivo, ma è vago nella sua risposta su cosa fare ( http://drupal.org/node/789710#comment- 2927556 ).

Ho provato:

function pages_views_pre_view($view){
    $view = views_get_view('north_carolina');
    $view->set_display('default');

    $view->display_handler->options['filters']['province']['value'] = 'Georgia';
    dsm($view->display_handler->options['filters']['province']);
}

Appunti:

1) Ho creato una vista chiamata north_carolinache ha due tipi di display: una pagina e un blocco (pagina_1 e blocco_1).

2) i miei filtri sono gli stessi su tutti i miei schermi, quindi sto provando a cambiare il display "predefinito" in modo che influisca su tutti.

3) Il valore predefinito del mio filtro è "North Carolina" (che ho impostato nell'interfaccia utente di Views) ma noti che sto cercando di cambiarlo in "Georgia"

4) Se eseguo DSM immediatamente dopo, vedo che il filtro è stato modificato, tuttavia i miei risultati mostrano ancora i risultati "North Carolina". La memorizzazione nella cache è disattivata e ottengo sempre la stessa cosa dopo aver eseguito drush cc all.

Ho anche provato a eseguire lo stesso codice attraverso hook_views_pre_builde hook_views_pre_execute.

Eventuali suggerimenti?

MODIFICARE:

Come suggerito, può essere utile avere ulteriori informazioni. Ecco un dump della vista:

$view = new view();
$view->name = 'north_carolina';
$view->description = '';
$view->tag = 'default';
$view->base_table = 'node';
$view->human_name = 'North Carolina';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['title'] = 'test nc block';
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'perm';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'full';
$handler->display->display_options['style_plugin'] = 'default';
$handler->display->display_options['row_plugin'] = 'fields';
/* Field: Content: Title */
$handler->display->display_options['fields']['title']['id'] = 'title';
$handler->display->display_options['fields']['title']['table'] = 'node';
$handler->display->display_options['fields']['title']['field'] = 'title';
$handler->display->display_options['fields']['title']['label'] = '';
$handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE;
$handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE;
/* Sort criterion: Content: Post date */
$handler->display->display_options['sorts']['created']['id'] = 'created';
$handler->display->display_options['sorts']['created']['table'] = 'node';
$handler->display->display_options['sorts']['created']['field'] = 'created';
$handler->display->display_options['sorts']['created']['order'] = 'DESC';
/* Filter criterion: Content: Published */
$handler->display->display_options['filters']['status']['id'] = 'status';
$handler->display->display_options['filters']['status']['table'] = 'node';
$handler->display->display_options['filters']['status']['field'] = 'status';
$handler->display->display_options['filters']['status']['value'] = 1;
$handler->display->display_options['filters']['status']['group'] = 1;
$handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
/* Filter criterion: Location: Province */
$handler->display->display_options['filters']['province']['id'] = 'province';
$handler->display->display_options['filters']['province']['table'] = 'location';
$handler->display->display_options['filters']['province']['field'] = 'province';
$handler->display->display_options['filters']['province']['value'] = 'North Carolina';
$handler->display->display_options['filters']['province']['exposed'] = TRUE;
$handler->display->display_options['filters']['province']['expose']['operator_id'] = 'province_op';
$handler->display->display_options['filters']['province']['expose']['label'] = 'State';
$handler->display->display_options['filters']['province']['expose']['operator'] = 'province_op';
$handler->display->display_options['filters']['province']['expose']['identifier'] = 'province';
$handler->display->display_options['filters']['province']['expose']['remember_roles'] = array(
  2 => '2',
  1 => 0,
  3 => 0,
  4 => 0,
);

/* Display: Block */
$handler = $view->new_display('block', 'Block', 'block_1');
$handler->display->display_options['block_description'] = 'test nc block';

Si noti che questi gestori sono forniti dal modulo locations. In particolare per il filtro "Posizione: provincia", mi viene fornito un modulo di completamento automatico. Quando scrivo in Carolina del Nord, si apre e devo sceglierlo. Tuttavia, notare nell'istruzione SQL che le viste generano utilizza l'abbreviazione di due caratteri per stato:

SELECT node.title AS node_title, node.nid AS nid, node.created AS node_created
FROM 
{node} node
LEFT JOIN {location_instance} location_instance ON node.vid = location_instance.vid
LEFT JOIN {location} location ON location_instance.lid = location.lid
WHERE (( (node.status = '1') AND (location.province = 'NC') ))
ORDER BY node_created DESC
LIMIT 10 OFFSET 0

Risposte:


8

Può essere difficile capire la parte esatta dell'oggetto viste da modificare. Di solito esporto prima la vista e guardo il codice generato per iniziare.

Lo snippet di seguito non è modificato e funziona come previsto in uno dei miei siti di produzione. Spero che sia abbastanza per farti andare nella giusta direzione (ovviamente, questo è in un modulo personalizzato chiamato offer_select). Se riesci a fornire il codice dalla vista esportata, qualcuno potrebbe essere in grado di dare un'occhiata.

//Alter the End date filter on the offer views
function offer_select_views_pre_view(&$view) {
  if ($view->name == 'active_offers') {
    $view->display['default']->handler->options['filters']['field_end_value']['value']['value'] = time();
  }
}

- AGGIORNAMENTO:
per la tua vista specifica ho installato il modulo Posizione e creato alcuni nodi in NC e alcuni in Georgia e ho importato la vista per testare. Nel mio modulo personalizzato (chiamato dev) ho iniziato con questo codice (con devel installato):

function dev_views_pre_view(&$view) {
  if ($view->name == 'north_carolina') {
    dpm($view->display['default']->handler->options['filters']);
  }
}

Da lì, ho continuato ad aggiungere all'array i valori ovvi visualizzati in krumo fino a quando non sono arrivato qui:

function dev_views_pre_view(&$view) {
  if ($view->name == 'north_carolina') {
    dpm($view->display['default']->handler->options['filters']['province']['value']);
  }
}

Che semplicemente stampato North Carolinain Krumo. A quel punto sono passato dalla stampa del valore all'impostazione in questo modo:

function dev_views_pre_view(&$view) {
  if ($view->name == 'north_carolina') {
    $view->display['default']->handler->options['filters']['province']['value'] = 'Georgia';
  }
}

E voilà. Questo ha funzionato.


Freddo. Quando ne avrò la possibilità, giocherò con il tuo punto di vista e vedrò se riesco a trovare una risposta più concreta.
Adam Balsam,

@ blue928 vedi sopra. Ho aggiornato la mia risposta con una risposta specifica alle tue domande e istruzioni generali su come ci sono arrivato.
Adam Balsam,

ha funzionato alla grande. Nota sulla risposta corretta: parte del mio problema è che non avevo bisogno di chiamare views_get_view o impostare il display.
blue928,

2

Nel caso in cui qualcuno abbia visualizzato questo thread durante la ricerca della stessa soluzione su D8 (come ho fatto io):

La nuova API consente di manipolare questi parametri in modo molto più chiaro. Vedi questa sezione per i riferimenti.

Piccolo esempio

function dev_views_pre_view(ViewExecutable &$view, $display_id, array &$args) {
  if ($display_id === 'my_unique_display_name') {
      $args[0] = 'desired_value';
  }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.