Drupal Architecture: Leveraging Entity Reference & Views For Related Content
Drupal 7's contrib module, Entity Reference, is a staple tool for Drupal Architects and Themers. It allows for powerful add-ons to nodes where you can reference other entities such as content types, vocabularies, users and more. It gives your content creators powerful editing capabilities without having to know any code or learn complex workflows.
Use Case
A typical use case for Entity Reference and one that I'll use as an example is if you have news stories on your site and you want your editors to be able to pick a specific related blog post and show it on a news story node. Traditionally you could do this with with Taxonomy and simply use a Views Contextual Filter (aka Views Arguments) to do this in an automated manner. However, sometimes you want more control, i.e. you'd like the editor to pick any related post they want and show that specific one independent of any vocabularies or other factors.
Out of the box, Entity Reference comes with some default display options such as showing the full rendered entity, label, link or id. These are generally ok but for more fine grained control over the design and what fields from the referenced entity you'd like to show, it's better to employ a View and substitute that. The way this works at a basic level is that you would hide the standard field display for the Entity Reference and then render a block for the View that contains the customized entity. The downside of this is that you may not have great control over placement in relation to the content but some of this depends on what theme you are using. To compensate, ideally you'd override your node display, for example with the Panelizer or Insert View modules.
Getting Started
For this project, you'll want a basic Drupal 7 install along with Views and Entity Reference. I have two existing content types, News and Blog. In my News Content type, I create a new Entity Reference Field called Further Reading. This will reference blog posts of the editor's choosing from the Blog content type. For the field's settings under Entity selection, you'll choose your "Target bundles" and in our case "Blog." I like to set the widget type to Autocomplete but you can experiment with whatever style and quantity you like. Note for the Display setting of this field, simply hide it as we'll create a View that displays instead.
Next you can create some content for both types, for my examples, I use Devel Generate in combo with Drupal Ipsum. Devel Generate will also fill in your new Entity Reference fields as well. Now, create a basic View with a block display and filter it for "Blog". This view will be your Further Reading block on your news pages that references blog posts. Add whatever fields from blog as you see fit, this hinges on your design. I use a title and an image for my example and I've added and edit link to make it easy for content editors to edit in place without having to search for the referenced node.
The Relationship
The next two steps are the crux of this entire post, we'll add a Views Relationship and a Views Contextual Filter, both under the "Advanced" tab in the Views UI. The Views Relationship tells views to query the Entity Reference from our news type and creates a bridge to it so it's aware of its data. Note, there's two types of Reference Relationships and a subtle difference:
- Entity Reference: Referenced Entity
- A bridge to the Content entity that is referenced via field_further_reading
- Entity Reference: Referencing entity
- A bridge to the Content entity that is referencing Content via field_further_reading
Suffice it to say, in our context, we want the latter because we are referencing from News to Blog and our View is filtered by Blog. You can create a user friendly name for the relationship's Identifier and I simply use the title, Entity Reference: Referencing entity. This will come in handy later when we select that in the Filter in the next step.
The Contextual Filter
Now that we've added a Relationship, let's add the Contextual Filter. Views Contextual Filters at least for me has been difficult to understand so it takes a lot of trial and error to really get it right but its powerful in that you only need to create one View that will look unique on dozens of different pages because it's "Contextual." For your filter, add "Content: Nid" and then choose the relationship we just created above. Under "When the filter value is NOT available", provide a default value for this context and you'll see different types, choose "Content ID from URL." This is probably one of the most common filters you'll use with a Views Contextual Filter. That's pretty much all you need but you can get fancy with additional settings for the filter.
Add the block and theme away
Finally, add your newly created view as a block to your News Story content type and you are good to go. Beyond that, you can experiment with the display which becomes a theming task. You can get pretty fancy with your display and one of my favorite ways to do this is with the Panelizer module which gives you ultimate control of mixing all kinds of entities on one page in a very logical and concise manner. In addition, Panelizer is highly exportable so this would work well in deployment flows.