1

So this is an interesting scenario I'm faced with. Lets say I have a content type called Article. Within that content type there is a term that is tagged as "sponsored." The content type also holds other tags like Chicago, Seattle, San Fran, Etc.

The View I have built is simply time based and shows a feed based on time published of all articles. However I want some special functionality for any article that is tagged as "sponsored." At the moment the feed looks like this...

1) tag

2) tag

3) tag

4) tag

5) tag

6) tag

This means that if an article is tagged as sponsored is simply falls down the list as new articles are added. What I'd like to have happen instead is always FIX the 2 latest sponsored articles (maybe in a node queue) in the second and fifth position. All other articles without the sponsored tag would fall off as normal based on time while the sponsored articles would stay. So you'd get

1) tag

Sponsored

3) tag

4) tag

Sponsored

6)

Can this even be done in views? Should I just think about adding it to the view template file in a custom manor? Thanks

1
  • This isn't something you can do in the views UI. You're going to need to do some custom code. Sorry I don't have the time to show an example. Probably using api.drupal.org/api/views/views.api.php/function/… you can loop over the results, find the first two which are sponsored, then insert them into the result array at the positions you desire.
    – leexonline
    Commented Feb 20, 2014 at 22:51

3 Answers 3

1

I found a pretty great solution that i hope others can use. I simply made a new view with my list of sponsored content in a node queue. I then used the function views_embed_view inside my view template of content and displayed each block at a certain row ID whick looked a bit like this:

<?php foreach ($rows as $id => $row): ?>
  <div<?php if ($classes_array[$id]) { print ' class="' . $classes_array[$id] .'"';  } ?>>
<?php print $row; ?>
 </div>
 <?php if ($id == 3): ?>
<?php print views_embed_view('sponsored_content','block_1'); ?>     
 <?php endif; ?>
 <?php if ($id == 8): ?>
<?php print views_embed_view('sponsored_content','block_2'); ?>
 <?php endif; ?> 
0

I think that you can solve this using the Views UI.

I would probably create a view for your content, containing one page display and two attachments like this:

  • The main view display can hold the 2 sponsored items (appropriate filters needed)
  • The first attachment display would filter out sponsored items and can hold the first 4 normal items.
  • The second attachment display would also filter out sponsored items and can display the next number of normal items. For this you can use the offset setting in the pager options, see the screenshot

enter image description here

The first attachment display would be configured to appear before the main content (which are the sponsored items) and the second attachment display would be configured to appear after the main content.

3
  • The only issue I see with that is being able to page through the view to all the other stories within the view.
    – Mr Poops
    Commented Feb 21, 2014 at 22:53
  • @user1792023 Right, that will probably not work and I don't see an obvious code-less solution to that. But then again, you could add a more link that displays another views page display that is just a listing of the normal items. If you want the sponsored ones in each page, then you will probably have to code something.
    – berliner
    Commented Feb 21, 2014 at 23:01
  • That sounds like a decent compromise i suppose. Time to fight with drupal again
    – Mr Poops
    Commented Feb 22, 2014 at 1:43
0

You can produce a block in a custom module, using hook_block_info() and hook_block_view() and a content callback for the block, like so:

/**
 * Implements hook_block_info().
 */
function YOUR_MODULE_block_info(){
  $blocks = array();
  $blocks['YOUR_BLOCK_DELTA'] = array(
    'info' => t('NICE NAME FOR YOUR BLOCK');
    'cache' => DRUPAL_CACHE_PER_PAGE,
  )
  return $blocks;
}

/**
 * Implements hook_block_view().
 */
function YOUR_MODULE_block_view($delta = '') {
  $block = array();
  switch($delta){
    case 'YOUR_BLOCK_DELTA':
      $block['subject'] = 'YOUR BLOCK TITLE';
      $block['content']['markup'] = your_block_callback();
      break;
  }
  return $block;
}    
function your_block_callback() {
      $position = 3;
      $sponsored = YOUR_SPONSORED_CONTENT;
      $query = db_select('node', 'n')
        ->fields('n', array('nid'))
        ->condition('n.status', 1)
        ->condition('n.type', 'YOUR_CONTENT_TYPE');
      $result = $query->execute();
      $return = '';
      $i = 1;
      foreach ($result as $r) {
         $node = node_load($r->nid);
          $teaser = node_view($node, 'teaser');
          if ($i == $position) {
            $return .= $sponsored;
          }
        $i++;
        $return .= render($teaser);
      }
      return $return;
    }

Replace all dummy text like YOUR_BLOCK_MACHINE_NAME with your own names, and place this in your custom module's .module file. You'll have to add some code to fill in YOUR_SPONSORED_CONTENT. This will produce a list of teasers. You'll have to add conditions and other logic to the $query, of course.can

2
  • So does this block get added inside the view? I'm assuming i'd place this function within template.php but im unclear as to how this would run for a particular view
    – Mr Poops
    Commented Feb 21, 2014 at 22:55
  • No you'd place this in a custom module, more specifically in the YOUR_MODULE.module file. You also need a YOUR_MODULE.info file. I've edited my answer to make it more complete. On module creation, see drupal.org/developing/modules/7
    – Ollie
    Commented Feb 22, 2014 at 12:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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