Search

Fri 22.07.2011
Drupal 7 - How to create a Related Content block



This tutorial is a follow up to Drupal 7 - How to use Views and Panels together tutorial. So you might want to check it out first. We create a references field for our book content type and spit added references out in a view next to the node. We use panels to split the content area and get the node id from url.


SUMMARY

1. Get necessary modules and enable them

2. Modify the Book content type

3. Add some references

4. Create a Related Content view

5. Edit the Books page

6. Configure Related Content view some more


1. Get necessary modules and enable them


Most of the needed modules are installed in Drupal 7 - How to use Views and Panels together
tutorial. So you can find them from there.

In addition we need the References module

Get it from here .

OR

download newest version from here:

(NOTE! At the time 7.x-2.0-beta3 version didn't actually work right so I used the dev version 7.x-2.x-dev here.)

References module: http://drupal.org/project/references

extract it in

sites/all/modules

and enable these components:



2. Modify the Book content type


Add new field called References



Select list widget is propably better option than check boxes if you have a lot's of nodes. Autocomplete may be even better.

Choose Book as the type that can be referenced



You propably don't want to limit the number of references, so select unlimited here:



Now you have this if you followed from the previous tutorial:



3. Add some references


Edit some of your content and select some references.



4. Create a Related Content view




In FIELDS, remove the Title and add Create Content: References field

Remove the label:



Apply (all displays)

Save the view and you have this:



Next, add a CONTEXTUAL FILTER called Content: Nid under Advanced

Select provide default value, choose Raw value from URL as a type and 2 as Path component (that's the id number in url: books/2)



Apply (all displays)

Save the view

5. Edit the Books page


Edit the Books page

Go to Layout and change Category to Two column



Go to Content and add the Related Content view In the right column:



Select Master as a display (It really doesn't matter because our view has only one display, but here you could for example define different displays for different pages.)



Continue and Finish

Update and save your page and you should have this:



6. Configure Related Content view some more


Now go to look at your content (in books/something) which has some references and you see that they are separated by comma, let's change this behaviour (you might want to keep it):

In your Related Content view, edit the Content: References field

Under MULTIPLE FIELD SETTINGS, uncheck Display all values in the same row.



Also we have to make the Reference links to point at right places:

Add Content: Nid in FIELDS and Exclude it from display



Arrange it above the References:



Edit Content: References field

Change Formatter as Title (no link) and under REWRITE RESULTS check Output this field as a link and set the right Link path (Replacement patterns are found below.)



And there you have it:



You might also want to check out the Featured Content module, which you can also use to make blocks to relate to your content.
Comments

Help

Thanks for the tutorial. It was very easy to follow but I can't seem to get the related view to show. I have one main content type (A) and 2 other content types (B & C) that have a node ref back to content A. I have just set it up for B only to see how I go but it won't show on my page. Any idea why it's not showing? I set it to a region and told it to display on the custom page. I'm not sure what I could be missing. Thanks again!

So what exactly you want to

So what exactly you want to achieve?

If you want to show item of type A and load its references from types B and C, you just define Content types that can be referenced as B and C for the references field of type A. And then just add some references from types B and C to nodes from A.

If you want to show one item of type B and C and show related items that are of type A, you have to create a view for both types B and C.

For example for a type B you just do a view as in this tutorial but define show content of type of B. Now if you have defined A as a content type that can be referenced in your B content type references field, the view block lists references (type A) if you load a node of type B.

Thanks for the reply, I did

Thanks for the reply, I did create a view for each of my content types and referenced them. I have been fiddling with it and removed the content:nid field and it worked. If I include it I get a white screen.

Hmm.. that's interesting,

Hmm.. that's interesting, surely you should be able to add any fields, including nid above the references if needed.

(Actually can't remember why I put it there anyway, because it's not really related to reference nid.)

I'm sure you didn't remove the content: nid in contextual filters, otherwise it would show ALL the references, not the ones relating to the particular node.

Have you flushed caches by the way?

Well if it works intended, you're good for now I guess :)

It is very odd. Yes the

It is very odd. Yes the caches have been cleared. I think this may have something to do with display suite, I have seen a few users having a problem with DS when a node reference is used - it shows a white page. I have it installed but I'm not using it. After playing around, I can get everything else working except the panel on the right that has the node ref in it.  I'm going to do a fresh install and try this tutorial again because it's exactly what I need. I'll let you know if I get the same result.

Ok! First of all I'm sure

Ok!

First of all I'm sure you'll get it to work, because it worked for me.

Here's some additional ideas though:
- Do you have a slow machine or misconfigured server software? Is the max_execution_time and memory_limit big enough in php.ini? Extra fields take extra memory.
- Did you pinpoint the problem to the panels (like put the view block in the sidebar and see if that works)?: As an alternative, you could always make a custom theme without panels and define a new region right beside the content area and add the view block there.

Nice tutorial, but how to show the full content?

Hi,


nice tutorial, thanks! But is it also possible to show the full content of the related nodes? So in your example you would show (a part of) the content of "Buddenbrooks" and "War and Peace"?

Sure!

Hi!
 
- Edit the Content: References field in the Related Content view
- Select formatter as Rendered node and then you can select View mode to Teaser or Full content
 
OR
 
- If you want to print out specific fields you could do this: 
- Set the Formatter as Node ID
- Set Multiple field settings: Display all values in the same row, and use the default (,) as separator
- Create a custom template for the view.
(check this how to make custom template for a view: http://www.wdtutorials.com/drupal7/49)
 
Basic idea would be to create a template file for the related content view like this: 
 
print $fields['title']->content . "<br />";
if ($fields['field_book_references']->content) {
  $nids = explode(',',strip_tags($fields['field_book_references']->content));
  foreach($nids as $nid) {
    $node = node_load($nid);
    print $node->field_custom['und']['0']['safe_value'] . "<br />";
  }
}
 
An explanation: 
- we check if there are references for the node
- if so, store them in $nids array with tags stripped
- loop through the array, and load node in every loop
- then you have all fields of the node available inside the loop
(like the custom field here)
 
Note: 
You can also use Relation module:

custom template

Hello,

regarding to my last entry http://wdtutorials.com/drupal7/87#comment-415

I have followed step by step according to the your tutorial, everything well until the last step -still doesn't work for me.

I could make a custom template. Edited the Content: References field used formatter as Node ID.

In my case, I want to print out specific fields: just referenced books title with their image in block.

I have not chance to get the image (field_book_image).

How can I solve this?

thank you very much.
S.

Put global $base_path; on top

Put global $base_path; on top of the file.

After you load the node ($node = node_load($nid);), you can do this inside the foreach loop:

print $node->title;
if(!empty($node->field_book_image)) { ?>
  <img src="<?php print $base_path; ?>sites/default/files/styles/thumbnail/public/field/image/<?php print $node->field_book_image['und']['0']['filename']?>" />
  <?php
}


With this technic you have to check where the images are actually stored in your set up (the red part): the field part in the address is propably field_book or something.

The original file is in sites/default/files/field_book/image or similar

(After installing Devel module, check with dpm($node) function what variables are available to you after $node = node_load($nid);)

 you are very cool. thank you

 you are very cool. thank you very much.

now I have just referenced books title with their image in block.
- but not as a link to the content.

Why when I use Fields:
Content: References
Content: book image (field_book_image)
I get just one (same) image for every reference?

that was the reason I chose the way with formatter as Node ID. is that the only way to get the right image for references?

thanks again
S.

Just do the links

Just do the links manually:

?><a href="<?php print $base_path ?>books/<?php print $node->nid; ?>"><?php print $node->title; ?></a><?php

and same around the image:

<a href="<?php print $base_path ?>books/<?php print $node->nid; ?>">
 <img src="<?php print $base_path ?>sites/default/files/styles/thumbnail/public/field/image/<?php print $node->field_book_image['und']['0']['filename']?>" />
</a>

The view here is only used to get the NID numbers of references, which we then use to load the actual reference nodes with node_load function. So the image field you add to the view is just the image of the current node you are watching, and printing that in the loops will just print it several times.

Well, this was my solution to get the images (and other variables) of references, but there might be other ways too :)

another field

I can not say thank you enough. it works.

but it doesn't work with adition field (field_book_slogan). is maybe the wrong syntax?


<?php
global $base_path;

if ($fields['field_book_references']->content) {
  $nids = explode(',',strip_tags($fields['field_book_references']->content));
  foreach($nids as $nid) {
   $node = node_load($nid);

?><a href="<?php print $base_path ?>node/<?php print $node->nid; ?>">
 <?php    print $node->title;?>
</a><?php

if(isset($node->field_book_image)) { ?>

<a href="<?php print $base_path ?>node/<?php print $node->nid; ?>">

  <img src="<?php print $base_path; ?>sites/default/files/styles/thumbnail/public/<?php print $node->field_book_image['und']['0']['filename']?>" />

</a>
  <?php
}


if(isset($node->field_book_slogan)) {


<?php  print $node->field_book_slogan['und']['0']['filename']; ?>

}



  }
}

?>

Check with dpm($node) to see

Check with dpm($node) to see what is the variable you should be printing.
Does field_book_slogan really refer to a file? :)
In this you are trying to print the filename of some file.

It should propably be this:

<?php  print $node->field_book_slogan['und']['0']['safe_value']; ?>

And change the isset to !empty in your if statements.

Little fix to

Little fix to this: (fixed above)
if(isset($node->field_book_image)) { ?>
should be
if(!empty($node->field_book_image)) { ?>

Because field_book_image actually exists even if there is NOT an image, it's just empty.

property of non-object

hi,

already change it to if(!empty($node->field_book_image))

when one book has no reference then I get

Notice: Trying to get property of non-object in include()...

what is the reaseon please?

and still problem with the third field like (field_book_slogan)

thank you!

S.

Oh yeah, that should be

Oh yeah, that should be checked too, sorry about that.
Another quick and dirty fix: change the first if statement to this
if (!($fields['field_book_references']->content == '<div class="field-content"></div>')) {

The reason we have these if statements wrong, is because I previously used this kind of thing when printing view fields, and in that case you could specify inside views that empty fields are not rendered. Here we deal with nodes so it's different.

Well actually indeed you

Well actually indeed you could have also defined no result behavior rule to hide if empty  in your views content: references field and used this in the first if statement:

if (isset($fields['field_book_references'])) {

Thank you again for your

Thank you again for your help.

it works everything.
S.

Great! No problem.

Great!

No problem.

hello again :-), I have

hello again :-),

I have still some problems to get the nodes to theming them.

sofar, I can change the layout for Titel in der View and the position of the image.

- unfortunately I can not assign my new image style that Resize to 50x50px. when I changed the width and height with css the images doesn't look good

- I can not make the slogan in italic.

can you please help me with that?

thank you very much
S.

Hi there!- Go to

Hi there!
- Go to /#overlay=admin/config/media/image-styles
- Edit thumbnail, override defaults, edit the scale effect
- Change dimension to 50x50 and Update effect
- Now your thumbnails are 50x50 px
  - Well they are 50 x something, because scaling maintains the original aspect ratio, so that the images don't distort). If you want have Exactly 50x50 images, choose the Scale and Crop effect.

If you have .slogan classed div around the slogan, put this in your style.css
.slogan { font-style:italic; }

thanks,  I could make a new

thanks, 

I could make a new image style but how to assign it in your example (node id,  new tpl and view) to the image in the view / block of the website?

- Go

- Go to #overlay=admin/structure/types and manage display of the content type that has the image
- Change the image style of the image field  to 50x50  (grey cog to the right)
- Update

- Now add new content and see where it stores the image and change the path accordinly:
(something like this):
<?php print $base_path; ?>sites/new.localhost/files/styles/50x50/public/field_kd_image/image/<?php print $node->field_kd_image['und']['0']['filename']?>" />

The original image will be found in something like:
files/field_kd_image/image if you want to print it in node template for example.

I think should be between the

I think should be between the div

<div class="slogan">
......

</div>

but I get the sytax error (http://wdtutorials.com/drupal7/52#comment-431)

So, did you try the

So, did you try the solution:
http://wdtutorials.com/drupal7/52#comment-434

yes I did. my final

yes I did.

my final version. I am just confuse with the syntax to put some classes and get the titel and slogan via css.

thank you very much.


<?php
global $base_path;

if (!($fields['field_empfehl_refer']->content == '<div class="field-content"></div>')) {
  $nids = explode(',',strip_tags($fields['field_empfehl_refer']->content));
  foreach($nids as $nid) {
    $node = node_load($nid);
    
 //   dpm($node);
    
    if(!empty($node->field_kd_image)) { ?>

<a href="<?php print $base_path ?>node/<?php print $node->nid; ?>">


<img src="<?php print $base_path; ?>sites/new.localhost/files/qt/<?php print $node->field_kd_image['und']['0']['filename']?>" />

</a>

  <?php
}

    
    ?><a href="<?php print $base_path ?>node/<?php print $node->nid; ?>">
 <?php    print $node->title."<br />";?>
</a><?php

if(!empty($node->field_slogan)) {


print $node->field_slogan['und']['0']['safe_value']."<br /><br /><br />";

}


  }
}

?>

Ok, so you can put divs

Ok, so you can put divs around the title like this:

 ?>
<div class="mytitle">
<a href="<?php print $base_path ?>node/<?php print $node->nid; ?>">
 <?php    print $node->title."<br />";?>
</a>
</div>
<?php

Then you can style it in your style.css like
.mytitle a { font-size: 12px; margin: 0 0 5px 0;}

You probably should take the "<br />" out from the link and put it after the </a> OR remove it altogether and use stylesheet to create that space.
(Same with the slogan)

if(!empty($node->field_slogan)) {
?>
<div class="slogan">

<?php print $node->field_slogan['und']['0']['safe_value']."<br /><br /><br />"; ?>
</div>
<?php

}

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <blockquote> <br> <cite> <code> <dd> <div> <dl> <dt> <em> <li> <ol> <p> <span> <strong> <ul>
    Allowed Style properties: color, font-weight

More information about formatting options

By submitting this form, you accept the Mollom privacy policy.