Hi all,

I have been using Drupal for awhile but I am a bit of a newbie when it comes to doing theming "the Drupal way" (on the previous site I worked on we did not use any theme functions, only a few override of core theme functions in the template.php and had our own php functions to generate all the html).

In my current site I have override the theme function for a node and replaced it with my own. In my own function, this calls a custom hook called (name of content type)_node_view - I prefer structuring my node html this way than with the _view hook.

In the _node_view I am calling a theme function to output a bunch a div with an h2 tag and a bunch of links. The h2 from this theme function never gets output (which I thought was down to my html filtering). However in the _node_view function, I output an h2 tag manually e.g.

$output .= '<h2>This is an h2 tag not from the theme function</h2>';

This appears.

To further test this, I duplicated the theme function as a standard normal php function and the h2 tags would not appear from this function either.

I am unsure as to what the difference is and how to get the header tags from my theme functions to appear as I would like to things the proper "drupal way" - Any help would be appreciated :)

Comments

francort’s picture

Some concepts( if i'm mistaken , someone just correct me )

1.- There are not custom Hooks. They're limited. Check this
2.- Hooks are for modules and not for themes
3.- With theme's function it is possible to override how a node is displayed

So , i would try with a theme function (mytheme_nodetype() , when you're not using phptemplate engine) or in a module with hook_nodeapi for the "alter" case( but that will be harder, and useless if it just the theme what you want and not a module changing the display of another module. )
Maybe this thread can help you if you're using phptemplate engine

Good luck!

jeebsuk’s picture

Hi, sorry I didnt explain myself very well:

(I am using the aurora theme at the moment):

function aurora_node($node, $teaser = FALSE, $page = FALSE) {
	if ($teaser == false) {
		$function = $node->type."_node_view";
		if (function_exists($function)) {
			// Call the function to generate the html
			$args = array($node,$teaser,$page);
			$output = call_user_func_array($function,$args);
			return $output;
		} else {
			// Default to normal behaviour.
			//drupal_set_message("using _default");
			return phptemplate_node($node,$teaser,$page);
			//return _phptemplate_callback('node', array('node' => $node, 'teaser' => $teaser, 'page' => $page));
		}
	}
}

That is my overriding of the node theme function in my template.php, when you get to the call_user_func_array, it takes me to:

function content_artist_node_view($node,$teaser = FALSE, $page = FALSE, $links = TRUE) {
	$output = '';
	$output .= '<h2>This is an h2 tag in the node view</h2>';
	$output .= '<br />';
	$title_text = '<h2>h2 tag here</h2>';

$output .= theme('artist_links_panel',$node,$title_text);
	$output .= $node->body;
	return $output;
}

and the theme function called in the artist_node_view is:

function theme_artist_links_panel($node,$title_text=null) {
	$html = '';
	$html .= '<div class="artist-links-panel" style="border: 1px solid #d4d4d4; margin-bottom: 10px; padding: 5px 10px;>';
	//this is where h2 tag should appear
	$html .= $title_text;
	$html .= '<ul class="inline">';
	if (!empty($node->website)) {
		$html .= '<li>'.l('Official Website',$node->website).'</li>';
	}
	if (!empty($node->myspace)) {
		$html .= '<li>'.l($node->title."'s page on Myspace",$node->myspace).'</li>';
	}
	if (!empty($node->lastfm)) {
		$html .= '<li>'.l($node->title."'s page on Last.fm",$node->lastfm).'</li>';
	}
	$html .= '</div>';
	return $html;
}

since I am passing $title_text which contains the h2 tag to the theme function, I would hope that it would output the tag. I have followed it through with XDebug in eclipse and when the theme function returns the html, the h2 tag is in the output variable, however somewhere between that and drupal finishing rendering the page, it is getting stripped from the output and I would like to know how to stop this from happening or what I need to change in order to stop this.

francort’s picture

I think this code is going in the wrong direction.
I can think on 2 straight forward solutions for this.

1) Make content_artist_node.tpl.php ( machinereadablename_node.tpl.php )

On that file, you can define how your content will be rendered. You can copy the file node.tpl.php, rename that copy with the right name and work on few twicks. This new file will be used any time you'll see that content_artist content type.

2) On template.php

You can just make some functions over there. I reccomend to have the original template.php for aurora theme, copy/paste chameleon.theme from chameleon.theme and play with it( erase node.tpl.php after that if you want)
Add a new line for the function. This line should go first and be something like:

<?php
if( !$teaser && $node->type == "content_artist" ) return myfunction( $myarguments );
?>

Just implement that "myfunction".

I believe this will be easier than what was done.
Good luck!

jeebsuk’s picture

The custom node.tpl.php is definitely the way to go thank you, however:

If I call the theme function I had from my earlier post inside the node-content_artist.tpl.php - I STILL cannot get the "h2" tag to appear, I am just wondering what part of drupal is stripping the tag (and what goes inside the tag) before it is getting rendered.

jeebsuk’s picture

I have also discovered that if I have any markup in a theme function, if the html element has a class on it (e.g. <h2 class="title">text</h2> Then it will be rendered. If the element has no class, it will not be rendered. Is this standard for Drupal or do I have something very weird going on? I have tried applying 3 or 4 different themes to my site and this is the case with all of them.