Uutiset:

Wondering if this will always be free?  See why free is better.

Main Menu
Advertisement:

Add [Category Name] to [Recent Posts] - HowTo?

Aloittaja vast, marraskuu 30, 2011, 02:39:24 IP

« edellinen - seuraava »

vast

I have a forum with 2 categorys and lots of boards in each of them. Below the Categories there is -one- Recent Posts field (showing the 10 latest posts)
lets say category 1 includes boards about cooking food.
and category 2 is about java programming.
both have nothing to do with each other, but the recent posts field mixes them together if they were just one category...

so my question is, how can I handle different categories within one recent posts field?

The perfect solution for me would be to add the category-name to each line in the recent posts field. it should look like:
[category name][boardname][Title of the Post] by [Author]
(without the bold section above, it would just be the default view of recent posts)

I tried to add a piece of code myself but failed as I don't have the deep insight to the code.
I found the following section in the BoardIndex.template.php (of my prefered theme):


// Show lots of posts.
elseif (!empty($context['latest_posts']))
{
echo '
<table width="100%" border="0">';
/* Each post in latest_posts has:
board (with an id, name, and link.), topic (the topic's id.), poster (with id, name, and link.),
subject, short_subject (shortened with...), time, link, and href. */
foreach ($context['latest_posts'] as $post)
echo '
<tr>
<td align="right" valign="top" nowrap="nowrap">[', $post['board']['link'], ']</td>
<td valign="top">', $post['link'], ' ', $txt[525], ' ', $post['poster']['link'], '</td>
<td align="right" valign="top" nowrap="nowrap">', $post['time'], '</td>
</tr>';
echo '
</table>';
}


I guess <td align="right" valign="top" nowrap="nowrap">[', $post['board']['link'], ']</td> is the magic line.

$post (or $context['latest_posts']) doesn't have any entry for the category-name, which I actually want to list here. (tested with var_dump).
I looked forward to $context['categories'], but I didn't get the connection between the current "recent post" and it's category.

Please, could somebody help me get the category name to the recent posts field?



vast

#1
I was just looking again at this case.

the $context['latest_posts'] array is defined in sourcedir/BoardIndex.php.
In BoardIndex.php the getLastPosts() function is called, which is defined in sourcedir/Recent.php.

The Recent.php got this getLastPosts() function which does a lot of mysql actions to get the board and message data.

So.. to get the Category to the Recent Posts table, I guess I need to add something to the MySQL Query to get the Category of the current message observed.

Any detailed help or solutions are welcome :)


the getLastPosts(); function:

function getLastPosts($showlatestcount)
{
global $scripturl, $txt, $db_prefix, $user_info, $modSettings, $func;

// Find all the posts.  Newer ones will have higher IDs.  (assuming the last 20 * number are accessable...)
// !!!SLOW This query is now slow, NEEDS to be fixed.  Maybe break into two?
$request = db_query("
SELECT
m.posterTime, m.subject, m.ID_TOPIC, m.ID_MEMBER, m.ID_MSG,
IFNULL(mem.realName, m.posterName) AS posterName, t.ID_BOARD, b.name AS bName,
LEFT(m.body, 384) AS body, m.smileysEnabled
FROM ({$db_prefix}messages AS m, {$db_prefix}topics AS t, {$db_prefix}boards AS b)
LEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = m.ID_MEMBER)
WHERE m.ID_MSG >= " . max(0, $modSettings['maxMsgID'] - 20 * $showlatestcount) . "
AND t.ID_TOPIC = m.ID_TOPIC
AND b.ID_BOARD = t.ID_BOARD" . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? "
AND b.ID_BOARD != $modSettings[recycle_board]" : '') . "
AND $user_info[query_see_board]
ORDER BY m.ID_MSG DESC
LIMIT $showlatestcount", __FILE__, __LINE__);
$posts = array();
while ($row = mysql_fetch_assoc($request))
{
// Censor the subject and post for the preview ;).
censorText($row['subject']);
censorText($row['body']);

$row['body'] = strip_tags(strtr(parse_bbc($row['body'], $row['smileysEnabled'], $row['ID_MSG']), array('<br />' => '&#10;')));
if ($func['strlen']($row['body']) > 128)
$row['body'] = $func['substr']($row['body'], 0, 128) . '...';

// Build the array.
$posts[] = array(
'board' => array(
'id' => $row['ID_BOARD'],
'name' => $row['bName'],
'href' => $scripturl . '?board=' . $row['ID_BOARD'] . '.0',
'link' => '<a href="' . $scripturl . '?board=' . $row['ID_BOARD'] . '.0">' . $row['bName'] . '</a>'
),
'topic' => $row['ID_TOPIC'],
'poster' => array(
'id' => $row['ID_MEMBER'],
'name' => $row['posterName'],
'href' => empty($row['ID_MEMBER']) ? '' : $scripturl . '?action=profile;u=' . $row['ID_MEMBER'],
'link' => empty($row['ID_MEMBER']) ? $row['posterName'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_MEMBER'] . '">' . $row['posterName'] . '</a>'
),
'subject' => $row['subject'],
'short_subject' => shorten_subject($row['subject'], 24),
'preview' => $row['body'],
'time' => timeformat($row['posterTime']),
'timestamp' => forum_time(true, $row['posterTime']),
'raw_timestamp' => $row['posterTime'],
'href' => $scripturl . '?topic=' . $row['ID_TOPIC'] . '.msg' . $row['ID_MSG'] . ';topicseen#msg' . $row['ID_MSG'],
'link' => '<a href="' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '.msg' . $row['ID_MSG'] . ';topicseen#msg' . $row['ID_MSG'] . '">' . $row['subject'] . '</a>'
);
}
mysql_free_result($request);

return $posts;
}

vast

#2
Ok Guys.. I solved the Problem by myself. In Case anyone wants the same feature in the future, I'll write the solution down.

Here is how I did it and what you have to do:

First, you have to expand the MySQL query of the getLastPosts() function found in /sources/Recent.php so that the Category id and name is coming with the rest of the information.

Second, you have to alter the BoardIndex.template.php (of your theme) and add the Category-name to the Place where you want to have it (in my case: in front of every "recent posts"-line)


Here is the Code I Added (marked red)

sources\Recent.php - getLastPosts() function:



function getLastPosts($showlatestcount)
{
   global $scripturl, $txt, $db_prefix, $user_info, $modSettings, $func;

   // Find all the posts.  Newer ones will have higher IDs.  (assuming the last 20 * number are accessable...)
   // !!!SLOW This query is now slow, NEEDS to be fixed.  Maybe break into two?
   $request = db_query("
      SELECT
         m.posterTime, m.subject, hxxp:m.id [nonactive]_TOPIC, hxxp:m.id [nonactive]_MEMBER, hxxp:m.id [nonactive]_MSG,
         IFNULL(mem.realName, m.posterName) AS posterName, hxxp:t.id [nonactive]_BOARD, hxxp:b.name [nonactive] AS bName, hxxp:b.id [nonactive]_CAT AS bIDcat,
         LEFT(m.body, 384) AS body, m.smileysEnabled, hxxp:c.id [nonactive]_CAT AS cIDcat, hxxp:c.name [nonactive] AS cName
      FROM ({$db_prefix}messages AS m, {$db_prefix}topics AS t, {$db_prefix}boards AS b, {$db_prefix}categories AS c)
         LEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = hxxp:m.id [nonactive]_MEMBER)
      WHERE hxxp:m.id [nonactive]_MSG >= " . max(0, $modSettings['maxMsgID'] - 20 * $showlatestcount) . "
         AND hxxp:t.id [nonactive]_TOPIC = hxxp:m.id [nonactive]_TOPIC
         AND hxxp:b.id [nonactive]_BOARD = hxxp:t.id [nonactive]_BOARD" . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? "
         AND hxxp:b.id [nonactive]_BOARD != $modSettings[recycle_board]" : '') . "
         AND hxxp:c.id [nonactive]_CAT = hxxp:b.id [nonactive]_CAT
         AND $user_info[query_see_board]
      ORDER BY hxxp:m.id [nonactive]_MSG DESC
      LIMIT $showlatestcount", __FILE__, __LINE__);
   $posts = array();
   while ($row = mysql_fetch_assoc($request))
   {
      // Censor the subject and post for the preview ;).
      censorText($row['subject']);
      censorText($row['body']);

      $row['body'] = strip_tags(strtr(parse_bbc($row['body'], $row['smileysEnabled'], $row['ID_MSG']), array('<br />' => '&#10;')));
      if ($func['strlen']($row['body']) > 128)
         $row['body'] = $func['substr']($row['body'], 0, 128) . '...';

      // Build the array.
      $posts[] = array(
         'category' => array(
            'id' => $row['cIDcat'],
            'name' => $row['cName']
         ),

         'board' => array(
            'id' => $row['ID_BOARD'],
            'name' => $row['bName'],
            'href' => $scripturl . '?board=' . $row['ID_BOARD'] . '.0',
            'link' => '<a href="' . $scripturl . '?board=' . $row['ID_BOARD'] . '.0">' . $row['bName'] . '</a>',
            'idcat' => $row['bIDcat']

         ),
         'topic' => $row['ID_TOPIC'],
         'poster' => array(
            'id' => $row['ID_MEMBER'],
            'name' => $row['posterName'],
            'href' => empty($row['ID_MEMBER']) ? '' : $scripturl . '?action=profile;u=' . $row['ID_MEMBER'],
            'link' => empty($row['ID_MEMBER']) ? $row['posterName'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_MEMBER'] . '">' . $row['posterName'] . '</a>'
         ),
         'subject' => $row['subject'],
         'short_subject' => shorten_subject($row['subject'], 24),
         'preview' => $row['body'],
         'time' => timeformat($row['posterTime']),
         'timestamp' => forum_time(true, $row['posterTime']),
         'raw_timestamp' => $row['posterTime'],
         'href' => $scripturl . '?topic=' . $row['ID_TOPIC'] . '.msg' . $row['ID_MSG'] . ';topicseen#msg' . $row['ID_MSG'],
         'link' => '<a href="' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '.msg' . $row['ID_MSG'] . ';topicseen#msg' . $row['ID_MSG'] . '">' . $row['subject'] . '</a>'
      );
   }
   mysql_free_result($request);

   return $posts;
}



here I'm going to add the new Category-name information in front of each "recent post":
smf/Themes/<yourtheme>/BoardIndex.template.php



   // This is the "Recent Posts" bar.
   if (!empty($settings['number_recent_posts']))
   {
      echo '
   <tr>
      <td class="catbg" colspan="2">', $txt[214], '</td>
   </tr>
   <tr>
      <td class="windowbg" width="20" valign="middle" align="center">
         <a href="', $scripturl, '?action=recent">
            <img src="', $settings['images_url'], '/post/xx.gif" alt="', $txt[214], '" border="0" /></a>
      </td>
      <td class="windowbg2">';

      // Only show one post.
      if ($settings['number_recent_posts'] == 1)
      {
         // latest_post has link, href, time, subject, short_subject (shortened with...), and topic. (its id.)
         echo '
         <b><a href="', $scripturl, '?action=recent">', $txt[214], '</a></b>
         <div class="smalltext">
            ', $txt[234], ' &quot;', $context['latest_post']['link'], '&quot; ', $txt[235], ' (', $context['latest_post']['time'], ')<br />
         </div>';
      }
      // Show lots of posts.
      elseif (!empty($context['latest_posts']))
      {
         echo '
         <table width="100%" border="0">';
         /* Each post in latest_posts has:
            board (with an id, name, and link.), topic (the topic's id.), poster (with id, name, and link.),
            subject, short_subject (shortened with...), time, link, and href. */
         foreach ($context['latest_posts'] as $post)
            echo '
            <tr>
               <td align="right" valign="top" nowrap="nowrap">&#187; ',$post['category']['name'],' [', $post['board']['link'], ']</td>
               <td valign="top">', $post['link'], ' ', $txt[525], ' ', $post['poster']['link'], '</td>
               <td align="right" valign="top" nowrap="nowrap">', $post['time'], '</td>         
            </tr>';
         echo '
         </table>';
      }
      echo '
      </td>
   </tr>';
   }





And That's it!
I'm still a bit surprised that I could solve it for myself, as I'm really not that experienced with smf and coding ^^

Good luck to everyone who needs this in the future.



vast

If anybody needs this (Categories in Recent Posts) for SMF v2.0.7+, here is what you need to change.

I upgraded SMF1 to SMF2 and had to customize the new recent posts code as it was different from the old one.


This time you need to adjust the code of the following file/function in your SMF Installation dir: /Sources/Subs-Recent.php

I colored the changes to RED. Add the RED pieces of code.

// Get the latest posts of a forum.
function getLastPosts($latestPostOptions)
{
   global $scripturl, $txt, $user_info, $modSettings, $smcFunc, $context;

   // Find all the posts.  Newer ones will have higher IDs.  (assuming the last 20 * number are accessable...)
   // !!!SLOW This query is now slow, NEEDS to be fixed.  Maybe break into two?
   $request = $smcFunc['db_query']('substring', '
      SELECT
         m.poster_time, m.subject, hxxp:m.id [nonactive]_topic, hxxp:m.id [nonactive]_member, hxxp:m.id [nonactive]_msg,
         IFNULL(mem.real_name, m.poster_name) AS poster_name, hxxp:t.id [nonactive]_board, hxxp:b.name [nonactive] AS board_name, hxxp:b.id [nonactive]_CAT AS bIDcat,
         SUBSTRING(m.body, 1, 385) AS body, m.smileys_enabled, hxxp:c.id [nonactive]_cat AS cIDcat, hxxp:c.name [nonactive] AS cName
      FROM {db_prefix}messages AS m
         INNER JOIN {db_prefix}topics AS t ON (t.id_topic = hxxp:m.id [nonactive]_topic)
         INNER JOIN {db_prefix}boards AS b ON (b.id_board = hxxp:t.id [nonactive]_board)
         INNER JOIN {db_prefix}categories AS c ON (c.id_cat = hxxp:b.id [nonactive]_cat)
         LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = hxxp:m.id [nonactive]_member)
      WHERE hxxp:m.id [nonactive]_msg >= {int:likely_max_msg}' .
         (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? '
         AND hxxp:b.id [nonactive]_board != {int:recycle_board}' : '') . '
         AND {query_wanna_see_board}' . ($modSettings['postmod_active'] ? '
         AND t.approved = {int:is_approved}
         AND m.approved = {int:is_approved}' : '') . '
      ORDER BY hxxp:m.id [nonactive]_msg DESC
      LIMIT ' . $latestPostOptions['number_posts'],
      array(
         'likely_max_msg' => max(0, $modSettings['maxMsgID'] - 50 * $latestPostOptions['number_posts']),
         'recycle_board' => $modSettings['recycle_board'],
         'is_approved' => 1,
      )
   );
   $posts = array();
   while ($row = $smcFunc['db_fetch_assoc']($request))
   {
      // Censor the subject and post for the preview ;).
      censorText($row['subject']);
      censorText($row['body']);

      $row['body'] = strip_tags(strtr(parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']), array('<br />' => '&#10;')));
      if ($smcFunc['strlen']($row['body']) > 128)
         $row['body'] = $smcFunc['substr']($row['body'], 0, 128) . '...';

      // Build the array.
      $posts[] = array(
         'category' => array(
                'id' => $row['cIDcat'],
                'name' => $row['cName']
          ),
      
         'board' => array(
            'id' => $row['id_board'],
            'name' => $row['board_name'],
            'href' => $scripturl . '?board=' . $row['id_board'] . '.0',
            'link' => '<a href="' . $scripturl . '?board=' . $row['id_board'] . '.0">' . $row['board_name'] . '</a>', // DON'T FORGET THE COMMA HERE!
              'idcat' => $row['bIDcat']

         ),
         'topic' => $row['id_topic'],
         'poster' => array(
            'id' => $row['id_member'],
            'name' => $row['poster_name'],
            'href' => empty($row['id_member']) ? '' : $scripturl . '?action=profile;u=' . $row['id_member'],
            'link' => empty($row['id_member']) ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>'
         ),
         'subject' => $row['subject'],
         'short_subject' => shorten_subject($row['subject'], 24),
         'preview' => $row['body'],
         'time' => timeformat($row['poster_time']),
         'timestamp' => forum_time(true, $row['poster_time']),
         'raw_timestamp' => $row['poster_time'],
         'href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . ';topicseen#msg' . $row['id_msg'],
         'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . ';topicseen#msg' . $row['id_msg'] . '" rel="nofollow">' . $row['subject'] . '</a>'
      );
   }
   $smcFunc['db_free_result']($request);

   return $posts;
}



Ok, you should now have the necessary data available for further presentation. To show the Category names in the Recent posts, all you need to do is place the "$post['category']['name']" on the right place. You can also use this variable to handle other stuff which might need the category information of recent posts.


Open the \Themes\<YOUR SMF THEME>\BoardIndex.template.php and find the following piece of code:

// Show lots of posts.
elseif (!empty($context['latest_posts']))
{
echo '
<dl id="ic_recentposts" class="middletext">';

/* Each post in latest_posts has:
board (with an id, name, and link.), topic (the topic's id.), poster (with id, name, and link.),
subject, short_subject (shortened with...), time, link, and href. */
foreach ($context['latest_posts'] as $post)
echo '
<dt><strong>', $post['link'], '</strong> ', $txt['by'], ' ', $post['poster']['link'], ' (', $post['board']['link'], ')</dt>
<dd>', $post['time'], '</dd>';
echo '
</dl>';
}
echo '



Now change it and place the Category name ($post['category']['name']) somewhere you want. Here is my example:

// Show lots of posts.
elseif (!empty($context['latest_posts']))
{
echo '
<dl id="ic_recentposts" class="middletext">';

/* Each post in latest_posts has:
board (with an id, name, and link.), topic (the topic's id.), poster (with id, name, and link.),
subject, short_subject (shortened with...), time, link, and href. */
foreach ($context['latest_posts'] as $post)
echo '
<dt> [',$post['board']['link'],'] ',$post['category']['name'],' <strong>', $post['link'], '</strong> ', $txt['by'], ' ', $post['poster']['link'], '</dt>
<dd>', $post['time'], '</dd>';
echo '
</dl>';
}



Thats it. Have fun and good luck to anyone who might need this in the future!

margarett

Se forem conduzir, não bebam. Se forem beber... CHAMEM-ME!!!! :D

LainaaOver 90% of all computer problems can be traced back to the interface between the keyboard and the chair

Advertisement: