Gerelateerde entities in views

Tijdens het ontwikkelen van Drupal websites lopen we wel eens tegen specifieke problemen aan. Deze artikelen geven de opgedane ervaringen weer, zodat andere ontwikkelaars of geavanceerde gebruikers van Drupal daar eventueel hun voordeel mee kunnen doen.

Het probleem:

We hebben een inhoudstype met daarin een veld dat refereerd aan een ander inhoudstype. Bijvoorbeeld een inhoudstype project met daarin een entity reference field dat refereerd naar een opdrachtgever. Op iedere pagina van het type project willen we een blok tonen met andere projecten van dezelfde opdrachtgever.

Na een aantal pogingen ben ik tot de volgende oplossing gekomen:

Vereiste modules:

Maak een aantal projecten aan die refereren naar een opdrachtgever.

Vervolgens maken we een blok view aan, met daarin de velden titel en nid. Het nid veld uitsluiten van weergave. Maak dan een relatie naar de opdrachtgever aan onder uitgebreid -> relations. De eerste relatie is er een naar de opdrachtgever entiteit. Gebruik Entity Reference: Referenced Entity A bridge to the Inhoud entity that is referenced via field_opdrachtgever. Ik heb de relatie 'Opdrachtgever' genoemd. Op dit moment zijn alle velden uit de opdrachtgever entiteit beschikbaar. Maar nu maken we een tweede relatie aan, waarbij er een link wordt gelegd van naar alle projecten die naar een opdrachtgever zijn gelinkt. Dit keer gebruiken we Entity Reference: Referencing entity A bridge to the Inhoud entity that is referencing Inhoud via field_opdrachtgever. Ik heb deze relatie 'Project' genoemd.

Maak beide relaties verplicht. Dit zorgt ervoor dat er alleen projecten worden getoond die deze relatie hebben. M.a.w. als een project geen link heeft naar een opdrachtgever, dan wordt dit project niet getoond.

Nu moeten deze resultaten worden gefilterd, zodat alleen projecten te zien zijn met dezelfde opdrachtgever als het project (de projectpagina) waarop ons blok wordt getoond. Dit kan worden gedaan met een contextueel filter (argument). Omdat een blok natuurlijk geen url heeft en dus ook geen argument, geven we een standaard contextueel filter mee.

Kies onder contextuele filters Inhoud: Nid De ID van de node. Als relatie kies 'Project'. Onder het kopje 'Wanneer de filterwaarde niet beschikbaar is' kiezen we 'Beginwaarde ingeven' -> 'Content ID from URL'.

We kunnen nu onze view testen door een node id in het 'Preview with contextual filters' invulveld te plakken. Neem daarvoor een van de node ids van de projecten die we aan het begin hebben aangemaakt.

Als alles goed gaat hebben we nu een resultaatlijst waarin alle projecten met dezelfde opdrachtgever wordt getoond.

De laatste stap is het filteren van de resultaten, waarbij het huidige project uit de resultatenlijst wordt gehaald. Bij een eenvoudige view kan je het resultaat fileren door de huidige node id uit te sluiten. Dit doe je dan bij 'Contextuele filters' -> 'Meer'. Maar in ons geval verkrijgen we de resultaten via de huidige node id, dus zodra we die uitsluiten hebben we helemaal geen resultaten meer. Daarom moeten we een andere oplossing verzinnen.

Voor het filteren van de resultatenlijst op basis van PHP code kunnen we de Views PHP module gebruiken. Onder 'Filtercriteria' krijgen we nu een extra mogelijkheid 'Global PHP'.

Na het kiezen van dit filter krijgen we de mogelijkheid de resultaten in PHP te manipuleren. Dit filter wordt op iedere rij van de resultaten toegepast. Om het filter in te stellen hebben we twee velden ter beschikking. Het eerste (Setup code) om een variabele aan te maken die voor alle velden geldt. Wat we willen bereiken is dat de huidige node id wordt uitgesloten van de resultaten. In dit veld zijn ook al een aantal beschikbare waarden te vinden, waaronder de variabele $view. Omdat we een standaard argument nid hebben aangemaakt (onder contextuele filters), kunnen we $view->argument['nid']->value[0] toekennen aan de variabele $static.

$static = $view->argument['nid']->value[0];

Deze variabele vervolgens beschikbaar in alle resultaatrijen (het tweede veld van het filter).

Omdat we in de view ook het veld nid hebben aangemaakt, is in het tweede veld (Filter code) de variabele $node->nid beschikbaar. Indien dit veld TRUE als resultaat geeft, wordt het uit de resultaten gefilterd. De filter code is dan ook:

if ($row->nid == $static) {
  return true;
}

of nog korter:

return ($row->nid == $static);

Het resultaat is een lijst van alle projecten die dezelfde opdrachtgever hebben als huidige project.