Tuesday, December 11, 2012

Drupal: Conditional Read More link in Views

A practical finding, for a change. This time in Drupal. If you use the Views project to output a list of nodes in “fields” mode (which allows you to select and configure each field individually, instead of a predefined node view), truncated by teaser, you may need to display a conditional Read More link.

Now, it may be unnecessary. Usually the title of the article is accepted by most people as the link to the full content (especially if they want to check out the comments etc). What is missing from this is an indication if there is actually something more to read — or not. This is relevant if sometimes your nodes are so brief that they fit the teaser in their entirety (and, to be honest, that's how I prefer other people to write their thoughts — not me, though, no no).

The simplest way to solve it is to add a “Node Link” field to the view (remember, we're talking about the fields-based view). This will display a “Read More” link on each node.

What I needed though, for a client project, was to display the link only if the truncation was actually happening, i.e. don't display the link if there isn't “More” to “Read”.

You'll need the following:

  • Drupal, Views, yep.
  • Views CustomField module — this will allow you to create custom fields (hence the name) in your views, namely — some simple PHP logic (to show the link only if a condition is met).
  • Make sure to include Node: Teaser and Node: Body fields in your view. I guess you do have the teaser already, but the Body is needed too (to compare them and check if a truncation happened).
  • Set the Body field to “Exclude from display”, you need the field to be included in the data, but don't need it showing to the visitors of your site:
  • Add a new field, CustomField: PHP code, and set its Value to the following PHP code:
<?php
if(strlen($data->node_revisions_body) > 
        strlen($data->node_revisions_teaser))
    print l('Read more', 
        drupal_get_path_alias('node/' . $data->nid));
?>
  • Preview the view (or View the preview, whichever you prefer), make sure it works, and then save it.
  • You're set!
The code is very simple, but I'll explain it briefly.

The $data object contains result of the view's database query for this specific record (in our case — node). We compare the length of the teaser and body, and if the teaser is shorter — we conclude that the body was truncated. If that is the case — print output of l-function, which, according to the very handy Drupal API, generates a link with a given text, applying necessary rules of the CMS (in most cases this is better than just handcrafting your own <a> tag). The text is “Read more”, the link is constructed by drupal_get_path_alias for the current node Id.

It is then up to you to style the link the way you like it.

You can see it working on the site for which I just implemented this approach: Blog at CloudPatterns, for now there are just two entries in the blog, and you can see the “Read more” magic in action on the second article in the list.


I am more impressed what Drupal can do with Views, but we're all impressed by different things, aren't we?

Take care and till next time!


1 comment:

  1. Looking at a CMS is very important I advocate Drupal. Because Seeing that the largest sites such as the White House use Durpal, it's a no brainer For our Drupal hosting I use Pantheon with options to build against their stack What content management system did you chose?
    Drupal Hosting

    ReplyDelete