I have a set of views (in D7.57, views 7.x-3.18). Each view takes a selection of my (drupal commerce) product-displays and places them in a grid, in alphabetical order.

Now I want to add a bespoke item as first item (so in row 1, column 1), 'bumping up' all normal products one place (so product 1 goes to row 1 column 2, etc). Whatever I try (adding global header in views (obviously wrong), changing the views-grid-xx.tpl) 'breaks' the rows, displaying my bespoke item in perfect order, but breaking the row.

Option 1: adapt the views style or row output .tpl

Update after @AltaGrade answer: Thanks for your answer. That's what I tried, I amended both the 'style' and the 'row' templates for the view, but do not get the desired results with either.

The view does display my insert (which is a piece of fixed code, same lay-out etc as the normal grid items), but then treats the normal generated items as a full row, causing breaks where I don't want them, and also repeats my insert each row.

My rows (of three columns each) then look like:

insert - item 1 - item 2

item 3

insert - item 4 - item 5

and so on..

Code of the views.grid.xxx.tpl looks like this, where and how would I code my inserts (one to go before the first item in row one; one to go after all items have been listed)?


* @file
* Default simple view template to display a rows in a grid.
* - $rows contains a nested array of rows. Each row contains an array    of columns.
* @ingroup views_templates
// Match Column numbers to Bootsrap class
$columns_classes = array(1 => 12, 2 => 6, 3 => 4, 4 => 3, 6 => 2, 12 =>     1);
$bootsrap_class = isset($columns_classes[$view->style_plugin-   >options['columns']]) ? $columns_classes[$view->style_plugin-   >options['columns']] : 3;
$delay_attr = '';
<?php foreach ($rows as $row_number => $columns): ?>
  <div class = "row<?php if ($row_classes[$row_number]) { print ' ' .  $row_classes[$row_number];  } ?>" >
    <?php foreach ($columns as $column_number => $item): ?>
        if(isset($column_classes[$row_number][$column_number]) &&  strpos($column_classes[$row_number][$column_number], 'animation-delay') !==  FALSE) {
          $delay = isset($delay) ? $delay + 0.1 : 0.1;
          $delay_attr = ' data-wow-delay = "' . $delay . 's" ';
      <div class = "col-md-<?php print $bootsrap_class; ?><?php if   ($column_classes[$row_number][$column_number]) { print ' ' .  $column_classes[$row_number][$column_number];  } ?>" <?php print  $delay_attr; ?>>
        <?php print $item; ?>

    <?php endforeach; ?>
<?php endforeach; ?>

Option 2: Preprocess the view output using pre_render.

One suggestion I found is using hooks (hook_views_pre_render, hook_views_post_render?), is this the best way? If so, where would I put such a hook? Are these actually written into views.api.php? And how do I then write such a hook that it only applies to the view I want? All pointers / help very welcome, hooks 100% new area for me.

In the views.api.php I also found a whole section on views-handlers which looks similar to the hooks, are these an option too?.

Option 3: create extra content types

Create new content types (in this case product types) and let the view render first extra type, then the main products, then the second extra type. So I'd create a new content type for the bespoke items, and then add them to the view's filter. Any explanation how I would do that so it neatly merges into the row would be amazing.


Go to admin/structure/views/view/YOUR-VIEWS-NAME/edit/page, click on Theme:Information and you will see bunch of lines. Choose appropriate one depending what exactly you want to override. It can be the whole views display output, or style output, or specific field output.

Each line will have an active hyperlink, clicking which you can copy the content of the new file. Also each line will have file name suggestions. When you identified the right output, you can choose pick any of the suggested file names on that line: the further to the right, the more specific output.

Create a new template file in your themes template directory, paste the copied content and start modifying the output per your desire.

For example, you could execute your checks just after foreach loop starts:

<?php foreach ($rows as $row_number => $columns): 
  if ($row_number != 0) {
    // Here goes your custom modifications.
<?php endforeach; ?>
| improve this answer | |
  • thanks again, have removed my second answer and amended the original question instead.. I will now go and have a try with your suggestion – xax Mar 23 '18 at 14:15
  • Any news on this one? Would be nice if you either accepted my answer or provided your own solution. Whatever you do just do not leave your questions unattended. – AltaGrade Apr 4 '18 at 16:43
  • Apologies for not reacting sooner- I've been trying to use your proposal, but can't get it to work. When I add your code snippet after the foreach in my views.grid.xxx.tpl code (as given above) I do get my insert on the second row and then repeated every other row, breaking the flow as described before. I have tried changing the != 0 to <=0, that helps as it then generates my insert as first item, but the flow is still broken, I get this: > -insert - - first row item 1- > (on a new row) - first row item 2 - -first row item 3 - – xax Apr 9 '18 at 10:28
  • Then on the next row normal flow resumes and I get row 2 items 1 to 3, etc So what I need is the insert snippet but then also how to amend the rest op the views.grid.xxx.tpl code so it generates views item1 as 2, 2 as 3 and so on.. ($column_number +1?). – xax Apr 9 '18 at 10:38
  • Can you just give me what do you want to insert and at which rows only and I will give you a code? – AltaGrade Apr 9 '18 at 15:59

As I can't add this much in a comment and can't do mark-up:

@AltaGrade - I need one 'fake' product to go on row 1, column 1, this is the code to be included:

// Here goes my custom modifications:
print "<div class=\"col-md-4 col-lg-4 mb-60 mb-xs-40\">
<div class=\"views-field views-field-field-sale-images\">
<div class=\"field-content\"><a href=\"http://link to another website\">
<img src=\"/sites/default/files/image_of_the_inserted_product.jpg\" width=\"770\" height=\"500\"></a>

<div class=\"views-field views-field-field-series\">
<div class=\"field-content\"><span class=\"mp_brand\">Text</span>
<span class=\"announcement\">&nbsp;-&nbsp;by&nbsp;text</span>
} ?>

Then I need to generate the normal products through the view (as in the code in the original question), filling up row 1 (there are three columns) with two more products in column 2 and column 3, then second row with three products in columns 1 to 3, etcetera..

At the end of the generated products I want to generate one more insert, (same code as the row 1, column 1 one), right behind the generated products (so in column 3 if products end at column 2, or in column 2 id the products and at column 1, etc..

Hope this makes sense?

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.