Hi everyone.

I created a custom content type with CCK. With only this content type, I'd like to have the title of a node available in the node content itself. Ideally I'd like to place it inline with some other fields that I created with CCK.

Is this possible? I looked at the node.tpl.php file, but it would seem that I would have to add the $title variable to the $content array somehow.

A workaround would be to create a new field type with CCK and Token that is just a mirror of the node title. However, I have no idea how to do this, and I didn't see any way to do this in either the Help documentation or online.

Anyone have any ideas? Could I do this with a theme override somehow?

Comments

Karlheinz’s picture

Nobody?

I could perhaps override the node-CONTENT_TYPE.tpl.php, but that would entail taking ALL of the fields out of the $content variable and hard-coding them into the page. I'm really not sure I want to do that - I've already done some field customizations, and it would be incredibly hard to change if I added more fields.

-Karlheinz

Karlheinz’s picture

Well, I did an override on the node template. It works OK, except for one thing: The image_attach'ed image is always in the $content variable, which means it is rendered on the page after my customizations.

Before I had it so that it was rendered before everything else, so I could float it either left or right without content being displayed above it.

Since it's not a CCK field, I can't access it using the $_rendered variables like I can the CCK fields. But I did a print_r on the $node object, and found out I can access its HTML through this array:
$node->content['image_attach']['#value']

The problem is, if I output the image in my custom node, it will still be in the $content variable, so it will print twice. I can't remove it dynamically in the template (that is, I can't unset($node->content['image_attach'])) because $content is already rendered.

Any ideas?

-Karlheinz

Jeff Burnz’s picture

In D6 its all or nothing, either you print all fields separately including the body ie $node->content['body']['#value'] or you print $content. Alternatively you can mess about in themeName_preprocess_node and set any variables you want, which is nice way to clean up the templates.

I dont understand your actual question though.

Karlheinz’s picture

Perhaps it would be simpler if I just showed you. This is the overridden part of my node-release.tpl.php file:

  <div class="content">
    <!-- Overridden content -->
    <?php
    /* Here is where I would print the image, if I could get it to not print twice
    if ($node->content['image_attach']){ 
      echo $node->content['image_attach']['#value'];
      unset($node->content['image_attach']);
    }
    */
    if ($field_artist_rendered){ 
      echo $field_artist_rendered; 
    }
    echo '<div class="field-rel-name">' . $title . '</div>';
    if ($field_rel_type_rendered){ 
      echo $field_rel_type_rendered; 
    }
    if ($field_rel_date_rendered){ 
      echo '(' . $field_rel_date_rendered . ')'; 
    } 
    ?>
    <!-- End overridden content -->
    
    <?php echo $content ?>
  </div>

This is to get something that looks like this:

<field_rel_artist>
<node title> <field_rel_type> (<field_rel_date>)

...which it does. But:

The page itself has other content (tracks, etc) which I have already themed am and happy with, so I didn't include that in the template. Instead I printed out the $content variable, with the above fields removed in admin/content/node-type/release/display. This also has the advantage that I wouldn't have to re-theme the whole page if I added a field to the Release type.

The problem now is that I can only include the overridden content either above or below the $content on the page. This isn't a big deal, except that the attached image floats below the overridden content. I can put the image with the overridden content (as above), but I can't then take it out of the $content variable, and so it prints twice.

Of course, all of this could be avoided if I could just get the $title variable into $content somehow... Then I'd just use CSS to make it look the way I want.

Make sense now?

EDIT: It seems like the themename_preprocess_node() function would work. But is there any way to only use that function on this node type?

-Karlheinz

Karlheinz’s picture

I just saw this article:

http://drupal.org/node/337022

Looks like it answers my questions. I don't know how I missed it the first time around.

-Karlheinz

Jeff Burnz’s picture

Yeah, like I say its all or nothing :/ D7 shaping up to improve this out-of-sight FYI.

To just affect one content type use:

function MYTHEME_preprocess_node(&$vars) {
  $node = $vars['node'];
  if ($node->type == 'story') {
    // your rock'n mods go here...
  }
}

BTW, now, I don't theme a lot of sites the way you are doing, but I would think that $field_rel_date_rendered is unsafe (security experts chime in please) and that you should use $field_rel_date_rendered[0][view] to be sure its been sanitized.

Karlheinz’s picture

Well, trying this method is more work than I thought...

I'm going to try to simply add the Title field into $content, and hopefully not have to worry about a theme override.

However, I can't seem to get it to work... Simply adding it to the $node object doesn't seem to have any effect on the page at all.

Here's my "starter" code:

function karlheinz_preprocess_node(&$vars) {
  $node = &$vars['node'];
  if ($node->type == 'release') {
    $node->field_title = array (
      0 => array (
        'value' => $node->title
      )
    );
  }
}

I've got the Devel module, and the theme registry is being rebuilt on every page view. Yet when I view the page in the "Dev Render" tab, field_title doesn't show up anywhere. I do know the preprocess function is being called (it gave me a parse error when I left off a semicolon).

Help?

Incidentally: according to the CCK help, $field_rel_date_rendered is safe:

$<FIELD_NAME>_rendered
Contains the rendered html for the field, including the label and all the field's values, with the settings defined on the Display fields tab.

The $<FIELD_NAME> array does have some values that are not safe, however. That might be what you're thinking of.

(edited to make code show up)

-Karlheinz

Karlheinz’s picture

I found an extremely easy way to do this.

Simply use the Computed Field module:
http://drupal.org/project/computed_field

Create a new field - I called mine "Node Title," for simplicity. In the field labeled "Computed Code," simply put this:
$node_field[0]['value'] = $node->title;

The rest can just be left as the defaults. (Though I put a limit of 64 characters in the "Data Length" field, since the default node title's length of 255 seems a bit extreme to me.)

And there you have it - a field called Node Title that is displayed along with all the other content. Without the need for either template or function overrides.

EDIT:
I just thought of this after I posted... But I don't even need to do that. To get a field that looks like this:
<node title> <field_rel_type> (<field_rel_date>)

...I would just include this code:

$node_field[0]['value'] = $node->title 
                              . ' ' . $node->field_rel_type[0]['view']
                              . ' (' . $node->field_rel_date[0]['view'] . ')';

That way I wouldn't even have to define a new Node Title field.

Wish I knew about this module earlier!

EDIT AGAIN:
The code above ("EDIT") won't work. Apparently the only values available to the $node object at the time of execution are $node->field_<FIELD_TYPE>[0]['value']. ['view'] doesn't seem to work. Don't know why.

Oh, well... Still better than nothing.

-Karlheinz