2 Column Layout

Allows you to show your forums in a 2 column layout, rather than 1 long list.

Please note that I did not write this code, it was written by members of the phpBB Team (credited at the end of this page). This snippet is only supported with prosilver based styles, however there is code for subSilver2 based styles.

#
#-----[ OPEN ]------------------------------------------
#
includes/functions_display.php
#
#-----[ FIND ]------------------------------------------
#
        $last_catless = $catless;
    }  
#
#-----[ AFTER ADD ]------------------------------------------
#
    //
    // Start category based loops
    // Credits to Noxwizard of phpBB.com for this code
    //

    //Sort forums by category

    $cat_array = array();

    foreach($forum_rows as $forum)
    {
       if ($forum['forum_type'] == FORUM_CAT)
       {
          $cat_array[$forum['forum_id']] = $forum;
       }
       else
       {
          $id = $forum['parent_id'];
          @$cat_array[$id]['children'][@count(@$cat_array[$id]['children'])] = $forum;
       }
    }

    //Loop through the categories
    foreach($cat_array as $cat)
    {

    //Category
    $template->assign_block_vars('catrow', array(
       'FORUM_ID'         => $cat['forum_id'],
       'FORUM_NAME'         => $cat['forum_name'],
       'FORUM_DESC'         => generate_text_for_display($cat['forum_desc'], $cat['forum_desc_uid'], $cat['forum_desc_bitfield'], $cat['forum_desc_options']),
       'FORUM_FOLDER_IMG'            => '',
       'FORUM_FOLDER_IMG_SRC'   => '',
       'FORUM_IMAGE'         => ($cat['forum_image']) ? '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $cat['forum_id']) . '"><img src="' . $phpbb_root_path . $cat['forum_image'] . '" alt="' . $user->lang['FORUM_CAT'] . '" /></a>' : '',
       'FORUM_IMAGE_SRC'      => ($cat['forum_image']) ? $phpbb_root_path . $cat['forum_image'] : '',
       'CHILDREN_COUNT'      => count($cat['children']),
       'U_VIEWFORUM'         => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $cat['forum_id']))
    );

       //Forums under category
       foreach($cat['children'] as $row)
       {
          $visible_forums++;
          $forum_id = $row['forum_id'];
          
          $forum_unread = (isset($forum_tracking_info[$forum_id]) && $row['orig_forum_last_post_time'] > $forum_tracking_info[$forum_id]) ? true : false;

          $folder_image = $folder_alt = $l_subforums = '';
          $subforums_list = array();

          // Generate list of subforums if we need to
          if (isset($subforums[$forum_id]))
          {
             foreach ($subforums[$forum_id] as $subforum_id => $subforum_row)
             {
                $subforum_unread = (isset($forum_tracking_info[$subforum_id]) && $subforum_row['orig_forum_last_post_time'] > $forum_tracking_info[$subforum_id]) ? true : false;

                if ($subforum_row['display'] && $subforum_row['name'])
                {
                   $subforums_list[] = array(
                      'link'      => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $subforum_id),
                      'name'      => $subforum_row['name'],
                      'unread'      => $subforum_unread,
                   );
                }
                else
                {
                   unset($subforums[$forum_id][$subforum_id]);
                }

                // If one subforum is unread the forum gets unread too...
                if ($subforum_unread)
                {
                   $forum_unread = true;
                }
             }

             $l_subforums = (sizeof($subforums[$forum_id]) == 1) ? $user->lang['SUBFORUM'] . ': ' : $user->lang['SUBFORUMS'] . ': ';
             $folder_image = ($forum_unread) ? 'forum_unread_subforum' : 'forum_read_subforum';
          }
          else
          {
             switch ($row['forum_type'])
             {
                case FORUM_POST:
                   $folder_image = ($forum_unread) ? 'forum_unread' : 'forum_read';
                break;

                case FORUM_LINK:
                   $folder_image = 'forum_link';
                break;
             }
          }

          // Which folder should we display?
          if ($row['forum_status'] == ITEM_LOCKED)
          {
             $folder_image = ($forum_unread) ? 'forum_unread_locked' : 'forum_read_locked';
             $folder_alt = 'FORUM_LOCKED';
          }
          else
          {
             $folder_alt = ($forum_unread) ? 'NEW_POSTS' : 'NO_NEW_POSTS';
          }
          
          // Create last post link information, if appropriate
          if ($row['forum_last_post_id'])
          {
             $last_post_subject = $row['forum_last_post_subject'];
             $last_post_time = $user->format_date($row['forum_last_post_time']);
             $last_post_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $row['forum_id_last_post'] . '&p=' . $row['forum_last_post_id']) . '#p' . $row['forum_last_post_id'];
          }
          else
          {
             $last_post_subject = $last_post_time = $last_post_url = '';
          }

          // Output moderator listing ... if applicable

          $l_moderator = $moderators_list = '';
          if ($display_moderators && !empty($forum_moderators[$forum_id]))
          {
             $l_moderator = (sizeof($forum_moderators[$forum_id]) == 1) ? $user->lang['MODERATOR'] : $user->lang['MODERATORS'];
             $moderators_list = implode(', ', $forum_moderators[$forum_id]);
          }

          $l_post_click_count = ($row['forum_type'] == FORUM_LINK) ? 'CLICKS' : 'POSTS';
          $post_click_count = ($row['forum_type'] != FORUM_LINK || $row['forum_flags'] & FORUM_FLAG_LINK_TRACK) ? $row['forum_posts'] : '';

          $s_subforums_list = array();

          foreach ($subforums_list as $subforum)
          {
             $s_subforums_list[] = '<a href="' . $subforum['link'] . '" class="subforum ' . (($subforum['unread']) ? 'unread' : 'read') . '">' . $subforum['name'] . '</a>';
          }
          $s_subforums_list = (string) implode(', ', $s_subforums_list);

          if ($row['forum_type'] != FORUM_LINK)
          {
             $u_viewforum = append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $row['forum_id']);
          }
          else
          {
             // If the forum is a link and we count redirects we need to visit it
             // If the forum is having a password or no read access we do not expose the link, but instead handle it in viewforum
             if (($row['forum_flags'] & FORUM_FLAG_LINK_TRACK) || $row['forum_password'] || !$auth->acl_get('f_read', $forum_id))
             {
                $u_viewforum = append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $row['forum_id']);
             }
             else
             {
                $u_viewforum = $row['forum_link'];
             }
                   }

          $template->assign_block_vars('catrow.forumrow', array(
             'S_IS_LINK'         => ($row['forum_type'] == FORUM_LINK) ? true : false,
             'S_UNREAD_FORUM'      => $forum_unread,
             'S_LOCKED_FORUM'      => ($row['forum_status'] == ITEM_LOCKED) ? true : false,
             'S_SUBFORUMS'         => (sizeof($subforums_list)) ? true : false,

             'FORUM_ID'         => $row['forum_id'],
             'FORUM_NAME'         => $row['forum_name'],
             'FORUM_DESC'         => generate_text_for_display($row['forum_desc'], $row['forum_desc_uid'], $row['forum_desc_bitfield'], $row['forum_desc_options']),

             'TOPICS'            => $row['forum_topics'],
             $l_post_click_count         => $post_click_count,
             
             'FORUM_FOLDER_IMG'      => $user->img($folder_image, $folder_alt),
             
             'FORUM_FOLDER_IMG_SRC'   => $user->img($folder_image, $folder_alt, false, '', 'src'),

             'FORUM_IMAGE'         => ($row['forum_image']) ? '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $row['forum_id']) . '"><img src="' . $phpbb_root_path . $row['forum_image'] . '" alt="' . $user->lang[$folder_alt] . '" /></a>' : '',
             'FORUM_IMAGE_SRC'      => ($row['forum_image']) ? $phpbb_root_path . $row['forum_image'] : '',

             'LAST_POST_SUBJECT'      => censor_text($last_post_subject),
             'LAST_POST_TIME'      => $last_post_time,
             'LAST_POSTER'         => get_username_string('username', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']),
             'LAST_POSTER_COLOUR'      => get_username_string('colour', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']),
             'LAST_POSTER_FULL'      => get_username_string('full', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']),

             'MODERATORS'         => $moderators_list,
             'SUBFORUMS'         => $s_subforums_list,

             'L_SUBFORUM_STR'      => $l_subforums,
             'L_FORUM_FOLDER_ALT'      => $folder_alt,
             'L_MODERATOR_STR'      => $l_moderator,

             'U_VIEWFORUM'         => $u_viewforum,
             'U_LAST_POSTER'         => get_username_string('profile', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']),
             'U_LAST_POST'         => $last_post_url)
          );

          // Assign subforums loop for style authors
          foreach ($subforums_list as $subforum)
          {
             $template->assign_block_vars('forumrow.subforum', array(
                'U_SUBFORUM'      => $subforum['link'],
                'SUBFORUM_NAME'   => $subforum['name'],
                'S_UNREAD'      => $subforum['unread'])
             );
          }
       }
    }
    //
    // End category based loops
    //

For the next part, you need to replace your entire forumlist_body.html file. I recommend backing up this file in case you ever want to revert back. There is also multiple ways to set this up, more details below.

Change the DEFINE $FORUMS to 1 in this part to specify the max number of forums before it starts putting them into a second column. This is the output:

Setting DEFINE $FORUMS = 3 will give this output: (Notice that the 2nd catagory only has 2 forum, so it's displayed as normal).

forumlist_body.html replacement file
    <!-- DEFINE $FORUMS = 1 -->
    <!-- BEGIN catrow -->

       <div class="forabg">
          <div class="inner"><span class="corners-top"><span></span></span>
             <ul class="topiclist">
                <li class="header">
                   <dl class="icon">
                      <dt><!-- IF catrow.FORUM_NAME --><a href="{catrow.U_VIEWFORUM}">{catrow.FORUM_NAME}</a><!-- ELSE -->{L_FORUM}<!-- ENDIF --></dt>
                   </dl>
                </li>
             </ul>
             <!-- IF catrow.CHILDREN_COUNT > $FORUMS --><div style="float: left; width: 49.95%;"><!-- ELSE --><div style="width: 100%"><!-- ENDIF -->
                <ul class="topiclist forums">
                   <!-- BEGIN forumrow -->
                      <!-- IF forumrow.S_ROW_COUNT is even or catrow.CHILDREN_COUNT <= $FORUMS -->
                         <li class="row">
                            <dl class="icon" style="background-image: url({forumrow.FORUM_FOLDER_IMG_SRC}); background-repeat: no-repeat;">
                               <dt title="{forumrow.FORUM_FOLDER_IMG_ALT}">
                                  <!-- IF forumrow.FORUM_IMAGE --><span class="forum-image">{forumrow.FORUM_IMAGE}</span><!-- ENDIF -->
                                  <a href="{forumrow.U_VIEWFORUM}" class="forumtitle">{forumrow.FORUM_NAME}</a><br />
                                  {forumrow.FORUM_DESC}
                   <!-- IF forumrow.CLICKS -->
                      <span>{L_REDIRECTS}: {forumrow.CLICKS}</span>
                   <!-- ELSEIF not forumrow.S_IS_LINK -->
                      <br /><br />{forumrow.TOPICS} {L_TOPICS} / {forumrow.POSTS} {L_POSTS}  
                      <!-- IF forumrow.LAST_POST_TIME --> <a href="{forumrow.U_LAST_POST}" title="{forumrow.LAST_POST_TIME}">{LAST_POST_IMG} {L_LAST_POST}</a> {L_POST_BY_AUTHOR} {forumrow.LAST_POSTER_FULL}<br />
                       <!-- ELSE -->{L_NO_POSTS}<!-- ENDIF -->
                   <!-- ENDIF -->   
                                  <!-- IF forumrow.MODERATORS -->
                                     <br /><strong>{forumrow.L_MODERATOR_STR}:</strong> {forumrow.MODERATORS}
                                  <!-- ENDIF -->
                                  <!-- IF forumrow.SUBFORUMS and forumrow.S_LIST_SUBFORUMS --><br /><strong>{forumrow.L_SUBFORUM_STR}</strong> {forumrow.SUBFORUMS}<!-- ENDIF -->
                               </dt>
                            </dl>
                         </li>
                      <!-- ENDIF -->
                   <!-- END forumrow -->
                </ul>
             </div>
          </div>
          <!-- IF catrow.CHILDREN_COUNT > $FORUMS -->
          <div style="float: right; width: 49.95%;">
             <ul class="topiclist forums">
                <!-- BEGIN forumrow -->           
                   <!-- IF forumrow.S_ROW_COUNT is odd -->
                      <li class="row">
                         <dl class="icon" style="background-image: url({forumrow.FORUM_FOLDER_IMG_SRC}); background-repeat: no-repeat;">
                            <dt title="{forumrow.FORUM_FOLDER_IMG_ALT}">
                               <!-- IF forumrow.FORUM_IMAGE --><span class="forum-image">{forumrow.FORUM_IMAGE}</span><!-- ENDIF -->
                               <a href="{forumrow.U_VIEWFORUM}" class="forumtitle">{forumrow.FORUM_NAME}</a><br />
                               {forumrow.FORUM_DESC}
                   <!-- IF forumrow.CLICKS -->
                      <span>{L_REDIRECTS}: {forumrow.CLICKS}</span>
                   <!-- ELSEIF not forumrow.S_IS_LINK -->
                      <br /><br />{forumrow.TOPICS} {L_TOPICS} / {forumrow.POSTS} {L_POSTS}  
                      <!-- IF forumrow.LAST_POST_TIME --> <a href="{forumrow.U_LAST_POST}" title="{forumrow.LAST_POST_TIME}">{LAST_POST_IMG} {L_LAST_POST}</a> {L_POST_BY_AUTHOR} {forumrow.LAST_POSTER_FULL}<br />
                       <!-- ELSE -->{L_NO_POSTS}<!-- ENDIF -->
                   <!-- ENDIF -->   
                               <!-- IF forumrow.MODERATORS -->
                                  <br /><strong>{forumrow.L_MODERATOR_STR}:</strong> {forumrow.MODERATORS}
                               <!-- ENDIF -->
                               <!-- IF forumrow.SUBFORUMS and forumrow.S_LIST_SUBFORUMS --><br /><strong>{forumrow.L_SUBFORUM_STR}</strong> {forumrow.SUBFORUMS}<!-- ENDIF -->
                            </dt>
                         </dl>
                      </li>
                   <!-- ENDIF -->
                <!-- END forumrow -->
             </ul>
          </div>
          <!-- ENDIF -->

          <span class="corners-bottom"><span></span></span>
       </div>

    <!-- BEGINELSE -->
       <div class="panel">
          <div class="inner"><span class="corners-top"><span></span></span>
          <strong>{L_NO_FORUMS}</strong>
          <span class="corners-bottom"><span></span></span></div>
       </div>
    <!-- END forumrow -->

Although the screenshots above don't show it, the above code includes the code to show the last topics/posts from each forum. Here is a screenshot below that shows it. Included is how it would look with a forum image as well.

Now here is a look at some of the subforum views. Depending on how many subforums you have and what you set the DEFINE at, will change how this displays. These screenshots are based on DEFINE being 1 with 1 and 2 subforums

This is all running from a default un-modded phpBB 3.0.2. If i've missed anything, if anything prosilver template-wise doesn't work, please let me know. I would appreciate anyone trying this, to try it on their prosilver template 1st before another style to make sure it works. That way we can work out other style quirks later.

Credits: