I hope someone can help me, since at this point I'm pulling out my hair. I've been trying to install flatforum into a Zen-based theme, and no matter how I merge the code into template.php, something ends up messed up. At this point I've tried merging the code in two ways, with the flatforum code either inserted before or after the Zen phptemplate variable code. If I insert it before the code, flatforum looks fine, but it breaks the Zen three-column layout and renders all three columns stacked one on top of another. If I insert the code after the Zen code, then only the initial post in the forum is formatted from flatforum--the comments stay the same as with the default Drupal forum. Any ideas? I'm pretty sure there's something in the Zen phptemplate variables code that's munging up flatforum, but I'm not enough of a programmer to figure it out. Any help would be appreciated.

Here's an example URL for the forum as it stands now, with flatforum formatting the forum post only, not the comments (I haven't installed the flatforum CSS... don't ask, long story...):

http://www.foxartshosting.com/?q=node/11

And here's the code for template.php with the flatforum theme code merged after. Hopefully somebody smarter than me can take a look at it and tell me where I've made a stupid mistake. ;)

<?php
// $Id: template.php,v 1.12.2.1 2007/01/17 05:28:41 jjeff Exp $

/**
 * @file
 * File which contains theme overrides for the Zen theme.
 */

/*
 * ABOUT
 *
 *  The template.php file is one of the most useful files when creating or modifying Drupal themes.
 *  You can add new regions for block content, modify or override Drupal's theme functions, 
 *  intercept or make additional variables available to your theme, and create custom PHP logic.
 *  For more information, please visit the Theme Developer's Guide on Drupal.org:
 *  http://drupal.org/node/509
 */

 
/*
 * MODIFYING OR CREATING REGIONS
 *
 * Regions are areas in your theme where you can place blocks.
 * The default regions used in themes  are "left sidebar", "right sidebar", "header", and "footer",  although you can create
 * as many regions as you want.  Once declared, they are made available to the page.tpl.php file as a variable.  
 * For instance, use <?php print $header ?> for the placement of the "header" region in page.tpl.php.
 * 
 * By going to  the administer > site building > blocks page you can choose which regions various blocks should be placed.
 * New regions you define here will automatically show up in the drop-down list by their human readable name.
 */
 
 
/*
 * Declare the available regions implemented by this engine.
 *
 * @return
 *    An array of regions.  The first array element will be used as the default region for themes.
 *    Each array element takes the format: variable_name => t('human readable name')
 */
function zen_regions() {
  return array(
       'left' => t('left sidebar'),
       'right' => t('right sidebar'),
       'content_top' => t('content top'),
       'content_bottom' => t('content bottom'),
       'header' => t('header'),
       'footer' => t('footer')
  );
} 

/*
 * OVERRIDING THEME FUNCTIONS
 *
 *  The Drupal theme system uses special theme functions to generate HTML output automatically.
 *  Often we wish to customize this HTML output.  To do this, we have to override the theme function.
 *  You have to first find the theme function that generates the output, and then "catch" it and modify it here.
 *  The easiest way to do it is to copy the original function in its entirety and paste it here, changing
 *  the prefix from theme_ to zen_.  For example:
 *
 *   original:  theme_breadcrumb() 
 *   theme override:   zen_breadcrumb()
 *
 *  See the following example. In this theme, we want to change all of the breadcrumb separator links from  >> to ::
 *
 */

 /**
  * Return a themed breadcrumb trail.
  *
  * @param $breadcrumb
  *   An array containing the breadcrumb links.
  * @return a string containing the breadcrumb output.
  */
 function zen_breadcrumb($breadcrumb) {
   if (!empty($breadcrumb)) {
     return '<div class="breadcrumb">'. implode(' :: ', $breadcrumb) .'</div>';
   }
 }
 
 
/* 
 * CREATE OR MODIFY VARIABLES FOR YOUR THEME
 *
 *  The most powerful function available to themers is the _phptemplate_variables() function. It allows you
 *  to pass newly created variables to different template (tpl.php) files in your theme. Or even unset ones you don't want
 *  to use.
 *
 *  It works by switching on the hook, or name of the theme function, such as:
 *    - page
 *    - node
 *    - comment
 *    - block
 *
 * By switching on this hook you can send different variables to page.tpl.php file, node.tpl.php
 * (and any other derivative node template file, like node-forum.tpl.php), comment.tpl.php, and block.tpl.php
 *
 */

 
/**
 * Intercept template variables
 *
 * @param $hook
 *   The name of the theme function being executed
 * @param $vars
 *   A sequential array of variables passed to the theme function.
 */

function _phptemplate_variables($hook, $vars = array()) {
  switch ($hook) {
    // Send a new variable, $logged_in, to page.tpl.php to tell us if the current user is logged in or out.
    case 'page':
      // get the currently logged in user
      global $user;
      
      // An anonymous user has a user id of zero.      
      if ($user->uid > 0) {
        // The user is logged in.
        $vars['logged_in'] = TRUE;
      }
      else {
        // The user has logged out.
        $vars['logged_in'] = FALSE;
      }
      
      $body_classes = array();
      // classes for body element
      // allows advanced theming based on context (home page, node of certain type, etc.)
      $body_classes[] = ($vars['is_front']) ? 'front' : 'not-front';
      $body_classes[] = ($vars['logged_in']) ? 'logged-in' : 'not-logged-in';
      if ($vars['node']->type) {
        $body_classes[] = 'ntype-'. zen_id_safe($vars['node']->type);
      }
      switch (TRUE) {
      	case $vars['sidebar_left'] && $vars['sidebar_right'] :
      		$body_classes[] = 'both-sidebars';
      		break;
      	case $vars['sidebar_left'] :
      		$body_classes[] = 'sidebar-left';
      		break;
      	case $vars['sidebar_right'] :
      		$body_classes[] = 'sidebar-right';
      		break;
      }
      // implode with spaces
      $vars['body_classes'] = implode(' ', $body_classes);
      
      break;
      
    case 'node':
      // get the currently logged in user
      global $user;

      // set a new $is_admin variable
      // this is determined by looking at the currently logged in user and seeing if they are in the role 'admin'
      $vars['is_admin'] = in_array('admin', $user->roles);
      
      $node_classes = array('node');
      if ($vars['sticky']) {
      	$node_classes[] = 'sticky';
      }
      if (!$vars['node']->status) {
      	$node_classes[] = 'node-unpublished';
      }
      $node_classes[] = 'ntype-'. zen_id_safe($vars['node']->type);
      // implode with spaces
      $vars['node_classes'] = implode(' ', $node_classes);
      
      break;
      
    case 'comment':
      // we load the node object that the current comment is attached to
      $node = node_load($vars['comment']->nid);
      // if the author of this comment is equal to the author of the node, we set a variable
      // then in our theme we can theme this comment differently to stand out
      $vars['author_comment'] = $vars['comment']->uid == $node->uid ? TRUE : FALSE;
      break;
  }
  
  return $vars;
}
{
  static $is_forum;
  $variables = array();
  if (!isset($is_forum)) {
    if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == '') {
      $nid = arg(1);
    }
    if (arg(0) == 'comment' && arg(1) == 'reply' && is_numeric(arg(2))) {
      $nid = arg(2);
    }
    if ($nid) {
      $node = node_load(array('nid' => $nid));
    }
    $is_forum = ($node && $node->type == 'forum');
    _is_forum($is_forum);
  }
  if ($is_forum) {
    switch ($hook) {
      case 'comment' :
        $variables['template_file'] = 'node-forum';
        $variables['row_class'] = _row_class();
        $variables['name'] = $vars['author'];
        $variables['userid'] = $vars['comment']->uid;
        $joined = module_invoke('flatforum', 'get_created', $vars['comment']->uid);
        $variables['joined'] = $joined ? format_date($joined, 'custom', 'Y-m-d') : '';
        $posts = module_invoke('flatforum', 'get', $vars['comment']->uid);
        $variables['posts'] = $posts ? $posts : 0;
        $variables['submitted'] = format_date($vars['comment']->timestamp);
        $subject = $vars['comment']->subject;
        $variables['title'] = empty($subject) ? '&nbsp' : $subject;
        $variables['content'] = $vars['comment']->comment;
        $variables['links'] = empty($vars['links']) ? '&nbsp' : $vars['links'];
        break;
      case 'node' :
        $variables['row_class'] = _row_class();
        $variables['userid']=$vars['node']->uid;
        $joined = module_invoke('flatforum', 'get_created', $vars['node']->uid);
        $variables['joined'] = $joined ? format_date($joined, 'custom', 'Y-m-d') : '';
        $posts = module_invoke('flatforum', 'get', $vars['node']->uid);
        $variables['posts'] = $posts ? $posts : 0;
        $variables['title'] = empty($vars['title']) ? '&nbsp' : $vars['title'];
        $variables['content'] = $vars['node']->body;
        $variables['links'] = empty($vars['links']) ? '&nbsp' : $vars['links'];
        break;
    }
  }
  return $variables;
}
function _row_class() {
  static $forum_row = TRUE;
  $forum_row = !$forum_row;
  return $forum_row ? 'odd' : 'even';
}
function _is_forum($arg = NULL) {
  static $is_forum = FALSE;
  if ($arg) {
    $is_forum = $arg;
  }
  return $is_forum;
}

/**
* Converts a string to a suitable html ID attribute.
* - Preceeds initial numeric with 'n' character.
* - Replaces space and underscore with dash.
* - Converts entire string to lowercase.
* - Works for classes too!
* 
* @param string $string
*  the string
* @return
*  the converted string
*/
function zen_id_safe($string) {
  if (is_numeric($string{0})) {
    // if the first character is numeric, add 'n' in front
    $string = 'n'. $string;
  }
  return strtolower(preg_replace('/[^a-zA-Z0-9-]+/', '-', $string));
}
// Get rid of navigation on forum posts.
function phptemplate_forum_topic_navigation($node) {
  return '';
}

Comments

michelle’s picture

It looks to me like you're ending your _phptemplate_variables function and then sticking some of what goes in the function after it. I copied mine and took out the non flatforum mods. This should work as long as I didn't take out something I shouldn't. (Note, this is just _phptemplate_variables, which is the part you need to merge, not the entire template.php)

Michelle

--------------------------------------
My site: http://shellmultimedia.com

function _phptemplate_variables($hook, $vars = array()) {  
  // get the currently logged in user
  global $user;

  // set a new $is_admin variable
  // this is determined by looking at the currently logged in user and seeing if they are in the role 'admin'
  // the 'admin' will need to have been created manually for this to work
  // this variable is available to all templates
  $vars['is_admin'] = in_array('admin', $user->roles);
  
  switch ($hook) {
    // Send a new variable, $logged_in, to page.tpl.php to tell us if the current user is logged in or out.
    case 'page':
      global $theme, $theme_key;
      
      // Replace Edit tab with Edit Account tab
      if (arg(0) == 'user') {
        $vars['tabs'] = str_replace('Edit</a>', 'Edit Account</a>', $vars['tabs']);
      }

      // if we're in the main theme
      if ($theme == $theme_key) {
        // These next lines add additional CSS files and redefine
        // the $css and $styles variables available to your page template
        // We had previously used @import declarations in the css files,
        // but these are incompatible with the CSS caching in Drupal 5
        drupal_add_css($vars['directory'] .'/layout.css', 'theme', 'all');
        drupal_add_css($vars['directory'] .'/icons.css', 'theme', 'all');
        drupal_add_css($vars['directory'] .'/zen.css', 'theme', 'all');
        $vars['css'] = drupal_add_css($vars['directory'] .'/print.css', 'theme', 'print');
        $vars['styles'] = drupal_get_css();
      }
      
      // An anonymous user has a user id of zero.      
      if ($user->uid > 0) {
        // The user is logged in.
        $vars['logged_in'] = TRUE;
      }
      else {
        // The user has logged out.
        $vars['logged_in'] = FALSE;
      }
      
      $body_classes = array();
      // classes for body element
      // allows advanced theming based on context (home page, node of certain type, etc.)
      $body_classes[] = ($vars['is_front']) ? 'front' : 'not-front';
      $body_classes[] = ($vars['logged_in']) ? 'logged-in' : 'not-logged-in';
      if ($vars['node']->type) {
        // if on an individual node page, put the node type in the body classes
        $body_classes[] = 'ntype-'. zen_id_safe($vars['node']->type);
      }
      switch (TRUE) {
      	case $vars['sidebar_left'] && $vars['sidebar_right'] :
      		$body_classes[] = 'both-sidebars';
      		break;
      	case $vars['sidebar_left'] :
      		$body_classes[] = 'sidebar-left';
      		break;
      	case $vars['sidebar_right'] :
      		$body_classes[] = 'sidebar-right';
      		break;
      }
      // implode with spaces
      $vars['body_classes'] = implode(' ', $body_classes);
      
      break;
      
    case 'node':
      if ($vars['submitted']) {
        // we redefine the format for submitted
        // adding macrotags and 
        $vars['submitted'] =
          t('Posted <abbr class="created" title="!microdate">@date</abbr> by !username',
            array(
              '!username' => theme('username', $vars['node']),
              '@date' => format_date($vars['node']->created,'custom', "F jS, Y"),
              '!microdate' => format_date($vars['node']->created,'custom', "Y-m-dTH:i:sO")
            )
          );
      }

      // special classes for nodes
      $node_classes = array('node');
      if ($vars['sticky']) {
      	$node_classes[] = 'sticky';
      }
      if (!$vars['node']->status) {
      	$node_classes[] = 'node-unpublished';
      }
      if ($vars['node']->uid && $vars['node']->uid == $user->uid) {
        // node is authored by current user
        $node_classes[] = 'node-mine';
      }
      // class for node type: "ntype-page", "ntype-story", "ntype-my-custom-type", etc.
      $node_classes[] = 'ntype-'. zen_id_safe($vars['node']->type);
      // implode with spaces
      $vars['node_classes'] = implode(' ', $node_classes);
      
      break;
      
    case 'comment':
      // we load the node object that the current comment is attached to
      $node = node_load($vars['comment']->nid);
      // if the author of this comment is equal to the author of the node, we set a variable
      // then in our theme we can theme this comment differently to stand out
      $vars['author_comment'] = $vars['comment']->uid == $node->uid ? TRUE : FALSE;

      $comment_classes = array('comment');
      
      // odd/even handling
      static $comment_odd = TRUE;
      $comment_classes[] = $comment_odd ? 'odd' : 'even';
      $comment_odd = !$comment_odd;
      
      if ($vars['comment']->status == COMMENT_NOT_PUBLISHED) {
      	$comment_classes[] = 'comment-unpublished';
      }
      if ($vars['author_comment']) {
        // comment is by the node author
      	$comment_classes[] = 'comment-by-author';
      }
      if ($vars['comment']->uid == 0) {
        // comment is by an anonymous user
      	$comment_classes[] = 'comment-by-anon';
      }
      if ($user->uid && $vars['comment']->uid == $user->uid) {
        // comment was posted by current user
      	$comment_classes[] = 'comment-mine';
      }
      $vars['comment_classes'] = implode(' ', $comment_classes);
      
      // if comment subjects are disabled, don't display 'em
      if (variable_get('comment_subject_field', 1) == 0) {
        $vars['title'] = '';
      }
      
      break;
  }
  
  // allow subtheme to add/alter variables
  if (function_exists('zen_variables')) {
    $vars = zen_variables($hook, $vars);
  }

  // The rest of this code is for the forums, from flatforum except where noted
  static $is_forum;
  
  $variables = array();

  if (!isset($is_forum)) {
    if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == '') {
      $nid = arg(1);
    }
    if (arg(0) == 'comment' && arg(1) == 'reply' && is_numeric(arg(2))) {
      $nid = arg(2);
    }
    if ($nid) {
      $node = node_load(array('nid' => $nid));
    }
    $is_forum = ($node && $node->type == 'forum');
    _is_forum($is_forum);
      
  }

  if ($is_forum) {
    switch ($hook) {
      case 'comment' :
        $variables['is_node'] = FALSE;
        $variables['template_file'] = 'node-forum';
        $variables['row_class'] = _row_class();
        $variables['name'] = $vars['author'];
        $variables['userid'] = $vars['comment']->uid;
        $joined = module_invoke('flatforum', 'get_created', $vars['comment']->uid);
        $variables['joined'] = $joined ? format_date($joined, 'custom', 'Y-m-d') : '';
        $posts = module_invoke('flatforum', 'get', $vars['comment']->uid);
        $variables['posts'] = $posts ? $posts : 0;
        $variables['submitted'] = format_date($vars['comment']->timestamp);
        $subject = $vars['comment']->subject;
        $variables['title'] = empty($subject) ? '&nbsp' : $subject;
        $variables['content'] = $vars['comment']->comment;
        $variables['links'] = empty($vars['links']) ? '&nbsp' : $vars['links'];
        // Begin comment numbering mod
        $post_number++;
        $variables['permalink_fragment'] = 'comment-' . $vars['comment']->cid;
        $variables['is_reply'] = true;
        // End comment numbering mod
        break;
      case 'node' :
        $variables['is_node'] = TRUE;
        $variables['row_class'] = _row_class();
        $variables['userid']=$vars['node']->uid;
        $joined = module_invoke('flatforum', 'get_created', $vars['node']->uid);
        $variables['joined'] = $joined ? format_date($joined, 'custom', 'Y-m-d') : '';
        $posts = module_invoke('flatforum', 'get', $vars['node']->uid);
        $variables['posts'] = $posts ? $posts : 0;
        $variables['title'] = empty($vars['title']) ? '&nbsp' : $vars['title'];
        $variables['content'] = $vars['node']->body;
                        
        break;
    }
  }
  
  // Need to merge flatforum and other variables into the regular ones because of Zen theme weirdness
  return array_merge($vars, $variables);
}
andrewtf’s picture

I'll give it a whirl and see if it makes a difference (hopefully it does). Wish me luck. :)

Cross_and_Flame’s picture

...care to share your php_template_variables section? I've also tried to get this to work, but zen keeps erroring me out on this:
Call to undefined function: _is_forum() in <SNIP>template.php on line 199
which is this:

    $is_forum = ($node && $node->type == 'forum');
    _is_forum($is_forum);

Thanks in advance. Your forums look amazing!

andrewtf’s picture

I'm happy to share, so take a look and see if anything here helps you out. I threw in all the flatforum-related code, just in case.

function _phptemplate_variables($hook, $vars = array()) {
  switch ($hook) {
    // Send a new variable, $logged_in, to page.tpl.php to tell us if the current user is logged in or out.
    case 'page':
      // get the currently logged in user
      global $user;
      
      // An anonymous user has a user id of zero.      
      if ($user->uid > 0) {
        // The user is logged in.
        $vars['logged_in'] = TRUE;
      }
      else {
        // The user has logged out.
        $vars['logged_in'] = FALSE;
      }
      
      $body_classes = array();
      // classes for body element
      // allows advanced theming based on context (home page, node of certain type, etc.)
      $body_classes[] = ($vars['is_front']) ? 'front' : 'not-front';
      $body_classes[] = ($vars['logged_in']) ? 'logged-in' : 'not-logged-in';
      if ($vars['node']->type) {
        $body_classes[] = 'ntype-'. zen_id_safe($vars['node']->type);
      }
      switch (TRUE) {
      	case $vars['sidebar_left'] && $vars['sidebar_right'] :
      		$body_classes[] = 'both-sidebars';
      		break;
      	case $vars['sidebar_left'] :
      		$body_classes[] = 'sidebar-left';
      		break;
      	case $vars['sidebar_right'] :
      		$body_classes[] = 'sidebar-right';
      		break;
      }
      // implode with spaces
      $vars['body_classes'] = implode(' ', $body_classes);
      
      break;
      
    case 'node':
      // get the currently logged in user
      global $user;

      // set a new $is_admin variable
      // this is determined by looking at the currently logged in user and seeing if they are in the role 'admin'
      $vars['is_admin'] = in_array('admin', $user->roles);
      
      $node_classes = array('node');
      if ($vars['sticky']) {
      	$node_classes[] = 'sticky';
      }
      if (!$vars['node']->status) {
      	$node_classes[] = 'node-unpublished';
      }
      $node_classes[] = 'ntype-'. zen_id_safe($vars['node']->type);
      // implode with spaces
      $vars['node_classes'] = implode(' ', $node_classes);
      
      break;
      
    case 'comment':
      // we load the node object that the current comment is attached to
      $node = node_load($vars['comment']->nid);
      // if the author of this comment is equal to the author of the node, we set a variable
      // then in our theme we can theme this comment differently to stand out
      $vars['author_comment'] = $vars['comment']->uid == $node->uid ? TRUE : FALSE;
      break;
  }
  
// The rest of this code is for the forums, from flatforum except where noted
  static $is_forum;
 
  $variables = array();

  if (!isset($is_forum)) {
    if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == '') {
      $nid = arg(1);
    }
    if (arg(0) == 'comment' && arg(1) == 'reply' && is_numeric(arg(2))) {
      $nid = arg(2);
    }
    if ($nid) {
      $node = node_load(array('nid' => $nid));
    }
    $is_forum = ($node && $node->type == 'forum');
    _is_forum($is_forum);
     
  }

  if ($is_forum) {
    switch ($hook) {
      case 'comment' :
        $variables['is_node'] = FALSE;
        $variables['template_file'] = 'node-forum';
        $variables['row_class'] = _row_class();
        $variables['name'] = $vars['author'];
        $variables['userid'] = $vars['comment']->uid;
        $joined = module_invoke('flatforum', 'get_created', $vars['comment']->uid);
        $variables['joined'] = $joined ? format_date($joined, 'custom', 'Y-m-d') : '';
        $posts = module_invoke('flatforum', 'get', $vars['comment']->uid);
        $variables['posts'] = $posts ? $posts : 0;
        $variables['submitted'] = format_date($vars['comment']->timestamp);
        $subject = $vars['comment']->subject;
        $variables['title'] = empty($subject) ? '&nbsp' : $subject;
        $variables['content'] = $vars['comment']->comment;
        $variables['links'] = empty($vars['links']) ? '&nbsp' : $vars['links'];
        // Begin comment numbering mod
        $post_number++;
        $variables['permalink_fragment'] = 'comment-' . $vars['comment']->cid;
        $variables['is_reply'] = true;
        // End comment numbering mod
        break;
      case 'node' :
        $variables['is_node'] = TRUE;
        $variables['row_class'] = _row_class();
        $variables['userid']=$vars['node']->uid;
        $joined = module_invoke('flatforum', 'get_created', $vars['node']->uid);
        $variables['joined'] = $joined ? format_date($joined, 'custom', 'Y-m-d') : '';
        $posts = module_invoke('flatforum', 'get', $vars['node']->uid);
        $variables['posts'] = $posts ? $posts : 0;
        $variables['title'] = empty($vars['title']) ? '&nbsp' : $vars['title'];
        $variables['content'] = $vars['node']->body;
                       
        break;
    }
  }
 
  // Need to merge flatforum and other variables into the regular ones because of Zen theme weirdness
  return array_merge($vars, $variables);
}

function _row_class() {
  static $forum_row = TRUE;
  $forum_row = !$forum_row;
  return $forum_row ? 'odd' : 'even';
}
function _is_forum($arg = NULL) {
  static $is_forum = FALSE;
  if ($arg) {
    $is_forum = $arg;
  }
  return $is_forum;
}

I know I had to do something else to get things working, but for the life of me I don't recall what it was. Must not have been too difficult, given the fact that I figured it out on my own.

Cross_and_Flame’s picture

Yeah, I kept erroring out, but a cut-and-paste worked, then adding back my customizations worked too.

Thanks friend. I appreciate ya!

andrewtf’s picture

Now if I can just figure out why the links ($links) at the bottom of the forum posts are FUBAR in IE6, I'll have a decent forum.

ryooki’s picture

this code worked for me, such that I didn't get any errors, but the flat forums still didn't display correctly. :( I still had threaded comments. Instead of comments being large boxes that spanned the entire page, they still shrink down into little columns.

vm’s picture

goto administer -> comments
click on the settings tab
change Default display mode: to Flat list