Hi there!

This is my first code contrib to the free software world and my first patch ever (: proud and shy :)

When this option is activated, if one of the items corresponds to the currently viewed node, this item will be used as the start position of the carousel and defined as the jcarousel-item-0.

Don't hesitate to correct my code or my english if necessary, i'm learning here, and there are others little options i would like to add...

Cheers!

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

lemartialou’s picture

Status: Active » Needs review

Forgot to give the 'need review' status :p

lemartialou’s picture

Here is an example of how i use this functionality:

I have a node type: Video
All the video nodes are classified with terms in a specific vocabulary.

What I want is a viewscarousel under my video node showing all the other videos of the same term.

No problem, i create my views block, filter it by 'Node:Published Yes' and 'Node:Type Video'.
Then i tell the view to show my thumbnail cck imagefield using imagecache with a carousel_preset, and tell it to link the image to the corresponding video node.

Then I set the style to 'Views Carousel' and configure it to get the magic.

At this point i've got a carousel in a block with all the videos thumbnails linking to their respective nodes.

Now I want the carousel to appear only on the video node page, and i want it to know which term is associated with this node, and i want it to show only the video nodes of the same term.

I found 2 methods to do this:

METHOD 1:
I set a 'Taxonomy:term id' argument with basic validation. I don't provide a default argument.
Then I take my node-video.tpl and inject this little snippet where i want to place the carousel:

if (!$teaser):
  foreach ( (array)$node->taxonomy as $term ) {
    print '<h3 class="video-carousel-title">Category: ' . $term->name . ' :</h3>';
    print views_embed_view('video_carousel_view', $display_id = 'block_1', $term->tid);
  }
endif;

This works well for me, but there could be problems if the node is associated with several terms, I don't know.

In case, I found
METHOD 2:
I set a 'Taxonomy:term id' argument with basic validation.
Now i provide a default argument: PHP Code.


$node=node_load(arg(1));
if($node) {
  $terms = array();
  foreach($node->taxonomy as $term){
    if($term->vid == 2){  //vocabulary ID
      $terms[]=$term->tid;
    }
  }
return implode('+', $terms);
} else {
  return FALSE;
}

(without the php tags)
Again, not sure if it works well with multiple terms cause i don't use them.
Now i can use my carousel as a block acting like I want.

I chose method 1 because I wanted the carousel inside the node, and not in a block.

At this point, the carousel is working, and shows only the video thumbnails relating to the same category of the video node that i'm viewing. That's pretty cool, and I'm pretty happy :)

Now I can sort the order of the carousel's items by using the different sort filters of my view.
Ok, let's sort them chronologically, old school , maybe we'll try to play with draggableviews later.
Chronologically is good.

And here comes the challenge.
My carousel displays 3 items at a time.
Say i've got 20 items , 20 videos of the same category.
If I want to navigate through the videos using the carousel, i'm screwed
Every time i'll go to a new node the carousel will be reset and i'll have to click and click again to reach the 20th video.

I want the video thumbnail of the node that i'm viewing to be in the center of my carousel, so that the left one would represent the previous video, and the right one the next video.

So I learned and I've made this patch.

That was an experience.
(this post is long enough)

Now I activate the 'node aware index start' and set the 'display offset' to 1, and here it goes!
And I can style the "active" node by tweaking the .jcarousel-item-0 selector.
Now my carousel is working exactly like I wanted.

Yipee!

...

I hope that could be useful for someone.
Cheers

LeMartialou

couash’s picture

Good job LeMartialou!

I've been looking for this feature forever. Thanks! It works great!

lemartialou’s picture

Aaah!!! I'm Glad that could help someone! :)

mani.atico’s picture

+1
Haven't tested but code looks great! I was achieving this through hook_views_pre_render, but making it a built in feature would be nice.

Agogo’s picture

Just a FYI - you can use Panels with its node template as well withuot the need of snippets to do the taxonomy term filtering. Just specify which argument to send to the view block in panels (term ID) and in views specify that you want that argument as an argument (Term ID) and voila.

veikko’s picture

Working here too. Thanks! Would be great to see this in the next release.

PetarB’s picture

Works perfectly, wonderful work lemartialou, and thanks for your effort. Will try and pay it forward one day!

iNik’s picture

I managed to handle this with a template.php override -- a little less extreme than patching the core module. (Although it might be a nice addition to the module)

The trick I'm having is matching the id of the item if it's a carousel showing something other than nodes. (e.g. users) So I added an "if" here to check for user or node types -- easily extended to others.

function your_theme_name_viewscarousel_view($view, $options = array(), $rows = array()) {
// Remove the skin and skin path from the options.

$skin = $options['skin'];
$path = ($skin == 'custom') ? $options['skin_path'] : NULL;
unset($options['skin'], $options['skin_path']);

// Set start position based on related node

if (is_numeric(arg(1))) {
// Go through the items in the views.
foreach ($view->result as $object => $key) {
// Set an appropriate key based on view type -- currently just node and user
if(arg(0) == 'user')
$viewkey = $key->uid;
elseif(arg(0) == 'node')
$viewkey = $key->nid;

// Find a viewkey-id'd item corresponding to the current node-id.
if ($viewkey == arg(1)) {
// Override start and offset values using the found item's index.
$options[start] = ((int)$object + 1);
//$options[offset] = -($options[start]);
}
}
}

// Remove any empty options and convert any numbers to float values.
foreach ($options as $key => $value) {
// Override so that URL variables can provide settings
if (isset($_GET[$key]) && is_numeric($_GET[$key])) {
$options[$key] = (float)$_GET[$key];
}

elseif (is_numeric($value)) {
$options[$key] = (float)$value;
}
if (empty($value)) {
unset($options[$key]);
}

}

// Use jCarousel to create the carousel.
return theme('jcarousel', $rows, $options, $skin, $path, 'viewscarousel-'. $view->name .'-'. $view->current_display);

}

ajayg’s picture

Status: Needs review » Reviewed & tested by the community

Looks a few folks have already tried this and reported it is working as described.

nevosa’s picture

iNik,
although I couldn't find anything wrong with the code, and the basic functionality worked, I have issues with this feature:
1) The prev/next are not updated, and the carousel is scrolling beyond the items scope.
2) The circular wrap doesn't work well - I got just white squeres after the last item.
3) the prev doesn't work when the middle item is set as first. After scrolling forwared it enabled the prev to the original beginning item.
Eventually I had to disable the node aware until I can resolve these issues.

I am not that proficient with the syntax, so perhaps you can help conplete this necessary update.
I feel this should be a part of the basic functionality of viewscarousel.
Thanks for the work and this feature!

N@ Betty778 Photography

ajayg’s picture

Status: Reviewed & tested by the community » Needs work
cindyr’s picture

Status: Needs work » Reviewed & tested by the community

I think Betty778's issues are with iNik's template solution, not lemartialou's awesome patch, so setting this back to reviewed and tested. I just installed the patch, and it works beautifully. Thanks, lemartialou!