So, it's no problem to style a node. I've got access to the $node variable and all the members within from my node-type.tpl.php file.

When I try and theme up a block with a block-view-[block-name].tpl.php file, I have no access to $node. I've done a print_r ($block) and have some data there, but it's nowhere near as robust as what I see in the print_r($node) from my node-type.tpl.php file.

I need to be able to take 100 characters from the body text and access the cck image field I've included...

Is there any way to get the node info from the block and access it right in my template?

Anyone?

Thanks,
adam

Comments

nimzie’s picture

or is there a way for me to make a differentiation in the node template for nodes which are in blocks on the front page?

These are like teasers, but are presented differently on the front page than their internal page teasers...

There's got to be a slick way around this :)

Thanks!

nevets’s picture

How about using vews to make the block and theming the view?

nimzie’s picture

I'm trying to use a file : block-views-amazing_products.tpl.php to style the block.

When I access $node->anything or print_r( $node ), it comes up empty.

I'm using views (page and block). The node styling (teaser/body) is taking care of the page view.

block-views-amazing_products.tpl.php should be taking care of the block view with access to $node, but no such luck.

How do I access $node from block-views-amazing_products.tpl.php ?

I guess that's more my question .. or what approach should I use?

nevets’s picture

Blocks (block.tpl.php) only see a general content variable ($content) and do not have a $node variable available (they are used more often for showing other things). Since it sounds like you are using views but want the node to look diifferent from either the standard full or teaser view you could theme the view and extend your theming for the node. The trick here is the theme function you will have something like

$node = node_load($nid);
print node_load($node);

You can change that to something like

$node = node_load($nid);
// Let the node know we are being themed from a view
$node->view_name = $view->name;
print node_load($node);

And then in a version of node.tpl.php specific to your content type take advantage of $node->view_name.

If only showing a few fields you could switch to a list view and theme the view output the fields in the way you want.

nimzie’s picture

Thank you for the reply. I am struggling through the million ways to do things in drupal.

In my node type, there is a cck image, the body and the title.

I need to be able to style these things in my tpl file.

So - according to your explanation, I am unsure of where the code you mention goes and how to implement, then - what does that give me?

Ideally, the view would have a node id somewhere and I could then get the node while in the block-view.tpl file? Is that an option?

Once again, thank you for the help. You deserve a lot of respect from the community for your time spent answering posts :)

Best.

nevets’s picture

Here is a generalized solution to theming full/teaser nodes when part of a views output.

Step 1: Add the following to your themes template.php file

// Override the theming of a view that lists either full or teaser nodes
// All it does is set $node->view_name to the name of the view
function phptemplate_views_view_nodes($view, $nodes, $type, $teasers = false, $links = true) {
  foreach ($nodes as $n) {
    $node = node_load($n->nid);
    $node->view_name = $view->name;
    $output .= node_view($node, $teasers, false, $links);
  }
  return $output;
}

At this point all we have done is add the view name to the node.

Step 2: This also goes in your template.php file. If you already have _phptemplate_variables() defined you will need to merge
this function with the existing one (details vary depending on the existing function)

/**
 * Override or insert PHPTemplate variables into the templates.
 */
function _phptemplate_variables($hook, $vars) {
  if ( $hook == 'node' ) {
  	$node = $vars['node'];
  	
  	if ( ! empty($node->view_name) ) {
			$suggestions = array();
      $suggestions[] = 'node-' . $node->view_name;
      $suggestions[] = 'node-' . $node->type . '-' . $node->view_name;      
      $vars['template_files'] = $suggestions;
      return $vars;
		}
  }
  return array();
}

What this step does is add a couple of more template file suggestions for nodes if $node->view_name is set. In general terms these new suggestions are node-{view_name}.tpl.php and node-{type}-{view_name}.tpl.php where {type} is the node type and {view_name} the view name.

So for example if you have a type called 'articles' and a view called 'recent_articles' you can use node-recent_articles.tpl.php to theme any content type displayed through the view 'recent_articles' or node-articles-recent_articles.tpl.php to theme just the content type 'articles' when displayed through the view 'recent_articles'.

When creating a template file either node.tpl.php or node-{type}.tpl.php is generally a good starting point.

nimzie’s picture

how would I have it so I can create a view/type template for block output only with node access?

Is it possible?

nevets’s picture

I am not sure what you mean by "how would I have it so I can create a view/type template for block output only with node access?", in particular "only with node access"

nimzie’s picture

well, I want to style somethign very particular...
The view's
view->block

And have access to $node

nevets’s picture

Following the steps under "A generalized solution" above change step 1 to

// Override the theming of a view that lists either full or teaser nodes
// All it does is set $node->view_name to the name of the view
function phptemplate_views_view_nodes($view, $nodes, $type, $teasers = false, $links = true) {
  foreach ($nodes as $n) {
    $node = node_load($n->nid);
    $node->view_name = $view->name;
    $node->view_type = $type;
    $output .= node_view($node, $teasers, false, $links);
  }
  return $output;
}

and change step 2 to

/**
* Override or insert PHPTemplate variables into the templates.
*/
function _phptemplate_variables($hook, $vars) {
  if ( $hook == 'node' ) {
  $node = $vars['node'];
 
  if ( ! empty($node->view_name) ) {
$suggestions = array();
      $suggestions[] = 'node-' . $node->view_name;
      $suggestions[] = 'node-' . $node->type . '-' . $node->view_name;     
      $suggestions[] = 'node-' . $node->view_name . '-' . $node->view_type;
      $suggestions[] = 'node-' . $node->type . '-' . $node->view_name . '-' . $node->view_type;
      $vars['template_files'] = $suggestions;
      return $vars;
}
  }
  return array();
}

With those additions to you themes template.php you will be able to use a tpl file named
node-view_name.tpl.php
node-node_type-view_name.tpl.php
node-view_name-view_type.tpl.php
node-node_type-view_name-view_type.tpl.php

As an example if your node type was 'car', your view name 'car_list' and your view type block you could use
node-car_list.tpl.php (applies to any view generated by car list)
node-car-car_list.tpl.php (applies to any view generated by car list but only for content of type 'car')
node-car_list-block.tpl.php (applies to any block view generated by car list)
node-car-car_list-block.tpl.php (applies to block view generated by car list only for content of type 'car')

Applies only to views of type teaser/full node (not list or table) and the tpl.php should have $node available.

nimzie’s picture

Thankyou! I will try this out tomorrow... I really appreciate your assistance and am learning piles!

Cheers,
Adam

kulfi’s picture

@nevets, thanks for the help in this thread and also http://drupal.org/node/260460. Before I jump into what I'm doing, here's the why:

I'd like to trim the teaser text, just for specific views (i.e. I'd like to keep the default post setting to 600 chars, and for View X reduce it to 200 chars).

A few questions, and how I'm trying to do this:

- Is function phptemplate_views_view_nodes($view, $type, $nodes, $teasers = false, $links = true) the API for D6? Because in D5 I kept getting an error on foreach($nodes as $n), and resolved it by switching the order of the params to:
function phptemplate_views_view_nodes($view, $nodes, $type, $teasers = false, $links = true)

- My views names are (1) view_stats and (2) view_blogs and in my template.php I have:

<?php

...

function phptemplate_views_view_view_stats($view, $type, $nodes) {
  return views_theme('views_view_nodes', $view, $nodes, $type, true);
}

function phptemplate_views_view_view_blogs($view, $type, $nodes) {
  return views_theme('views_view_nodes', $view, $nodes, $type, true);
}

function phptemplate_views_view_nodes($view, $nodes, $type, $teasers = false, $links = true) {
	foreach ($nodes as $n) {
		$node = node_load($n->nid);

		$l=strlen($node->content['body']['#value']); 
		if($l>100) {
			$teasers = substr($node->content['body']['#value'],0,100)."…";
		}

		$output .= node_view($node, $teasers, false, $links);
	}
	return $output;
}

?>

However, this doesn't affect the teasers at all?

nevets’s picture

Try changing

$teasers = substr($node->content['body']['#value'],0,100)."…";

to

$node->content['body']['#value'] = substr($node->content['body']['#value'],0,100)."…";
kulfi’s picture

No joy. It looks like the change needs to be persisted (node_save) to have any impact, but that defeats the purpose of showing a non-standard teaser length.

I ended up removing those template.php edits and creating individual node-.tpl.php with:

	<?php  
		global $current_view;
		if ($current_view->name == 'view_stats' || $current_view->name == 'view_blogs') { 
			print phptemplate_front($node, $node_url);
		} else { 
	?>