Вывод последних активных тем (компактная версия)
Добавлено: 21 янв 2014, 02:15
Хочу описать простой мод, выводящий активные темы (т.е. темы, в которых появились последние сообщения). Можете глянуть на морду моего форума ("ПОСЛЕДНЯЯ АКТИВНОСТЬ НА ФОРУМЕ") чтоб лицезреть как сия краса выглядит. Клик по теме перекидывает на её первое непрочитанное сообщение (ну, а незарегистрированных юзеров - на начало темы) в новой вкладке браузера. Мод напоминает известный "Top Five", но имеет некоторые отличия.
Преимущества по сравнению с "Top Five":
1. Блок очень компактен и его не жалко запихнуть на видное место - он может занимать мало места по горизонтали (а "Top Five" крадёт всё пространство - если его сжать, то его содержимое превратится в бардак). В нём дана ТОЛЬКО сама необходимая инфа - название темы, к-во сообщений и время последнего сообщения (причём независимо от дефолтного формата даты/времени будет выводиться в формате "3 минуты назад", что позволяет показать случайномуи посетителю, что форум активен - конечно, если он активен; в моде "Top Five" эта архиважная информация похоронена среди кучи не нужной).
2. Это джаваскрипт, который может быть вписан в HTML любого сайта - даже не связанного с форумом физически. Вот как это выглядит на моём стареньком персональном сайтике ("Последние активные темы на форуме").
3. Можно высвечивать начало первого сообщения темы (лично мне это не надо, но, может, кому-то понравится).
Недостатки по сравнению с "Top Five":
1. Скрипт игнорирует права доступа и тупо высвечивает топики из тех подфорумов, которые ему указали (или игнорирует те, что приказано игнорировать).
2. Это джаваскрипт, что в принципе не есть хорошо (хотя больше теоретически, чем на практике).
3. Невозможно установить мод всплывающей подсказки (mouse hoover).
Но я охотно хаваю все эти недостатки из-за одного первого преимущества.
Итак, что надо сделать.
ШАГ 1 - создать в корневой папке форума файл с именем recent.php и следующим текстом:
Переменная $cfg_ignore_forums заполняется перечисленными через запятую номерами подфорумов, котрые НЕ НАДО выводить в список (у меня это закрытый женский подфорум, а также "Корзина", темы из которой просто неинтересны) - замените на свои если есть (а если нет - присвойте переменной пустую строку).
Переменная$cfg_nm_topics хранит число выводимых тем (у меня это 18 - замените если хотите на своё).
ШАГ 2 - создать в папке styles\<ваш стиль>\template\ файл с именем recent_body.html и следующим текстом:
В recent_body.html вы можете изменить внешний вид выводимых строк согласно своему вкусу или стилю форума.
ШАГ 3 - разместить следующий фрагмент в том месте файла styles\<ваш стиль>\template\index_body.html, где хотите выводить последние темы:
Если хотите разместить этот фрагмент на стороннем сайте (не связанном с форумом физически), то не забудьте указать полный путь к файлу! Например, вот как это выглядит у меня:
Как видите, вывод блока взят под условие - на некоторых страницах его не надо показывать - например, на главной, где он и так есть, на search - это когда юзер открыл страницу "Непрочитанное" (чтоб не показывать то-же самое дважды) и на posting - когда юзер создаёт тему или ответ.
Преимущества по сравнению с "Top Five":
1. Блок очень компактен и его не жалко запихнуть на видное место - он может занимать мало места по горизонтали (а "Top Five" крадёт всё пространство - если его сжать, то его содержимое превратится в бардак). В нём дана ТОЛЬКО сама необходимая инфа - название темы, к-во сообщений и время последнего сообщения (причём независимо от дефолтного формата даты/времени будет выводиться в формате "3 минуты назад", что позволяет показать случайномуи посетителю, что форум активен - конечно, если он активен; в моде "Top Five" эта архиважная информация похоронена среди кучи не нужной).
2. Это джаваскрипт, который может быть вписан в HTML любого сайта - даже не связанного с форумом физически. Вот как это выглядит на моём стареньком персональном сайтике ("Последние активные темы на форуме").
3. Можно высвечивать начало первого сообщения темы (лично мне это не надо, но, может, кому-то понравится).
Недостатки по сравнению с "Top Five":
1. Скрипт игнорирует права доступа и тупо высвечивает топики из тех подфорумов, которые ему указали (или игнорирует те, что приказано игнорировать).
2. Это джаваскрипт, что в принципе не есть хорошо (хотя больше теоретически, чем на практике).
3. Невозможно установить мод всплывающей подсказки (mouse hoover).
Но я охотно хаваю все эти недостатки из-за одного первого преимущества.
Итак, что надо сделать.
ШАГ 1 - создать в корневой папке форума файл с именем recent.php и следующим текстом:
Код: Выделить всё
<?php
/**
*
* @package phpBB3
* @version $Id: recent.php,v 1.1.2 2007/08/21 23:21:39 rxu Exp $
* @copyright (c) 2005 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/
/**
* Page of the MOD: http://bb3x.ru/mods/info/40
*/
/* Config section */
$cfg_ignore_forums = '24,47'; // forums to ignore: 24=Zhenskij Salon, 47=Korzina
$cfg_only_forums = ''; // ids of forums you only want to display, separated by commas or empty
$cfg_nm_topics = 18; // number of topics to output
$cfg_max_topic_length = 120; // max topic length, if more, title will be shortened
$cfg_show_replies = true; // show number of replies to topics
$cfg_show_first_post = false; // show first posts of the recent topics
$cfg_show_attachments = false; // show attachments in the first posts of recent topics
/* End of config */
define('IN_PHPBB', true);
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);
include($phpbb_root_path . 'includes/bbcode.' . $phpEx);
//
// Let's prevent caching
//
if (!empty($_SERVER['SERVER_SOFTWARE']) && strstr($_SERVER['SERVER_SOFTWARE'], 'Apache/2'))
{
header ('Cache-Control: no-cache, pre-check=0, post-check=0');
}
else
{
header ('Cache-Control: private, pre-check=0, post-check=0, max-age=0');
}
header('Content-type: text/html; charset=UTF-8');
header('Expires: 0');
header('Pragma: no-cache');
// Start session management
$user->session_begin();
$auth->acl($user->data);
$user->setup('common');
//
// Building URL
//
$board_path = generate_board_url();
$viewtopic_url = $board_path . '/viewtopic.' . $phpEx;
// Fetching forums that should not be displayed
$forums = implode(',', array_keys($auth->acl_getf('!f_read', true)));
$cfg_ignore_forums = (!empty($cfg_ignore_forums) && !empty($forums)) ? $cfg_ignore_forums . ',' . $forums : ((!empty($forums)) ? $forums : ((!empty($cfg_ignore_forums)) ? $cfg_ignore_forums : ''));
// Building sql for forums that should not be displayed
$sql_ignore_forums = (!empty($cfg_ignore_forums)) ? ' AND t.forum_id NOT IN(' . $cfg_ignore_forums .') ' : '';
// Building sql for forums that should only be displayed
$sql_only_forums = (!empty($cfg_only_forums)) ? ' AND t.forum_id IN(' . $cfg_only_forums .') ' : '';
// Fetching topics of public forums
$sql = 'SELECT t.topic_id, t.forum_id, t.topic_title, t.topic_last_post_id, t.topic_first_post_id, t.topic_replies, t.topic_replies_real, p.post_id, p.post_text, p.bbcode_uid, p.bbcode_bitfield, p.post_attachment, p.post_approved, t.topic_last_post_time
FROM ' . TOPICS_TABLE . ' AS t, ' . POSTS_TABLE . ' AS p, ' . FORUMS_TABLE . " AS f
WHERE t.forum_id = f.forum_id
$sql_ignore_forums
$sql_only_forums
AND p.post_id = t.topic_first_post_id
AND t.topic_moved_id = 0
ORDER BY t.topic_last_post_id DESC LIMIT $cfg_nm_topics";
$result = $db->sql_query($sql);
$recent_topics = $db->sql_fetchrowset($result);
//
// BEGIN ATTACHMENT DATA
//
if($cfg_show_first_post && $cfg_show_attachments)
{
$attach_list = $update_count = array();
foreach ($recent_topics as $post_attachment)
{
if ($post_attachment['post_attachment'] && $config['allow_attachments'])
{
$attach_list[] = $post_attachment['post_id'];
if ($post_attachment['post_approved'])
{
$has_attachments = true;
}
}
}
// Pull attachment data
if (sizeof($attach_list))
{
if ($auth->acl_get('u_download') )
{
$sql_attach = 'SELECT *
FROM ' . ATTACHMENTS_TABLE . '
WHERE ' . $db->sql_in_set('post_msg_id', $attach_list) . '
AND in_message = 0
ORDER BY filetime DESC, post_msg_id ASC';
$result_attach = $db->sql_query($sql_attach);
while ($row_attach = $db->sql_fetchrow($result_attach))
{
$attachments[$row_attach['post_msg_id']][] = $row_attach;
}
$db->sql_freeresult($result_attach);
}
else
{
$display_notice = true;
}
}
}
//
// END ATTACHMENT DATA
//
foreach ( $recent_topics as $row )
{
$topic_title = censor_text($row['topic_title']);
$topic_title = (utf8_strlen($topic_title) > $cfg_max_topic_length) ? utf8_substr($topic_title, 0, $cfg_max_topic_length) . '…' : $topic_title;
$topic_title = str_replace(array("\r\n", "\r", "\n"), '<br />', $topic_title);
$topic_title = addslashes($topic_title);
// Replies
$replies = ($auth->acl_get('m_approve', $row['forum_id'])) ? $row['topic_replies_real'] : $row['topic_replies'];
// Instantiate BBCode if need be
if ($row['bbcode_bitfield'] !== '')
{
$bbcode = new bbcode(base64_encode($row['bbcode_bitfield']));
}
$message = $row['post_text'];
// Parse the message
$message = censor_text($message);
// Second parse bbcode here
if ($row['bbcode_bitfield'])
{
$bbcode->bbcode_second_pass($message, $row['bbcode_uid'], $row['bbcode_bitfield']);
}
$message = str_replace("\n", '<br />', $message);
// Always process smilies after parsing bbcodes
$message = smiley_text($message);
// Parse attachments
if ($cfg_show_first_post && $cfg_show_attachments && !empty($attachments[$row['post_id']]))
{
parse_attachments($row['forum_id'], $message, $attachments[$row['post_id']], $update_count);
}
$message = str_replace(array("\r\n", "\r", "\n"), '<br />', $message);
$message = addslashes($message);
$message = str_replace('./', $board_path . '/', $message);
$tags = array('dl', 'dt', 'dd');
$message = strip_selected_tags($message, $tags);
$template->assign_block_vars('topicrow', array(
'U_TOPIC' => $viewtopic_url . '?f=' . $row['forum_id'] . '&t=' . $row['topic_id'] . '&view=unread#unread',
'TOPIC_TITLE' => $topic_title,
'TOPIC_REPLIES' => ($cfg_show_replies) ? '[' . $replies . '] ' : '',
'LAST_POST_TIME' => $user->format_date($row['topic_last_post_time'], '|d M Y| H:i'), /* Ursego */
'S_HAS_ATTACHMENTS' => ($cfg_show_first_post && $cfg_show_attachments && !empty($attachments[$row['post_id']])) ? true : false,
));
if ($cfg_show_first_post)
{
$template->assign_block_vars('topicrow.first_post_text', array(
'TOPIC_FIRST_POST_TEXT' => ($cfg_show_first_post) ? $message : ''
));
}
// Display not already displayed Attachments for this post, we already parsed them. ;)
if ($cfg_show_first_post && $cfg_show_attachments && !empty($attachments[$row['post_id']]))
{
foreach ($attachments[$row['post_id']] as $attachment)
{
$attachment = str_replace(array("\r\n", "\r", "\n"), '<br />', $attachment);
$attachment = str_replace('"./', '"' . $board_path . '/', $attachment);
$tags = array('span', 'dt', 'dd');
$attachment = strip_selected_tags($attachment, $tags);
$template->assign_block_vars('topicrow.first_post_text.attachment', array(
'DISPLAY_ATTACHMENT' => $attachment)
);
}
}
}
$db->sql_freeresult($result);
//
// Load template
//
$template->set_filenames(array(
'body' => 'recent_body.html')
);
//
// Output
//
$template->display('body');
/**
* Works like PHP function strip_tags, but it only removes selected tags.
* Example: * strip_selected_tags('<b>Person:</b> <strong>Larcher</strong>', 'strong') => <b>Person:</b> Larcher
* by Matthieu Larcher
* http://ru2.php.net/manual/en/function.strip-tags.php#76045
*/
function strip_selected_tags($text, $tags = array())
{
$args = func_get_args();
$text = array_shift($args);
$tags = (func_num_args() > 2) ? array_diff($args,array($text)) : (array)$tags;
foreach ($tags as $tag)
{
while(preg_match('/<'.$tag.'(|\W[^>]*)>(.*)<\/'. $tag .'>/iusU', $text, $found))
{
$text = str_replace($found[0],$found[2],$text);
}
}
return preg_replace('/(<('.join('|',$tags).')(|\W.*)\/>)/iusU', '', $text);
}
?>
Переменная
ШАГ 2 - создать в папке styles\<ваш стиль>\template\ файл с именем recent_body.html и следующим текстом:
Код: Выделить всё
<!-- BEGIN topicrow -->
document.writeln('• <a href="{topicrow.U_TOPIC}" target="_blank"><strong>{topicrow.TOPIC_TITLE}</strong></a> <font color="grey">{topicrow.TOPIC_REPLIES}</font>{topicrow.LAST_POST_TIME}<br />\n');
<!-- BEGIN first_post_text -->
document.writeln('{topicrow.first_post_text.TOPIC_FIRST_POST_TEXT}<br />\n');
<!-- BEGIN attachment -->
document.writeln('{topicrow.first_post_text.attachment.DISPLAY_ATTACHMENT}<br />\n');
<!-- END attachment -->
document.writeln('<br />\n');
<!-- END first_post_text -->
<!-- END topicrow -->
ШАГ 3 - разместить следующий фрагмент в том месте файла styles\<ваш стиль>\template\index_body.html, где хотите выводить последние темы:
Код: Выделить всё
<!-- IF not S_IS_BOT --><script language='JavaScript' type='text/javascript' src='/recent.php'></script><!-- ENDIF -->
Код: Выделить всё
<noindex><script language='JavaScript' type='text/javascript' src='http://forum.north-ameri.ca/recent.php'></script></noindex>
**********************************
В дополнение к главной странице (index_body.html) этот блок можно разместить и внизу каждой страницы форума, тобто в overall_footer.html (я был вынужден это сделать - форумчане потребовали). Вот фрагмент, который надо вставить в "подвал":Код: Выделить всё
<!-- IF SCRIPT_NAME neq 'index' and SCRIPT_NAME neq 'search' and SCRIPT_NAME neq 'mcp' and SCRIPT_NAME neq 'ucp' and SCRIPT_NAME neq 'posting' and not S_IS_BOT --><script language='JavaScript' type='text/javascript' src='/recent.php'></script><!-- ENDIF -->
**********************************
Этот мод был взят мною здесь http://bb3x.ru/mods/info/40 и немного доработан - добавлено время последнего постинга и немного изменена косметика (т.е. как темы выводятся визуально).