PunBB is one of the fastest and minimal forum softwares powered by PHP. PunBB says about itself:
PunBB is a fast and lightweight PHP-powered discussion board. It is released under the GNU General Public License. Its primary goals are to be faster, smaller and less graphically intensive as compared to other discussion boards. PunBB has fewer features than many other discussion boards, but is generally faster and outputs smaller, semantically correct XHTML-compliant pages.
You can see a detailed review about PunBB from forum-software.org.
What’s the purpose this mod?
PunBB has categories for forum. But there is no categorization for Topics like many other forums. This mod implements an iconized category for topics. The end result of this mod is -
- It will add an excellent looking “Category Icons” fieldset in “Post new topic” form. (see Image#1)
- Users can (optionally) select a topic category while posting a topic.
- The category icon will be displayed beside the topic title in forum index page, topic detail page, search result etc. (see Image#2 and Image#3)
- Clicking on a category icon will show all topics under that category.(see Image#4)
Lets see some screenshot of this modification :
|
Image#1: Category icons in Post new topic form |
|
Image#2: Category icons before topic title in forum page |
|
Image#4: Filtering by category |
Let’s start
I am assuming the objective and the screenshots have eluded you if you are reading up to this, so let’s start. It’s assumed that you’ve at least some working experience on PHP (don’t mind if you’re a guru) and already installed PunBB. So, now we will start straight from modifying our working PunBB. First of all, download necessary files from below and extract it.
Download files : Topic categories for PunBB
This zip file contains -
- PHP file to modify database : install_topic_category.php file
- Sql file for sample data : sample_data.sql file
- Sample category icons : cat-icons folder
- Edited files : modified-files folder
Note: sample icons are taken from http://forums.slickdeals.net/. Thanks to slickdeals.
Now we will complete the modification in 6 easy steps. The files in modified-files folder of the downloaded package are taken from PunBB 1.2.2 just after implementing this modification. It will be easier to find and modify if you keep open the modified file when changing your copy.
1. Modify database
After extracting files, copy the install_topic_category.php to your PunBB root folder and go to http://<path_of_punbb_root>/install_topic_category.php from browser. It will create new table <db_prefix>topic_categories and new field cat_id in <db_prefix>topics table. To insert sample topic categories, run the queries of sample_data.sql. Then copy the cat-icons folder to <punbb_root>/img.
Note : Before executing the queries, change the word <table_prefix> as your table prefix.
Note : All your category icons should keep in <punbb_root>/img/cat-icons folder.
2. Add categories field to “Post new topic” form
Open post.php file.
Find this line (line: 35)
$fid = isset($_GET['fid']) ? intval($_GET['fid']) : 0;
Add this line below
$topic_category = isset($_POST['t_cat_id']) ? intval($_POST['t_cat_id']) : 0;
else if ($fid) { // Create the topic $db->query('INSERT INTO '.$db->prefix.'topics (poster, subject, posted, last_post, last_poster, forum_id) VALUES(\''.$db->escape($username).'\', \''.$db->escape($subject).'\', '.$now.', '.$now.', \''.$db->escape($username).'\', '.$fid.')') or error('Unable to create topic', __FILE__, __LINE__, $db->error());
$db->query('INSERT INTO '.$db->prefix.'topics (poster, subject, posted, last_post, last_poster, forum_id, cat_id) VALUES(\''.$db->escape($username).'\', \''.$db->escape($subject).'\', '.$now.', '.$now.', \''.$db->escape($username).'\', '.$fid.', '.$topic_category.')') or error('Unable to create topic', __FILE__, __LINE__, $db->error());
$checkboxes = array(); if (!$pun_user['is_guest']) {
Add this code just above the “$checkboxes = array();”
if ($fid): ?> <fieldset> <legend>Category(optional)</legend> <div class="infldset"> You may choose a category icon for your message from the following list:<br> <div class="rbox"> <?php $cat_result = $db->query('SELECT * FROM '.$db->prefix.'topic_categories') or error('Unable to fetch topic category list', __FILE__, __LINE__, $db->error()); while ($cur_topic_cat = $db->fetch_assoc($cat_result)): ?> <span class="topic-cat"> <input type="radio" value='<?php echo $cur_topic_cat['id']?>' name="t_cat_id"> <img src="<?php echo PUN_ROOT . 'img/cat-icons/' .$cur_topic_cat['cat_icon'] ?>" alt="<?php echo $cur_topic_cat['cat_name']?>" align="top""> </span> <?php endwhile; ?> <div style="clear:both; height: 0px"> </div> </div> </div> </fieldset> <?php endif;
Almost done. Just add this css to your template’s css file or put in header.php after line 80. Use <style> tag to add this in header.php
DIV.cat-icon { width: 47; height: 16; margin: 0px 5px; FLOAT: left; DISPLAY: block; border: none; } span.topic-cat{ display: block; float: left; width: 100px; padding: 2px; } span.topic-cat input{ margin-right: 2px; } span.topic-cat img{ @margin-top: 3px; }
Now you should see a fieldset in your form like Image#1.
Verify this change: Go to “Post new topic” page and see if their is a fieldset containing category icons. Post a topic with selecting the category “Media”. Check the <prefix>topics table in database. ‘11′ should be the value of cat_id field for last topic.
3. Display category icon in topic list
To display category icons in topic list, we have to modify 3 lines in viewforum.php.
Open the viewforum.php and find this lines (line:110)
if ($pun_user['is_guest'] || $pun_config['o_show_dot'] == '0') { // Without "the dot" $sql = 'SELECT id, poster, subject, posted, last_post, last_post_id, last_poster, num_views, num_replies, closed, sticky, moved_to FROM '.$db->prefix.'topics WHERE forum_id='.$id.' ORDER BY sticky DESC, '.(($cur_forum['sort_by'] == '1') ? 'posted' : 'last_post').' DESC LIMIT '.$start_from.', '.$pun_user['disp_topics'];
Change the query of line 113 with this:
$sql = 'SELECT t.id, poster, subject, posted, last_post, last_post_id, last_poster, num_views, num_replies, closed, sticky, moved_to, tc.id as t_cat_id, tc.cat_name, tc.cat_icon FROM '.$db->prefix.'topics as t LEFT JOIN '.$db->prefix.'topic_categories AS tc ON t.cat_id=tc.id WHERE forum_id='.$id.' ORDER BY sticky DESC, '.(($cur_forum['sort_by'] == '1') ? 'posted' : 'last_post').' DESC LIMIT '.$start_from.', '.$pun_user['disp_topics'];
And, Just after 7 lines of this change, the query below “‘case ‘mysqli’:” change with this one:
$sql = 'SELECT p.poster_id AS has_posted, t.id, t.subject, t.poster, t.posted, t.last_post, t.last_post_id, t.last_poster, t.num_views, t.num_replies, t.closed, t.sticky, t.moved_to, tc.id as t_cat_id, tc.cat_name, tc.cat_icon FROM '.$db->prefix.'topics AS t LEFT JOIN '.$db->prefix.'posts AS p ON t.id=p.topic_id AND p.poster_id='.$pun_user['id'].' LEFT JOIN '.$db->prefix.'topic_categories AS tc ON t.cat_id=tc.id WHERE t.forum_id='.$id.' GROUP BY t.id ORDER BY sticky DESC, '.(($cur_forum['sort_by'] == '1') ? 'posted' : 'last_post').' DESC LIMIT '.$start_from.', '.$pun_user['disp_topics'];
If your database is sqlite, you have to change the query below “case ’sqlite’:” instead of the above.
Now find this line: (line: 221 originally/226 after applying changes above.)
<div class="<?php echo $icon_type ?>"><div class="nosize"><?php echo trim($icon_text) ?></div></div>
Add this lines below
<?php if(!empty($cur_topic['cat_icon'])): ?> <div class="cat-icon"> <a href="<?php echo 'search.php?action=show_cat&t_cat_id='. $cur_topic['t_cat_id'] ?>"><img src="<?php echo PUN_ROOT . 'img/cat-icons/' .$cur_topic['cat_icon'] ?>" alt="<?php echo $cur_topic['cat_name']?>" title="<?php echo $cur_topic['cat_name']?>"></a> </div> <?php endif; ?>
Ok, Done. Now if you go to index of a forum, you should see category icons at the left side of topics(for whose category icon was selected) as shown in image#2.
Verify this change: Go to the forum index in which you have posted a new topic in previous step. See if there is an icon of media before the new topic title.
4. Display category icon in Topic details page
Now we will change in viewtopic.php to show icons in topic page.
Open the file and go to this line (line: 96)
// Fetch some info about the topic if (!$pun_user['is_guest'])
$result = $db->query('SELECT t.subject, t.closed, t.num_replies, t.sticky, f.id AS forum_id, f.forum_name, f.moderators, fp.post_replies, s.user_id AS is_subscribed, tc.id as t_cat_id, tc.cat_name, tc.cat_icon FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'subscriptions AS s ON (t.id=s.topic_id AND s.user_id='.$pun_user['id'].') LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') LEFT JOIN '.$db->prefix.'topic_categories AS tc ON t.cat_id=tc.id WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.id='.$id.' AND t.moved_to IS NULL') or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error());
And replace the other query (used for else) with the query below:
$result = $db->query('SELECT t.subject, t.closed, t.num_replies, t.sticky, f.id AS forum_id, f.forum_name, f.moderators, fp.post_replies, 0, tc.id as t_cat_id, tc.cat_name, tc.cat_icon FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') LEFT JOIN '.$db->prefix.'topic_categories AS tc ON t.cat_id=tc.id WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.id='.$id.' AND t.moved_to IS NULL') or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error());
Find this line (Line: 315 originally/ 339 after applying the changes above)
<h2><span><span class="conr">#<?php echo ($start_from + $post_count) ?> </span><a href="viewtopic.php?pid=<?php echo $cur_post['id'].'#p'.$cur_post['id'] ?>"><?php echo format_time($cur_post['posted']) ?></a></span></h2>
Replace with this lines:
<h2>
<span>
<span class="conr">#<?php echo ($start_from + $post_count) ?> </span><a href="viewtopic.php?pid=<?php echo $cur_post['id'].'#p'.$cur_post['id'] ?>"><?php echo format_time($cur_post['posted']) ?></a>
<?php if(!isset($category_printed) && !empty($cur_topic['cat_icon'])): ?>
<a href="<?php echo 'search.php?action=show_cat&t_cat_id='. $cur_topic['t_cat_id'] ?>"><img align="top" src="<?php echo PUN_ROOT . 'img/cat-icons/' .$cur_topic['cat_icon'] ?>" alt="<?php echo $cur_topic['cat_name']?>" title="<?php echo $cur_topic['cat_name']?>"></a>
<?php
$category_printed = true;
endif;
?>
</span>
</h2>
You will see the category icon after the posting time in topic details page after applying the changes above as shown in Image#3.
Verify this change: Click on a the topic title which you posted in step 2. In the details page of the topic, check there is an icon of media after posting time of first post of topic.
5. Display category icon in search result
Here we will change the search.php so that icons appears in the listing of search result. First open the search.php and go to line 462. Replace the query of else block with:
$sql = 'SELECT t.id AS tid, t.poster, t.subject, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.closed, t.forum_id, tc.id as t_cat_id, tc.cat_name, tc.cat_icon FROM '.$db->prefix.'topics AS t LEFT JOIN '.$db->prefix.'topic_categories AS tc ON t.cat_id=tc.id WHERE t.id IN('.$search_results.') ORDER BY '.$sort_by_sql;
Find this line of search.php (line: 644 originally/650 after applying changes above.)
<div class="tclcon">
<div class="cat-icon"> <a href="<?php echo 'search.php?action=show_cat&t_cat_id='. $search_set[$i]['t_cat_id'] ?>"><img src="<?php echo PUN_ROOT . 'img/cat-icons/' . $search_set[$i]['cat_icon'] ?>" alt="<?php echo $search_set[$i]['cat_name']?>" title="<?php echo $search_set[$i]['cat_name']?>"></a> </div>
Ok. Now you should see Category Icons in search result as other pages.
6. Filtering (or displaying) by category
At last, we will make icons enable for filtering. After completing this step, if you click on a category icon, it will show all topics which were posted under this topic category. This change will also happen in search.php.
Find this line in search.php (line 85)
// If it's a user search (by id) else if ($action == 'show_user')
Add the following elseif block after ending of this elseif :
else if ($action == 'show_cat') { $topic_cat_id = intval($_GET['t_cat_id']); if ($topic_cat_id < 1) message($lang_common['Bad request']); }
Find this line (Line: 321 originally/ 327 after applying the changes above)
else if ($action == 'show_new' || $action == 'show_24h' || $action == 'show_user' || $action == 'show_subscriptions' || $action == 'show_unanswered')
And replace with this line:
else if ($action == 'show_new' || $action == 'show_24h' || $action == 'show_user' || $action == 'show_subscriptions' || $action == 'show_unanswered' || $action == 'show_cat')
Find this line (Line: 344 originally/ 350 after applying the changes above)
// If it's a search for posts by a specific user ID else if ($action == 'show_user')
Add the following elseif block after closing of this elseif :
else if ($action == 'show_cat') { $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.cat_id='.$topic_cat_id.' GROUP BY t.id') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error()); $num_hits = $db->num_rows($result); if (!$num_hits) message($lang_search['No user posts']); }
Everything is done. Now your icons are enabled to filtering topics.
Verify this change : Post 3 topics under 3 different forum with same topic category. And, from anywhere click on this category icon. Now you should see these 3 topics together as image#4.
We’re finished implementing Topic categories for PunBB. You can ask me anything about this modification. I will try my best to reply. Thanks a lot for staying this l-o-n-g time with ajaxray.