How to Create a Product Display Entity Reference and Block View of Related Products

This will guide you through creating a Related Products block for Drupal Commerce.

Install the necessary modules

  1. Download, Install, and Enable the "Entity Reference" module. http://drupal.org/project/entityreference

Creating the Reference Field

  1. Create your product types and product display content types. For this example, the product display content types is labeled "Product Display".
  2. Navigate to Structure -> Content Types -> Product Display -> Manage fields
  3. Add a new Entity Reference field. For this example, the field is labeled "Related Products", and named "pd_related_products". The widget type is Autocomplete.
  4. Choose the number of values. For this example, this is set to "Unlimited".
  5. Select the "Target type" of "Node" or "Content".
  6. Select the target bundles. For this example, there is only one product display. Therefore, we highlight "Product Display".
  7. Optionally, set the sort options. For this example, the field is sorted by the Title property in ascending order.

Configure the "Related Products" field in the display

  1. Navigate to Structure -> Content Types -> Product Display -> Manage display
  2. For this example, the Related Products are shown in a block. Therefore, we hide this field from the display.

Add one or more Related Products to a Product Display

  1. If it hasn't already been done, add a few sample products, and the accompanying product displays.
  2. On at least one product display edit screen, choose the references to the product displays that will be listed as Related Products.

Create the View

  1. Initial View Creation
    1. Navigate to Structure -> Add new view
    2. Choose a view name. In this example, the name is "Related Products".
    3. Choose Show: "Content", of type "Product Display", sorted by "Newest first".
    4. Uncheck the box reading "Create a page"
    5. Check the box reading "Create a block".
    6. Give the block a title, for this example the title is "Related Products".
    7. Select the desired number of items to display and pager settings.
    8. Click "Continue & edit".
  2. Configure Contextual Filters
    1. Add a new filter of "Content: Nid". Select "Provide default value", Change Type to "Content ID from URL"
  3. Configure Display
    1. Under "Format" set "Show" to be Fields
    2. Under "Fields" add "Content: Related Products". Set "Formatter" to be "Rendered Entity" and the view mode to your preferred mode. "Teaser" may be a good choice.
    3. Still under "Fields" remove "Content: title"
    4. Save the View
  4. Configure Filter Criteria - Only do this if you DON'T want the block to display when there are no results ie if no related products have been entered for this product
    1. Under "Filter Criteria" add "Content: Related Products (field_pd_related_products)" and set "Operator" to "Is not empty (NOT NULL)
    2. Under "Advanced" -> "Other" -> "Query settings" select "Distinct"
    3. Save the View

Configure the Block

  1. Navigate to Structure -> Blocks.
  2. Locate the "View: Related Products" block.
  3. Choose the desired display region for this block. In this example, the region selected is "Second Sidebar" provided by the Zen theme.

Navigate to the Product Display that has Related Products to confirm everything worked.

Comments

FrancescoUK’s picture

Many thanks for the great tip and to finding the time to write it here, it's very useful.

I followed what indicated but got few more issues that I fixed in the following way:

Issue 1
I couldn't find Global: PHP and I use D7 and Views 3.
So I've installed Views PHP: http://drupal.org/project/views_php
It's still in development, so it's work in progress and risky, but I couldn't find any alternative to get Global: PHP.

Issue 2
I couldn't set aggregation as it complained about a MySQL error.
What I've done was to add a Filter: "Content: Product:delta (= 0)" to avoid showing multiple times the same item.

Issue 3
Views PHP was complaining about the PHP code and found that you need to do have the following in the for-loop:

   for ($i=0; $i<=count($related); $i++ ) {
      <strong>if(isset($related[$i]['target_id']))</strong>{
        $related_ids[] = $related[$i]['target_id'];
      }
   }

The isset ensures there is a value set such View PHP doesn't throws errors on the web page.

jbova’s picture

Thank you for the reply.

Issue 1

You are correct that Views PHP module needs to be installed. I have updated the documentation to reflect this.

Issue 2

The following line should be replaced:

for ($i=0; $i<=count($related); $i++ ) {
... with the following:
for ($i=0; $i<count($related); $i++ ) {

Sorry for the simple mistake. The comparison should be a less than operator, not a less than or equal operator. Then, there is no need for the extra check you have added to make sure the array key is set.

Issue 3

Can you please post the MySQL error you were getting with aggregation? I know there were some issues with access control and aggregation settings. I had chosen the following route in the view:

Advanced -> Other -> Query Settings -> Disable SQL Rewriting

I think this will fix your aggregation settings. However, it effectively disables content access checks for the view. Perhaps setting the delta filter, as you suggested, would be a better alternative. Never the less, your issue may be indicative of that described in this issue #1276450: Views results empty for unprivileged user when using Relationship: Content: Referenced Product. I believe I ran across this, used the "Disable SQL Rewriting" fix, and forgot by the time I wrote the documentation.

Summit’s picture

Hi,
2 comments:
1) If more than one related product is added, how to filter the one out chosen in the node-display please?
2) Couldn't related products be chosen by the "normal" product reference field instead of a new entity reference field?
Greetings, Martijn

jbova’s picture

Hi Martijn,

1) If more than one related product is added, how to filter the one out chosen in the node-display please?

The only way the product you are currently viewing would appear in the related products block, is if you related a product to itself by accident. The block only displays nodes that have been referenced using the entity reference field.

Couldn't related products be chosen by the "normal" product reference field instead of a new entity reference field?

Normal product reference fields relate products(entities) to product displays(nodes). See Site Building Guide: Commerce Overview.

To provide related products, we need to map product displays(nodes) to product displays(nodes).

Regards,
Jim

Summit’s picture

Hi Jim,
I think we talk about two different things.
I use the product node only to show the title and body. All other product-related stuff is inside the product entity.
One product node can be referencing more than on product entity. A difference between two product entities can be the color. And this color is placed as a term in a taxonomy.
My situation is therefor that a related product (as is in commerce perspective), is another referenced product of the node. Do you get my way of working?
The product-node is really only the display with selection possibility to show the default product (first referenced), and with the possibility to choose another color by selecting another term (color). The node-view shows the title and the rendered-node.

What I would like is to have underneath the selected product, the other products which are referrenced by the product display.
This is I think a different set-up than yours right?

Thanks for your remarks in advance!
Greetings, Martijn

jbova’s picture

Martijn,

Yes. You speak of a different scenario. You are referring to products being referenced by a product display node. I usually handle these within the product display node template. Here is an example of the working related products block to help illustrate the situation:

https://shop.highwood-usa.com/catalog/furniture-collections/new-adironda...

Do you see the color options, white and toffee? If you choose one or the other, it switches the node display to the product being referenced. There is a single product display, with two product references, one white table, and one toffee table. To achieve this, I have checked the box for the color field that reads, "Enable this field to function as an attribute field on Add to Cart forms.". This is what displays the color option to the visitor.

The related products block, as described in this documentation, is shown in the second sidebar. This allows you to relate other product displays to this product display.

Thanks,
Jim

Summit’s picture

Hi Jim,

Yes this is exactly the same scenario I am referring to. I use also the "Enable this field to function as an attribute field on Add to Cart forms."
I want to show in your scenario the table in white, toffee, may be black etc...in another block and only show the other colors than the one which the node display shows. So when the node-display is showing the white table the block will show the toffee and black product for instance?
Is this possible?

Thanks again for your quick reply!
Greetings, Martijn

jbova’s picture

Martijn,

It may be easiest for you give each product its own display node, since you are not showing each product variation on the same display node. You would then be able to use the instructions posted above.

Your use case is less like related products, and more like product variants. It would be like a "Also available in these colors:" block.

Thanks,
Jim

Summit’s picture

Hi Jim,
I think the solution I want is in between. Scematic is this my architecture:

* Product 1 node display (title/body of a specific producttype)
  Say Drinking Bottle
    - Product 1 referenced productentity (term:color, image, size etc..of a specific product entity)
       Say Yellow Drinking Bottle
    - Product 1 referenced productentity (term:color, image, size etc..of a specific product entity)
       Say Grey Drinking Bottle
    - Product 1 referenced productentity (term:color, image, size etc..of a specific product entity)
       SAY Red Drinking Bottle

* Product 2 node display
  Say Football
    - Product 2 referenced productentity
       Say White Football
    - Product 2 referenced productentity
       Say Black Football
   - Product 2 referenced productentity
      Say Golden Football

Then when I have the Yellow Drinking Bottle showing in the view of the product 1 node display (the product entity is showing through rendered node)
I would very much like the other Drinking Bottle colors productentities to show in a block underneath.

I do not think these are product variants. Isn't the architecture of product variants like: http://drupal.org/node/184846
I have the architecture of

* Product display (with productreference to product entities)
  - product entity 1
  - product entity 2
  etc..

Greetings, Martijn

jbova’s picture

Martijn,

What you are referring to is a way to show the product variants in a block, or at least on the product display node. That wouldn't be considered related products. Maybe this conversation should be taking place somewhere else then, such as as feature request or another documentation section. If you want to open a new issue, send me a link. If I can come up with something else, I'll send you a PM.

A good place to start would be to create a custom display template for the node type of your product display. For example, if your product display node type is called "Product Display", then you would create a new file in themes templates folder called node--product-display.tpl.php. If you are familiar with the Panels module, you can probably accomplish the same thing.

Jim

Summit’s picture

Hi Jim,

I will make a new issue. Not now, it is bedtime and bizzy week. I think this is something else yes, but very relevant for drupal commerce in my perspective.
Thanks for this thoughtful conversation, and we see whats coming from it!

Greetings, Martijn

magicbryan’s picture

This is a great guide. thanks. I am running into a problem though...

When creating reference field it states:
5. Select the "Target type" of "Node". My problem is that Node doesn't show up for an option.

Is this a module conflict or am I missing something? Thanks.

drupal 7.12
Entity reference 7.x-1.0-rc1

jbova’s picture

magicbryan,
If you have recently upgraded Entity Reference, then be sure to run your updates. The Target Types selection was rewritten from the beta-3 to the rc1 versions. Do you have any options in the "Target Type", such as Comment, User, Taxonomy Term, etc...?

magicbryan’s picture

Thanks for your response.

I ran update.php. Still not showing "Node" as "Target Type" I am getting "Content, Comment, Commerce Product, File Taxonomy, ..." just not "node"

jbova’s picture

Try creating an Entity Reference field in another content type, such as Page or Story. See if the Target Type "Node" is available there. If it is not, then try the following:
Delete you Entity Reference field. Disable Entity Reference. Uninstall Entity Reference, Re-install Entity Reference.

If the problem persists after these steps, then file a bug with Entity Reference.

olfe’s picture

1, Create your product types and product display content types. For this example, the product display content types is labeled "Product Display".
2, Navigate to Structure -> Content Types -> Product Display -> Manage fields
3,

  • Add new field -->"Related Products",
  • field_ --> "pd_related_products".
  • Type of data to store.--> Entity Reference
  • The widget type is Autocomplete.

4,After save than a next page-->

  • Select the "Target type" of "Node
  • Select the target bundles there is only one product display. Therefore, we highlight "Product Display".

5,Optionally, set the sort options. For this example, the field is sorted by the Title property in ascending order.

johnhorning’s picture

I'm having the same problem as magicbryan - no "Node" selection available for Target type. I did as suggested by jbova, but no luck.
Using Entity Reference 7.x-1.0-rc3
Drupal 7.14

picxelplay’s picture

No need for the Views PHP.module.

Add your relationship, require it.
Add a Contextual filters of Content: Nid, provide default and select Content ID from URL.
Now when you add or edit fields, Under Relationship, use the relationship you added.
Works with the References.module also
Done.

----
Sudo Kill Cylons

franklca’s picture

I was very excited to see this method, tried it and the page rendered much faster - only to find that it only displayed the same product as the current node page.

picxelplay’s picture

You must be doing something wrong. Here is an export of a sample view. Hope this helps you.

http://snipplr.com/view/65033/d7-views3-related-products-block-export/

Here are some pictures of the field settings:
http://imgur.com/a/fbYsU

----
Sudo Kill Cylons

franklca’s picture

Thank guys, I am very interested in making this work. The link you provided to the sample appears to be broken. Would you check the link and repost please.

picxelplay’s picture

I'm sorry; I guess I marked it as private. Try the link now.

----
Sudo Kill Cylons

franklca’s picture

Ok, so I got this working now. After looking at your view, I noticed that the relationship was "Entity Reference: Referenced Entity". The instructions above stated:

Expand the "Advanced" settings of the view configuration.
In the "Relationships" heading, add a new relationship to "Content: Referenced product".
Give this reference an identifier, for this example "Product Reference" was used.
Apply this setting. Fields from the product entity will now be available as fields in the view.

To make this work without the php, you really need both The entity reference "Entity Reference: Referenced Entity" AND "Content: Referenced product". The "Entity Reference: Referenced Entity" finds the related product display nodes but does not make their referenced product fields available for the view. Adding the "Content: Referenced product" allowed access to the referenced product fields such as image and price to be used by the view.

I named the first relationship "Product Display Reference" and the second relationship "Product entity Reference". Then in the fields I selected the content: title from the "Product Display Reference" and the image and price from "Product Entity Reference".

This is working very fast with virtually no impact on page load times. Thank you for posting this solution!

picxelplay’s picture

Your added Referenced product makes sense for Drupal Commerce. @jbova, Note the differences when configuring Commerce compared to Ubercart/general nodes.

----
Sudo Kill Cylons

jbova’s picture

pixcelplay,

Thank you for the suggestions. I suppose I can update the tutorial, as you suggested, to explain that this works for anywhere that you wish to display related nodes.

Note the differences when configuring Commerce compared to Ubercart/general nodes.

Are you saying that I should note the differences in this tutorial?

Since this article is already quite long, and filed under the Drupal Commerce section of the Community Documentation, I would like to keep that explanation brief to avoid muddying the waters. My aim was to allow readers with little knowledge of commerce or views to be able to set up Related Products under Drupal Commerce with ease.

Possibly there can be a generic related node tutorial linked from this page, or maybe a tutorial for doing something similar with Ubercart. I'm not sure of the best route. I'm also don't think the Ubercart related products tutorial should be filed under the Drupal Commerce section. Your thoughts?

Jim

picxelplay’s picture

Yeah, I was just trying to give you extra added information when you rewrite the tutorial to make it complete as possible. It really didn't register in my head that this was filed under DC. It would probably be best to have a separate tutorial for Ubercart with both cross linked to each other. And in each one, note that this method can be used with generic nodes for any situation. These articles would also rank high for people searching Google/D.org for a generic related nodes tutorial, so there wouldn't need to be a third tutorial to write.

----
Sudo Kill Cylons

jbova’s picture

franklca,
You are correct. You need both references. You need the product reference, which references a product entity as described in the tutorial, if you want to use product fields in your view. You also need the additional reference to a product display node, as described by picxelplay if you want to get rid of the Views PHP module. Sorry if that was not explained very well.
-Jim

jbova’s picture

franklca,

The suggestion by picxelplay does work. I have converted my views using his method. I'll try to update the tutorial to make more sense of it. You need to make sure that if you arrange the relationship to the product below the relationship to your related product display reference field. It is a bit much to explain here. I'll update the tutorial.

picxelplay,
Thank you very much for your improvement.

-Jim

picxelplay’s picture

No problem. Consider explaining that this works for Drupal Commerce, Ubercart, or anywhere in Drupal where you want to individually hand pick nodes to relate to another node.

----
Sudo Kill Cylons

parashutiki’s picture

Thanks, guy. It's work fine for me.

franklca’s picture

Thank you for the article, it is exactly what we needed for our store. I have this working with the Entity Reference View Widget to select the related products using a field search. The back end is working perfectly now but having major pains getting it to display on the product page in a block from a view.

Can you explain the comparison for arg(0) twice:
if (arg(0) && arg(0) == 'node') {

My guess is that the first arg(0) is for the url of the current node and the second arg(0) for the url of the related products?

After entering the php code into the filter of the view, the view will no longer load without an exceeded memory error. I am wondering if the second one is being passed to the loop here:

$node = node_load(arg(1));

which may be causing a problem of looping over many products rather than only the nid of the main product?!?

jbova’s picture

Can you explain the comparison for arg(0) twice:
if (arg(0) && arg(0) == 'node') {

Those are two unique comparisons. The first checks to ensure that arg(0) returns a non false value. The second is a string comparison to check that arg(0) == 'node'.

My guess is that the first arg(0) is for the url of the current node and the second arg(0) for the url of the related products?

No. In the following URL: mydomain.org/node/13, the first argument is the string "node". The second argument is the integer '13'. Therefore, the following are true:
1. arg(0) exists
2. arg(0) is equal to 'node'
3. arg(1) is equal to 13
$node = $node_load(arg(1)); will load node 13 into the variable $node.

It may be sufficient to only have if (arg(0) == 'node'). Either way, this would not cause your memory exhausted problems. On a product display node, the first argument, arg(0), would be node, and the second argument, arg(1), would be the node id (nid).

Feel free to export your view and upload it so I may take a look at the view definition.

franklca’s picture

Here is an export of the view that is giving me trouble. Thanks for looking jbova!

$view = new view;
$view->name = 'related_products_display';
$view->description = '';
$view->tag = 'default';
$view->base_table = 'node';
$view->human_name = 'Related Products Display';
$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'] = 'Related Products Display';
$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['query']['options']['disable_sql_rewrite'] = TRUE;
$handler->display->display_options['query']['options']['query_comment'] = FALSE;
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'some';
$handler->display->display_options['pager']['options']['items_per_page'] = '12';
$handler->display->display_options['style_plugin'] = 'grid';
$handler->display->display_options['row_plugin'] = 'fields';
/* Relationship: Content: Referenced product */
$handler->display->display_options['relationships']['field_product_product_id']['id'] = 'field_product_product_id';
$handler->display->display_options['relationships']['field_product_product_id']['table'] = 'field_data_field_product';
$handler->display->display_options['relationships']['field_product_product_id']['field'] = 'field_product_product_id';
$handler->display->display_options['relationships']['field_product_product_id']['label'] = 'Product Reference';
$handler->display->display_options['relationships']['field_product_product_id']['required'] = 1;
/* Field: Content: Nid */
$handler->display->display_options['fields']['nid']['id'] = 'nid';
$handler->display->display_options['fields']['nid']['table'] = 'node';
$handler->display->display_options['fields']['nid']['field'] = 'nid';
$handler->display->display_options['fields']['nid']['label'] = '';
$handler->display->display_options['fields']['nid']['exclude'] = TRUE;
$handler->display->display_options['fields']['nid']['alter']['alter_text'] = 0;
$handler->display->display_options['fields']['nid']['alter']['make_link'] = 0;
$handler->display->display_options['fields']['nid']['alter']['absolute'] = 0;
$handler->display->display_options['fields']['nid']['alter']['external'] = 0;
$handler->display->display_options['fields']['nid']['alter']['replace_spaces'] = 0;
$handler->display->display_options['fields']['nid']['alter']['trim_whitespace'] = 0;
$handler->display->display_options['fields']['nid']['alter']['nl2br'] = 0;
$handler->display->display_options['fields']['nid']['alter']['word_boundary'] = 1;
$handler->display->display_options['fields']['nid']['alter']['ellipsis'] = 1;
$handler->display->display_options['fields']['nid']['alter']['more_link'] = 0;
$handler->display->display_options['fields']['nid']['alter']['strip_tags'] = 0;
$handler->display->display_options['fields']['nid']['alter']['trim'] = 0;
$handler->display->display_options['fields']['nid']['alter']['html'] = 0;
$handler->display->display_options['fields']['nid']['element_label_colon'] = FALSE;
$handler->display->display_options['fields']['nid']['element_default_classes'] = 1;
$handler->display->display_options['fields']['nid']['hide_empty'] = 0;
$handler->display->display_options['fields']['nid']['empty_zero'] = 0;
$handler->display->display_options['fields']['nid']['hide_alter_empty'] = 1;
$handler->display->display_options['fields']['nid']['link_to_node'] = 0;
/* 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']['alter_text'] = 0;
$handler->display->display_options['fields']['title']['alter']['make_link'] = 0;
$handler->display->display_options['fields']['title']['alter']['absolute'] = 0;
$handler->display->display_options['fields']['title']['alter']['word_boundary'] = 0;
$handler->display->display_options['fields']['title']['alter']['ellipsis'] = 0;
$handler->display->display_options['fields']['title']['alter']['strip_tags'] = 0;
$handler->display->display_options['fields']['title']['alter']['trim'] = 0;
$handler->display->display_options['fields']['title']['alter']['html'] = 0;
$handler->display->display_options['fields']['title']['hide_empty'] = 0;
$handler->display->display_options['fields']['title']['empty_zero'] = 0;
$handler->display->display_options['fields']['title']['link_to_node'] = 1;
/* Field: Field: Image */
$handler->display->display_options['fields']['field_image']['id'] = 'field_image';
$handler->display->display_options['fields']['field_image']['table'] = 'field_data_field_image';
$handler->display->display_options['fields']['field_image']['field'] = 'field_image';
$handler->display->display_options['fields']['field_image']['relationship'] = 'field_product_product_id';
$handler->display->display_options['fields']['field_image']['label'] = '';
$handler->display->display_options['fields']['field_image']['alter']['alter_text'] = 0;
$handler->display->display_options['fields']['field_image']['alter']['make_link'] = 0;
$handler->display->display_options['fields']['field_image']['alter']['absolute'] = 0;
$handler->display->display_options['fields']['field_image']['alter']['external'] = 0;
$handler->display->display_options['fields']['field_image']['alter']['replace_spaces'] = 0;
$handler->display->display_options['fields']['field_image']['alter']['trim_whitespace'] = 0;
$handler->display->display_options['fields']['field_image']['alter']['nl2br'] = 0;
$handler->display->display_options['fields']['field_image']['alter']['word_boundary'] = 1;
$handler->display->display_options['fields']['field_image']['alter']['ellipsis'] = 1;
$handler->display->display_options['fields']['field_image']['alter']['more_link'] = 0;
$handler->display->display_options['fields']['field_image']['alter']['strip_tags'] = 0;
$handler->display->display_options['fields']['field_image']['alter']['trim'] = 0;
$handler->display->display_options['fields']['field_image']['alter']['html'] = 0;
$handler->display->display_options['fields']['field_image']['element_label_colon'] = FALSE;
$handler->display->display_options['fields']['field_image']['element_default_classes'] = 1;
$handler->display->display_options['fields']['field_image']['hide_empty'] = 0;
$handler->display->display_options['fields']['field_image']['empty_zero'] = 0;
$handler->display->display_options['fields']['field_image']['hide_alter_empty'] = 1;
$handler->display->display_options['fields']['field_image']['click_sort_column'] = 'fid';
$handler->display->display_options['fields']['field_image']['settings'] = array(
'image_style' => 'product_display_grid',
'image_link' => 'content',
);
$handler->display->display_options['fields']['field_image']['field_api_classes'] = 0;
/* 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: Content: Type */
$handler->display->display_options['filters']['type']['id'] = 'type';
$handler->display->display_options['filters']['type']['table'] = 'node';
$handler->display->display_options['filters']['type']['field'] = 'type';
$handler->display->display_options['filters']['type']['value'] = array(
'product_display' => 'product_display',
);
/* Filter criterion: Global: PHP */
$handler->display->display_options['filters']['php']['id'] = 'php';
$handler->display->display_options['filters']['php']['table'] = 'views';
$handler->display->display_options['filters']['php']['field'] = 'php';
$handler->display->display_options['filters']['php']['use_php_setup'] = 0;
$handler->display->display_options['filters']['php']['php_filter'] = ' if (arg(0) && arg(0) == \'node\') {
$related_ids = array();
$node = node_load(arg(1));
$related = field_get_items(\'node\',$node,\'field_related_products\');
if ($related && is_array($related) && sizeof($related) > 0) {
for ($i=0; $i $related_ids[] = $related[$i][\'target_id\'];
}
}
}
return (isset($related_ids) && in_array($row->nid, $related_ids) ? FALSE : TRUE );
';

/* Display: Block */
$handler = $view->new_display('block', 'Block', 'block');

jbova’s picture

I'm not sure that the shorthand for loop and ternary operator you are using in the global PHP section will work. Please copy the code as displayed in the tutorial and see if that works.

shinew’s picture

Thank you for the guide, i'm getting really to what I want to achieve!
This would be perfect if the product has no variations, but for product with variations, it's showing all the variations fields as well(see attached screenshot, I didn't use the global:PHP to filter the result because I would like to have the current product shown as well)
http://tinyurl.com/6t6yy3x

Is there anyway I could filter the result using Global:PHP or whatever method to display only the first image of each of the referenced product instead of all their variations? thank you!

shinew’s picture

So I worked it out myself, it's actually pretty simple once I understand how to use the views php module. Here is the snippet for my setup in case anyone is interested, basically I want to display all the product variations including their attributes as images, and user can select them by clicking on the images(thumbnails):

if(!is_array($static)) $static = array();
if(!in_array($row->nid, $static) && arg(1)) 
{ 
   $static[]=$row->nid;
   return FALSE;
}else{
   return TRUE;
}

Thanks again for the post to get my started on the right track!

jbova’s picture

shinew,
This would be taken care of with the Aggregation settings on the field.
1) Under Advanced section in your view, set "Use aggregation" to "Yes"
2) On the field in question (image), click on "Aggregation settings". Choose "Group results together" with the grouping column set to "Entity ID".

Here is a screenshot.

Thanks,
Jim

shinew’s picture

Hi Jim,
Thanks for the reply. However, I get the same image for every related product when I follow your method, but only #148 actually matches its product image. here is the screenshot, the numbers are NID for debugging purpose.
http://tinyurl.com/d6y8cjj
here is what it should look like(using global php method without aggregation). http://tinyurl.com/bw7sxwx

Any idea how to fix it? Although I got it working as I wanted, it would be nice to know an alternative method. thanks!

drupaluser_test’s picture

Hi,

I am using drupal 7. In my views block I have 100 contents. In that 100 contents I want to display only 10 contents. I have to select that 10 contents. I can not add multiple nid in filter criteria. How can I add more than one nid in content:nid filter criteria? Is it possible in views php?

Do you have any Idea?

jalves’s picture

Hi,

i'm getting this error after saving the view: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS commerce_product_field_data_field_product_reference__field_d, node.created AS' at line 1

I think i've done everything like the tutorial but maybe i'm missing something..
The block isn't showing up..
Anyone got this one?

Thanks

jalves’s picture

I disabled aggregation and everything is fine!
Anyone know why aggregation caused this problem?

jbova’s picture

Did you remember to choose the "Disable SQL query rewriting" in the view? This will otherwise cause an error due to this bug
#1276450: Views results empty for unprivileged user when using Relationship: Content: Referenced Product

JCL324’s picture

I've disabled the query rewriting and still get the SQLSTATE error. Looking at issue #1276450 above (with 124 comments now!), there are still patches being made and the latest one has failed. I'm using Kickstart 2.6 (which includes Views 3.6 and Drupal 7.22) and this now being over a year later, I'd think it would be fixed?

JCL

nocean’s picture

This is great, thanks so much for outlining how to implement. Is there a way to sort the results by the Entity Reference's weights?

jbova’s picture

I just reordered my related products using the drag handles provided by the Entity Reference widget. It appears to have sorted the related products display to match the order of entity references. Can you verify whether or not this is working for you?

storytellerjeff’s picture

Thanks for the great tutorial, I have it up and running and all is well. My only question would be if there's a way of making the Global PHP filter allow for non-related products to fill out the view?

Example:

My related products block shows 5 products (content:rendered content). If I add 3 related products while editing my node, I'd like the view to populate the remaining two spots with random products. This way, I get more variety in my related products shown, but the products that I am intentionally recommending are always listed.

I tried adding a second view using Global: view area in the footer and then using css to align it under the related products block - which looks great, but none of the the non-related products are clickable do to the related products view-content area overlapping it.

Wasn't sure if this was a views feature request - just thought I'd ask if anyone who's tried this tutorial had a solution.

satvision83’s picture

I've followed the tutorial, everything goes well, but after two week it stopped working.
In Views I've noticed this: This view has been automatically updated to fix missing relationships. While this View should continue to work, you should verify that the automatic updates are correct and save this view.

The Global PHP code has gone from sort criteria.

I've tried again with creating a new view with the same procedure and It's not working at all. The block is displayed on every page.

This problem appears when I've updated the new Views 3.7 or it's some coincidental.
Is anyone have this problem too?

jbova’s picture

I'm assuming your haven't removed or rename any of the fields, and your problem is related to the update. Can you try disabling views caching for that view and report back?

satvision83’s picture

Views caching was never even activated.

tisabelle’s picture

Hello,

This is wonderful tutorial!

I wonder if it is possible to import "Entity Reference" fields using "Commerce Feeds". So far, I only seem to be able to import "Term reference", "Text", and "Long text and summary" fields. Any suggestions?

Thank you!

tisabelle’s picture

This module worked for me . . .

https://drupal.org/project/entityreference_feeds

1. I followed above instructions to setup my entity reference field, making sure the "Entity selection" was for one content type only (as far as I can tell this only works when only one content type is pre-selected at this point).
2. Installed and enabled the "Entity reference feeds" module. This contributed module allows SEVERAL options of "field_pd_related_products . . .", Choose one.
3. In the mapping, I chose the GUID (which is the Product SKU field for me).
4. I made sure this was in my csv file.
5. Ran it and it worked!!!!! :-)

Now I need to know how to import multiple values somehow. :P

tisabelle’s picture

Strange, but this worked.

1. In my CSV file I created four new columns "Related Product 1", "Related Product 2", "Related Product 3", and "Related Product 1".
2. I created four source fields in my import mapping with the same titles as the column headers.
3. I chose the "...(...: GUID)" for the appropriate products I have.
4. I ran the import and it worked.

But here is the strange thing. It made no difference what group the product in my csv file was associated with as it wasn't the same as that of the "...(...: GUID)" I chose and it still worked for me.

For my needs, however, this was fine.

agoradesign’s picture

Thank you for this tutorial. It was a great inspiration for me, when creating a similar block. I've found a way to accomplish this without the use of Views PHP. I did this earlier this year and described it in our blog, based on your tutorial. However, the blog post was unpublished long time, as our site relaunch had unexpected huge delay. But now it's online, take a look here: http://www.agoradesign.at/blog/drupal-commerce-revised-related-products-...

creativepragmatic’s picture

I just wanted to thank you. I was trying to figure out how to do this and your blog post saved me a lot of time!

christo snyman’s picture

Hi,

I've been following every post related to this topic and it seems they work for some people but they all only mention one Content Type (Product Display). I have multiple product displays (shirts, pants etc). I can get related products working on one single product display but the moment I add the other content types in the filter it displays the others too. I'm at a loss of what to do when I have multiple content types (i've tried using unique reference fields and re-using existing reference fields) and I want them to use the same view but only display the related content type. Any suggestions?

agoradesign’s picture

Hi,
I haven't looked very deeply onto this now, but as my tutorial is based on explicitely declared relationships by Entity Reference module, you should be able to safely filter more than one content type, as long your products are only referencing other products, that they really related too. Otherwise you have wrong references

noovocreative’s picture

I had the same issue when using multiple Product Displays. Only worked when I Had my pager set to 'Display all items'.

If i tried to list only 4 items the view vanished!

suntower’s picture

I have had a situation that has been driving me NUTS. When our users would add a new Product to the catalog it simply wouldn't show up in the Commerce Product Search. Not even in the search_api_db table.

Like most sites I imagine, the Product Search Index excludes unpublished products.

It turns out that if you have Related Products and even one of those 'children' is unpublished, the search considers the -parent- product unpublished and it is excluded from the search results. Just to be clear: the parent product is published. If the related product is UNpublished that excludes the -parent- from the search. Ouch.

Sure would like to know how to fix that.

scott859’s picture

Greetings,

I'm using Commerce Kickstart 7.x-2.25 and the in the target type of the entity reference field "Node" is not an option (as is mentioned in a couple of comments above). I tried "Content" as an alternative.

I'm also getting the same SQL error mentioned above when selecting "aggregate" in the view.

I can't get the view to produce any results. Has anyone had success with using this in Commerce Kickstart? If so, can you give me any insight into making this work?

Thanks in advance.

xalexas’s picture

I really don't understand what are you talking about in this tutorial. Maybe I'm missing something but you don't really need two content types nor Views PHP module.
In my scenario I have only one content type: Product. I wanted to display block with related products to the one that is currently displayed. I wanted to pick manually which products are related. For example when I display Wall paint, I wanted to include Thinner, Brushes, Paint Roller etc. You get the idea. I will copy text from this tutorial and change it a little bit.

  1. First add Entity reference field to your Product content type
  2. Navigate to Structure -> Content Types -> Product Display -> Manage fields
  3. Add a new Entity Reference field. For this example, the field is labeled "Related Products", and named "pd_related_products". The widget type is Autocomplete.
  4. Choose the number of values. For this example, this is set to "Unlimited".
  5. Select the "Target type" of "Node" or "Content".
  6. Select the target bundles. For this example, there is only one product display. Therefore, we highlight "Product Display".

Add some related products

  1. Navigate to Structure -> Content Types -> Product -> Manage display
  2. For this example, the Related Products are shown in a block. Therefore, we hide this field from the display.
  3. Add one or more Related Products to a Product
  4. If it hasn't already been done, add a few sample products.

Create the View

  1. Navigate to Structure -> Add new view
  2. Choose a view name. In this example, the name is "Related Products".
  3. Choose Show: "Content", of type "Product Display", sorted by "Newest first".
  4. Uncheck the box reading "Create a page"
  5. Check the box reading "Create a block".
  6. Give the block a title, for this example the title is "Related Products".
  7. Select the desired number of items to display and pager settings.
  8. Click "Continue & edit".

Configure the view

  1. Add fields from Product content type: Title, Image.. whatever you need
  2. Go to Relationships and add relation: Entity Reference: Referencing entity. Check - Require this relationship.
  3. Go to Contextual filter
  4. Add a new filter of "Content: Nid". From the Relatonships dropdown select relationship that we created. Then select "Provide default value", Change Type to "Content ID from URL"

Save the view.

That's it. Hope it helps.

alirahimian’s picture

This lightweight module is trying to solve the problem that Views contextual filter named "Content has taxonomy term ID (with depth)" is available only for nodes and can not be used for products in Drupal Commerce 2.x.

The Module extends Taxonomy module from Drupal core and provides a new contextual filter "Product has taxonomy term ID (with depth)".

Commerce product taxonomy filter for making Related Products

Commerce product taxonomy filter

Note after install module

1- Add Product: Has taxonomy term ID (with depth) from (Contextual filters)
2-select Provide default value
3-select "Product has taxonomy term ID (with depth)".
4-select Load default filter from commerce_product page, that's good for related taxonomy blocks
5-Select Limit terms by vocabulary
6- select Filter to items that share any term

that is work great !

Karan Sen’s picture

For displaying the related or featured products please refer to the module Seasonal Product Reccomendation. The link to the module is https://www.drupal.org/project/seasonal_product_recommendations.