CLANGAMING.Net Форуми CLANGAMING.Net
Българският портал за CS 1.6
 
 Въпроси/ОтговориВъпроси/Отговори   ТърсенеТърсене   ПотребителиПотребители   Потребителски групиПотребителски групи   Регистрирайте сеРегистрирайте се 
 ПрофилПрофил   Влезте, за да видите съобщенията сиВлезте, за да видите съобщенията си   ВходВход 

Урок: Как да добавим блок „Последни теми“ в phpBB2

 
Създайте нова тема   Напишете отговор    CLANGAMING.Net Форуми -> Уеб програмиране
Предишната тема :: Следващата тема  
Автор Съобщение
AetheldredaBG
Главен Администратор
Главен Администратор
AetheldredaBG

Регистриран на: 14 Сеп 2026
Мнения: 15
Местожителство: София, България

МнениеПуснато на: Сря Сеп 16, 2026 11:07 pm    Заглавие: Урок: Как да добавим блок „Последни теми“ в phpBB2 Отговорете с цитат

Урок: Как да добавим блок „Последни теми“ в phpBB2
Тема: subSilver • phpBB 2.x • начална страница • CLANGAMING.NET

Внимание: Този урок е писан специално за CLANGAMING.NET. Копирането, препубликуването или разпространението му без знание и съгласие на администрацията на CLANGAMING.NET не е позволено.

Какво ще получиш:
На началната страница, над списъка с форуми, се появява таблица Последни теми с:

  • 10 най-скоро активни теми
  • колони Отговори, Преглеждания, Последно мнение
  • аватар на автора и на последния писал
  • клик върху аватара води към профила (гостите нямат линк)
  • показват се само форуми, които потребителят има право да вижда


Файлове, които ще се пипат (в този ред):

  1. includes/functions.php
  2. language/lang_english/lang_main.php
  3. language/lang_bulgarian/lang_main.php
  4. templates/subSilver/overall_header.tpl
  5. index.php
  6. templates/subSilver/index_body.tpl


Преди да започнеш, направи копие на всеки от тези 6 файла.


Стъпка 1 — Функция за аватар

Отвори:
Код:
includes/functions.php


Намери тази функция (тя е към края на файла, преди redirect):

Код:
function phpbb_realpath($path)
{
   global $phpbb_root_path, $phpEx;

   return (!@function_exists('realpath') || !@realpath($phpbb_root_path . 'includes/functions.'.$phpEx)) ? $path : @realpath($path);
}

function redirect($url)


Между края на phpbb_realpath и началото на redirect постави точно този код:

Код:
function phpbb_user_avatar($avatar, $avatar_type, $allow_avatar, $alt = '', $css_class = 'recent-avatar', $profile_url = '', $show_empty = true)
{
   global $board_config;

   $alt = htmlspecialchars($alt);
   $img = '';

   if ( $avatar_type && $allow_avatar )
   {
      switch ( intval($avatar_type) )
      {
         case USER_AVATAR_UPLOAD:
            $img = ( $board_config['allow_avatar_upload'] && $avatar != '' ) ? $board_config['avatar_path'] . '/' . $avatar : '';
            break;
         case USER_AVATAR_REMOTE:
            $img = ( $board_config['allow_avatar_remote'] && $avatar != '' ) ? $avatar : '';
            break;
         case USER_AVATAR_GALLERY:
            $img = ( $board_config['allow_avatar_local'] && $avatar != '' ) ? $board_config['avatar_gallery_path'] . '/' . $avatar : '';
            break;
      }
   }

   if ( $img != '' )
   {
      $html = '<img src="' . htmlspecialchars($img) . '" alt="' . $alt . '" title="' . $alt . '"' . ( $css_class != '' ? ' class="' . $css_class . '"' : '' ) . ' border="0" />';
   }
   else if ( $show_empty )
   {
      $html = '<span class="recent-avatar-empty" title="' . $alt . '"></span>';
   }
   else
   {
      return '';
   }

   if ( $profile_url != '' )
   {
      $html = '<a href="' . $profile_url . '" class="recent-avatar-link">' . $html . '</a>';
   }

   return $html;
}


Защо е нужна: без тази функция index.php ще гръмне, защото оттам се викат аватарите и линкът към профила.

Запази файла.


Стъпка 2 — Английски език

Отвори:
Код:
language/lang_english/lang_main.php


Непосредствено преди реда:

Код:
//
// That's all, Folks!
// -------------------------------------------------


добави:

Код:
$lang['Latest_topics'] = 'Latest Topics';
$lang['Topic_views'] = 'Views';


Запази файла.


Стъпка 3 — Български език

Отвори:
Код:
language/lang_bulgarian/lang_main.php


Непосредствено преди реда:

Код:
//
// That's all Folks!
// -------------------------------------------------


добави точно тези два реда (използвани са HTML кодове, за да няма проблем с кодирането windows-1251):

Код:
$lang['Latest_topics'] = "Последни теми";
$lang['Topic_views'] = "Преглеждания";


На форума ще се четат като Последни теми и Преглеждания.

Запази файла.


Стъпка 4 — CSS за малките аватари

Отвори:
Код:
templates/subSilver/overall_header.tpl


В секцията <style> намери:

Код:
hr   { height: 0px; border: solid {T_TR_COLOR3} 0px; border-top-width: 1px;}


Директно под него добави (ако вече имаш CSS за 1400px, сложи този блок след него, не го трий):

Код:
img.recent-avatar {
   width: 32px;
   height: 32px;
   vertical-align: middle;
   border: 1px {T_TH_COLOR1} solid;
   margin-right: 4px;
   object-fit: cover;
}
span.recent-avatar-empty {
   display: inline-block;
   width: 32px;
   height: 32px;
   vertical-align: middle;
   background-color: {T_TR_COLOR2};
   border: 1px {T_TH_COLOR1} solid;
   margin-right: 4px;
}
a.recent-avatar-link {
   text-decoration: none;
}
a.recent-avatar-link:hover img.recent-avatar,
a.recent-avatar-link:hover span.recent-avatar-empty {
   border-color: {T_BODY_HLINK};
}


Важно: този CSS е само за малките аватари в списъците (32px). Не пипай големите аватари в самата тема.

Запази файла.

По желание: phpBB2 по подразбиране не зарежда subSilver.css (линкът към него е коментиран). Ако някой ден го включиш, копирай същите правила и там, но с фиксирани цветове: рамка #98AAB1, фон на празния аватар #DEE3E7, hover #DD6900.


Стъпка 5 — Логиката в index.php

Отвори:
Код:
index.php


Това е най-важната стъпка. Мястото на кода не е случайно. Трябва да е:

  • след auth() (за да знае кои форуми може да вижда потребителят)
  • след page_header.php (за икони, език, тема)
  • след $template->assign_vars
  • преди цикъла, който строи категориите (Let's decide which categories)



5.1 — Добави езиковите променливи

Намери края на $template->assign_vars. Оригинално изглежда така:

Код:
      'L_MARK_FORUMS_READ' => $lang['Mark_all_forums'],

      'U_MARK_READ' => append_sid("index.$phpEx?mark=forums"))
   );


Замени го с:

Код:
      'L_MARK_FORUMS_READ' => $lang['Mark_all_forums'],

      'U_MARK_READ' => append_sid("index.$phpEx?mark=forums"),

      'L_LATEST_TOPICS' => ( !empty($lang['Latest_topics']) ) ? $lang['Latest_topics'] : 'Latest Topics',
      'L_AUTHOR' => $lang['Author'],
      'L_TOPIC_VIEWS' => ( !empty($lang['Topic_views']) ) ? $lang['Topic_views'] : $lang['Views'])
   );


Обърни внимание: след mark=forums вече има запетая, а затварящата скоба на масива остава след новите редове.


5.2 — Постави целия блок за последните теми

Веднага след затварянето на assign_vars и преди коментара:

Код:
   //
   // Let's decide which categories we should display
   //


постави точно този код:

Код:
   //
   // Latest topics (10 most recently posted-to topics)
   //
   $recent_forum_ids = array();
   for ( $i = 0; $i < $total_forums; $i++ )
   {
      $recent_fid = intval($forum_data[$i]['forum_id']);
      if ( !empty($is_auth_ary[$recent_fid]['auth_view']) )
      {
         $recent_forum_ids[] = $recent_fid;
      }
   }

   if ( count($recent_forum_ids) )
   {
      $orig_word = array();
      $replacement_word = array();
      obtain_word_list($orig_word, $replacement_word);

      $sql = "SELECT t.topic_id, t.forum_id, t.topic_title, t.topic_replies, t.topic_views, t.topic_type, t.topic_status, t.topic_vote, t.topic_moved_id, t.topic_last_post_id,
            f.forum_name, f.forum_status,
            u.username, u.user_id, u.user_avatar, u.user_avatar_type, u.user_allowavatar,
            u2.username as user2, u2.user_id as id2, u2.user_avatar as last_user_avatar, u2.user_avatar_type as last_user_avatar_type, u2.user_allowavatar as last_user_allowavatar,
            p.post_username, p2.post_username AS post_username2, p2.post_time
         FROM " . TOPICS_TABLE . " t, " . FORUMS_TABLE . " f, " . USERS_TABLE . " u, " . POSTS_TABLE . " p, " . POSTS_TABLE . " p2, " . USERS_TABLE . " u2
         WHERE t.forum_id = f.forum_id
            AND t.topic_poster = u.user_id
            AND p.post_id = t.topic_first_post_id
            AND p2.post_id = t.topic_last_post_id
            AND u2.user_id = p2.poster_id
            AND t.topic_moved_id = 0
            AND t.forum_id IN (" . implode(', ', $recent_forum_ids) . ")
         ORDER BY p2.post_time DESC
         LIMIT 10";
      if ( !($result = $db->sql_query($sql)) )
      {
         message_die(GENERAL_ERROR, 'Could not query latest topics', '', __LINE__, __FILE__, $sql);
      }

      $recent_i = 0;
      while ( $recent_row = $db->sql_fetchrow($result) )
      {
         if ( !$recent_i )
         {
            $template->assign_block_vars('switch_recent_topics', array());
         }

         $topic_id = $recent_row['topic_id'];
         $forum_id = $recent_row['forum_id'];
         $replies = $recent_row['topic_replies'];
         $topic_title = ( count($orig_word) ) ? preg_replace($orig_word, $replacement_word, $recent_row['topic_title']) : $recent_row['topic_title'];

         $topic_type = $recent_row['topic_type'];
         if ( $topic_type == POST_ANNOUNCE )
         {
            $topic_type = $lang['Topic_Announcement'] . ' ';
         }
         else if ( $topic_type == POST_STICKY )
         {
            $topic_type = $lang['Topic_Sticky'] . ' ';
         }
         else
         {
            $topic_type = '';
         }

         if ( $recent_row['topic_vote'] )
         {
            $topic_type .= $lang['Topic_Poll'] . ' ';
         }

         if ( $recent_row['topic_type'] == POST_ANNOUNCE )
         {
            $folder = $images['folder_announce'];
            $folder_new = $images['folder_announce_new'];
         }
         else if ( $recent_row['topic_type'] == POST_STICKY )
         {
            $folder = $images['folder_sticky'];
            $folder_new = $images['folder_sticky_new'];
         }
         else if ( $recent_row['topic_status'] == TOPIC_LOCKED )
         {
            $folder = $images['folder_locked'];
            $folder_new = $images['folder_locked_new'];
         }
         else if ( $replies >= $board_config['hot_threshold'] )
         {
            $folder = $images['folder_hot'];
            $folder_new = $images['folder_hot_new'];
         }
         else
         {
            $folder = $images['folder'];
            $folder_new = $images['folder_new'];
         }

         $folder_image = $folder;
         $folder_alt = ( $recent_row['topic_status'] == TOPIC_LOCKED ) ? $lang['Topic_locked'] : $lang['No_new_posts'];

         if ( $userdata['session_logged_in'] && $recent_row['post_time'] > $userdata['user_lastvisit'] )
         {
            $unread_topics = true;

            if ( !empty($tracking_topics[$topic_id]) && $tracking_topics[$topic_id] >= $recent_row['post_time'] )
            {
               $unread_topics = false;
            }
            if ( !empty($tracking_forums[$forum_id]) && $tracking_forums[$forum_id] >= $recent_row['post_time'] )
            {
               $unread_topics = false;
            }
            if ( isset($HTTP_COOKIE_VARS[$board_config['cookie_name'] . '_f_all']) && $HTTP_COOKIE_VARS[$board_config['cookie_name'] . '_f_all'] >= $recent_row['post_time'] )
            {
               $unread_topics = false;
            }

            if ( $unread_topics )
            {
               $folder_image = $folder_new;
               $folder_alt = $lang['New_posts'];
            }
         }

         $topic_profile_url = ( $recent_row['user_id'] != ANONYMOUS ) ? append_sid("profile.$phpEx?mode=viewprofile&amp;" . POST_USERS_URL . '=' . $recent_row['user_id']) : '';
         $last_profile_url = ( $recent_row['id2'] != ANONYMOUS ) ? append_sid("profile.$phpEx?mode=viewprofile&amp;" . POST_USERS_URL . '=' . $recent_row['id2']) : '';

         $topic_author = ( $topic_profile_url != '' ) ? '<a href="' . $topic_profile_url . '">' . $recent_row['username'] . '</a>' : ( ( $recent_row['post_username'] != '' ) ? $recent_row['post_username'] : $lang['Guest'] );
         $last_post_author = ( $last_profile_url != '' ) ? '<a href="' . $last_profile_url . '">' . $recent_row['user2'] . '</a>' : ( ( $recent_row['post_username2'] != '' ) ? $recent_row['post_username2'] : $lang['Guest'] );

         $topic_avatar_alt = ( $recent_row['user_id'] != ANONYMOUS ) ? $recent_row['username'] : $lang['Guest'];
         $last_avatar_alt = ( $recent_row['id2'] != ANONYMOUS ) ? $recent_row['user2'] : $lang['Guest'];

         $row_class = ( !($recent_i % 2) ) ? $theme['td_class1'] : $theme['td_class2'];

         $template->assign_block_vars('switch_recent_topics.recent_topic', array(
            'ROW_CLASS' => $row_class,
            'TOPIC_FOLDER_IMG' => $folder_image,
            'L_TOPIC_FOLDER_ALT' => $folder_alt,
            'TOPIC_TYPE' => $topic_type,
            'TOPIC_TITLE' => $topic_title,
            'TOPIC_AUTHOR' => $topic_author,
            'TOPIC_AVATAR' => phpbb_user_avatar($recent_row['user_avatar'], $recent_row['user_avatar_type'], $recent_row['user_allowavatar'], $topic_avatar_alt, 'recent-avatar', $topic_profile_url),
            'FORUM_NAME' => $recent_row['forum_name'],
            'REPLIES' => $replies,
            'VIEWS' => $recent_row['topic_views'],
            'LAST_POST_TIME' => create_date($board_config['default_dateformat'], $recent_row['post_time'], $board_config['board_timezone']),
            'LAST_POST_AUTHOR' => $last_post_author,
            'LAST_POST_AVATAR' => phpbb_user_avatar($recent_row['last_user_avatar'], $recent_row['last_user_avatar_type'], $recent_row['last_user_allowavatar'], $last_avatar_alt, 'recent-avatar', $last_profile_url),
            'LAST_POST_IMG' => '<a href="' . append_sid("viewtopic.$phpEx?" . POST_POST_URL . '=' . $recent_row['topic_last_post_id']) . '#' . $recent_row['topic_last_post_id'] . '"><img src="' . $images['icon_latest_reply'] . '" alt="' . $lang['View_latest_post'] . '" title="' . $lang['View_latest_post'] . '" border="0" /></a>',
            'U_VIEW_TOPIC' => append_sid("viewtopic.$phpEx?" . POST_TOPIC_URL . '=' . $topic_id),
            'U_VIEWFORUM' => append_sid("viewforum.$phpEx?" . POST_FORUM_URL . '=' . $forum_id))
         );

         $recent_i++;
      }
      $db->sql_freeresult($result);
   }


Не сменяй името на блока switch_recent_topics.recent_topic. В phpBB2 вложеният шаблон задължително се пълни с пълния път, иначе редовете ще са празни.

За да показва друга бройка, сменяш само:

Код:
LIMIT 10


например на LIMIT 15.

Запази файла.


Стъпка 6 — HTML на началната страница

Отвори:
Код:
templates/subSilver/index_body.tpl


Намери края на таблицата с часа / последното посещение. След нея идва таблицата на форумите:

Код:
</table>

<table width="100%" cellpadding="2" cellspacing="1" border="0" class="forumline">
  <tr>
   <th colspan="2" class="thCornerL" height="25" nowrap="nowrap">&nbsp;{L_FORUM}&nbsp;</th>


Между тези две таблици постави точно този HTML:

Код:
<!-- BEGIN switch_recent_topics -->
<table width="100%" cellpadding="4" cellspacing="1" border="0" class="forumline">
  <tr>
   <th colspan="2" align="center" height="25" class="thCornerL" nowrap="nowrap">&nbsp;{L_LATEST_TOPICS}&nbsp;</th>
   <th width="50" align="center" class="thTop" nowrap="nowrap">&nbsp;{L_REPLIES}&nbsp;</th>
   <th width="80" align="center" class="thTop" nowrap="nowrap">&nbsp;{L_TOPIC_VIEWS}&nbsp;</th>
   <th align="center" class="thCornerR" nowrap="nowrap">&nbsp;{L_LASTPOST}&nbsp;</th>
  </tr>
  <!-- BEGIN recent_topic -->
  <tr>
   <td class="{switch_recent_topics.recent_topic.ROW_CLASS}" align="center" valign="middle" width="20"><img src="{switch_recent_topics.recent_topic.TOPIC_FOLDER_IMG}" width="19" height="18" alt="{switch_recent_topics.recent_topic.L_TOPIC_FOLDER_ALT}" title="{switch_recent_topics.recent_topic.L_TOPIC_FOLDER_ALT}" /></td>
   <td class="{switch_recent_topics.recent_topic.ROW_CLASS}" width="100%" valign="middle">
     <table width="100%" cellspacing="0" cellpadding="0" border="0">
      <tr>
        <td valign="middle" width="40">{switch_recent_topics.recent_topic.TOPIC_AVATAR}</td>
        <td valign="middle" width="100%"><span class="topictitle">{switch_recent_topics.recent_topic.TOPIC_TYPE}<a href="{switch_recent_topics.recent_topic.U_VIEW_TOPIC}" class="topictitle">{switch_recent_topics.recent_topic.TOPIC_TITLE}</a></span><br /><span class="gensmall">{L_AUTHOR}: {switch_recent_topics.recent_topic.TOPIC_AUTHOR}&nbsp;&raquo;&nbsp;<a href="{switch_recent_topics.recent_topic.U_VIEWFORUM}" class="gensmall">{switch_recent_topics.recent_topic.FORUM_NAME}</a></span></td>
      </tr>
     </table>
   </td>
   <td class="{switch_recent_topics.recent_topic.ROW_CLASS}" align="center" valign="middle"><span class="postdetails">{switch_recent_topics.recent_topic.REPLIES}</span></td>
   <td class="{switch_recent_topics.recent_topic.ROW_CLASS}" align="center" valign="middle"><span class="postdetails">{switch_recent_topics.recent_topic.VIEWS}</span></td>
   <td class="{switch_recent_topics.recent_topic.ROW_CLASS}" align="center" valign="middle" nowrap="nowrap">
     <table cellspacing="0" cellpadding="2" border="0" align="center">
      <tr>
        <td valign="middle">{switch_recent_topics.recent_topic.LAST_POST_AVATAR}</td>
        <td valign="middle" nowrap="nowrap"><span class="postdetails">{switch_recent_topics.recent_topic.LAST_POST_TIME}<br />{switch_recent_topics.recent_topic.LAST_POST_AUTHOR} {switch_recent_topics.recent_topic.LAST_POST_IMG}</span></td>
      </tr>
     </table>
   </td>
  </tr>
  <!-- END recent_topic -->
</table>
<br />
<!-- END switch_recent_topics -->


Задължително ползвай пълните имена като:
Код:
{switch_recent_topics.recent_topic.TOPIC_TITLE}


Ако напишеш само {recent_topic.TOPIC_TITLE}, phpBB2 няма да попълни нищо.

Запази файла.


Стъпка 7 — Проверка


  1. Качи всички записани файлове на сървъра (ако редактираш локално)
  2. Отвори началната страница на форума
  3. Натисни Ctrl + F5
  4. Над списъка с форуми трябва да има таблица Последни теми
  5. Провери колоните: тема, отговори, преглеждания, последно мнение
  6. Кликни аватар на регистриран потребител — трябва да отвори профила



Често срещани грешки


  • Пропуснат е includes/functions.php — бяла страница или грешка Call to undefined function phpbb_user_avatar
  • Кодът в index.php е сложен преди page_header — липсват икони/език
  • В шаблона е писано {recent_topic.XXX} вместо {switch_recent_topics.recent_topic.XXX} — таблицата е празна или с празни редове
  • Забравена е запетаята след U_MARK_READ в assign_vars — Parse error в index.php
  • Променен е само HTML, без PHP — блокът изобщо не се показва (той се показва само ако има поне 1 тема)
  • Редактиран е viewforum.php или viewtopic.php — това не е този урок. Тук се пипа само началната страница



Авторски права
Този урок е писан за CLANGAMING.NET.
Копирането му без знание и съгласие не е позволено.
_________________
CLANGAMING.Net Administrator
Гейминг общност & Уеб разработки
Гледайте ни в Twitch: AetheldredaBG
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение Изпрати мейла Посетете сайта на потребителя
Покажи мнения от преди:   
Създайте нова тема   Напишете отговор    CLANGAMING.Net Форуми -> Уеб програмиране Часовете са според зоната GMT
Страница 1 от 1

 
Идете на:  
Не Можете да пускате нови теми
Не Можете да отговаряте на темите
Не Можете да променяте съобщенията си
Не Можете да изтривате съобщенията си
Не Можете да гласувате в анкети


Powered by phpBB © 2001, 2005 phpBB Group
Translation by: Boby Dimitrov