Часть 2: Комбинированная задача. Улучшаем представление вида главной страницы Форумы.
это продолжение, часть 1 находится по адресу www.drupal.ru/node/10510
-
Задачи:
- № 1 - указывать в столбце "последнее сообщение" каждого форума не только дату
топика и имя добавившего, но и Заголовок топика (нода) + кол-во
сообщений в топике (комментов нода) - № 2 - позволить сворачивать форумы с запоминанием в кукисах.
Для решения этих задач переопределяю функцию theme_forum_list в template.php
(далее по правилам переопределения функций замените MY-THEME-NAME на имя вашей темы):
function MY-THEME-NAME_forum_list($forums, $parents, $tid) {
global $user;
if ($forums) {
//
// следующий js-скрипт необходим для решения задачи №2 - сворачивание форумов.
// (его содержимое будет ниже)
// недостаток у скрипта в том что он написан мною по подобию бюлетеневского,
// а не на базе встроенного jquery , но работает от этого он не хуже
//
drupal_add_js('misc/myforum.js');
$header = array(t('Forum'), t('Topics'), t('Posts'), t('Last post'));
//
// Данный запрос не является идеальным, над ним еще прийдется поколдавать, это быстрое
// решение которое пришло мне в голову, но оно начнет неправильно выдавать результат,
// когда у нас появяться более одного сообщения созданного в одну и ту же секунду.
// Этот запрос требуется для решения первой задачи - вывод заголовка нового нода
// или нода который прокомментировали последним
//
$sql = "
SELECT f.tid, n.nid,n.title,nc.last_comment_timestamp,nc.comment_count,nc.last_comment_uid as uid,
CASE WHEN nc.last_comment_name THEN nc.last_comment_name ELSE u.name END as name
FROM {forum} AS f, {node} AS n,{node_comment_statistics} AS nc
INNER JOIN {users} u ON nc.last_comment_uid = u.uid
WHERE n.nid = f.nid AND nc.nid=n.nid AND nc.last_comment_timestamp
SELECT max(ncs.last_comment_timestamp)
FROM {node_comment_statistics} AS ncs,{node} nd,{forum} fr
WHERE ncs.nid=nd.nid AND nd.nid=fr.nid AND nd.type='forum' AND fr.tid=f.tid
GROUP BY fr.tid
)
GROUP BY f.tid
";
$result = db_query(db_rewrite_sql($sql));
$nodetopic = array();
while ($nt = db_fetch_object($result)){
$nodetopic[$nt->tid]->topic = drupal_strlen($nt->title)>40?drupal_substr($nt->title,0,40)."...":$nt->title;
$nodetopic[$nt->tid]->node = $nt->nid; // id нода
$nodetopic[$nt->tid]->alt = $nt->title; // заголовок нода
$nodetopic[$nt->tid]->count = $nt->comment_count; // кол-во комментов
$nodetopic[$nt->tid]->user->uid = $nt->uid; // id пользователя
$nodetopic[$nt->tid]->user->name = $nt->name; // имя пользователя
$nodetopic[$nt->tid]->user->timestamp = $nt->last_comment_timestamp; // время последнего сообщения
}
$cc=0;
foreach ($forums as $forum) {
//
// Этот блок кода решает вторую задачу - отделяет контейнеры каждого форума,
// чтобы их потом можно было сворачивать
// Сворачивать форумы мы будем с помощью стрелочек
// /misc/menu-expanded.png - стрелка указывает вниз (форум развернут)
// /misc/menu-expanded_collapsed.png - стрелка указывает влево (форум свернут)
//
if ($forum->container) {
$description = '
$description .= '
\n";
if ($forum->description) {
$description .= '
\n";
}
$description .= "
\n";
$rows[] = array(array('data' => $description, 'class' => 'container', 'colspan' => '4'));
$cc++;
}
else {
$new_topics = _forum_topics_unread($forum->tid, $user->uid);
$forum->old_topics = $forum->num_topics - $new_topics;
if (!$user->uid) {
$new_topics = 0;
}
$description = '
$description .= '
\n";
if ($forum->description) {
$description .= '
\n";
}
$description .= "
\n";
$nt = $nodetopic[$forum->tid];
//
// В следующем массиве я меняю последний элемент (это вывод в столбец Последнее сообщение)
//
$rows[] = array(
array('data' => $description, 'class' => 'forum'),
array('data' => $forum->num_topics . ($new_topics ? ' '. l('[+'.$new_topics.']', "forum/$forum->tid", NULL, NULL, 'new') : ''), 'class' => 'topics'),
array('data' => $forum->num_posts, 'class' => 'posts'),
array('data' => ($nt ? ( l ( $nt->topic, "node/$nt->node", array('title'=>$nt->alt, 'class'=>'replay-topic' ) , NULL , 'new')) . " [".$nt->count."]
\n"
: '' ) . theme('forum_format', $nt->user), 'class' => 'last-reply')
);//array('data' => _forum_format($forum->last_post), 'class' => 'last-reply')
$cc++;
}
}
return theme('table', $header, $rows);
}
}
?>
Кроме того, там же в template.php переопределяю функцию theme_table
(для того чтобы иметь возможность сворачивать форумы):
function MY-THEME-NAME_table($header, $rows, $attributes = array(), $caption = NULL) {
$output = '
\n";
return $output;
}
?>
UPD:
И кроме того я ввел новую функцию для отображения время/даты и пользователя:
(вместо функции _forum_format )
function MY-THEME-NAME_forum_format($topic) {
if ($topic && $topic->timestamp) {
$str = t('time от !author', array('time' => format_date($topic->timestamp, 'custom', 'H:i d.m.Y', NULL), '!author' => theme('username', $topic)));
return $str;
}
else {
return t('n/a');
}
}
?>
Содержимое файла myforum.js
//alert ( fetch_cookie('myforum_collapse') );
arrayofcont = fetch_cookie('myforum_collapse');
if (arrayofcont!= null){
arrayofcont = arrayofcont.split('\n');
for (var i in arrayofcont) {
collapse(arrayofcont[i]);
}
}
}
var is_regexp = (window.RegExp) ? true : false;
function fetch_object(idname) {
if (document.getElementById){ return document.getElementById(idname); }
else if (document.all){ return document.all[idname]; }
else if (document.layers){ return document.layers[idname]; }
else { return null; }
}
function collapse(id) {
if (!is_regexp)return false;
obj = fetch_object('collapsitbody_' + id);
row = fetch_object('container_' + id);
img = fetch_object('img_' + id);
if (!obj)
{
if (img)img.style.display = 'none';
return false;
}
if (obj.style.display == 'none')
{
obj.style.display = '';
save_collapsed(id, false);
if (img)
{
img_re = new RegExp("_collapsed\\.png$");
img.src = img.src.replace(img_re, '.png');
}
}else{
obj.style.display = 'none';
save_collapsed(id, true);
if (img)
{
img_re = new RegExp("\\.png$");
img.src = img.src.replace(img_re, '_collapsed.png');
}
}
return false;
}
function save_collapsed(id, addcollapsed)
{
var collapsed = fetch_cookie('myforum_collapse');
var tmp = new Array();
if (collapsed != null)
{
collapsed = collapsed.split('\n');
for (var i in collapsed)
if (collapsed[i] != id && collapsed[i] != '') tmp[tmp.length] = collapsed[i];
}
if (addcollapsed) tmp[tmp.length] = id;
expires = new Date();
expires.setTime(expires.getTime() + (1000 * 86400 * 365));
set_cookie('myforum_collapse', tmp.join('\n'), expires);
}
function set_cookie(name, value, expires)
{
document.cookie = name + '=' + escape(value) + '; path=/' + (typeof expires != 'undefined' ? '; expires=' + expires.toGMTString() : '');
}
function delete_cookie(name)
{
document.cookie = name + '=' + '; expires=Thu, 01-Jan-70 00:00:01 GMT' + '; path=/';
}
function fetch_cookie(name)
{
cookie_name = name + '=';
cookie_length = document.cookie.length;
cookie_begin = 0;
while (cookie_begin < cookie_length)
{
value_begin = cookie_begin + cookie_name.length;
if (document.cookie.substring(cookie_begin, value_begin) == cookie_name)
{
var value_end = document.cookie.indexOf (';', value_begin);
if (value_end == -1)value_end = cookie_length;
return unescape(document.cookie.substring(value_begin, value_end));
}
cookie_begin = document.cookie.indexOf(' ', cookie_begin) + 1;
if (cookie_begin == 0)break;
}
return null;
}
продолжение следует...
Комментарии
Сворачивает отлично, а вот стоит чуток подождать и перестает разворачивать, стрелочка пропадает
странно, не замечал ни разу
а js-ошибки не вылазят? а каким браузером пользуетесь?
Браузер FF, js ошибок нет, кстати у вас на сайте все отлично работает
либо у вас конфликтует js с другими (хотя это мало вероятно), либо css свойства table,tbody,thead .. перекрываются
надо смотреть, ничего определённее сказать не могу
Это заработало. просто не было картинки с названием menu-expanded_collapsed.png
теперь другая проблема, последнее сообщение и количество коментариеа отображаются, а вот автор и время нет
ой, да. забыл написать: я использую свою функцию для отображения время/даты и пользователя
function MY-THEME-NAME_forum_format($topic)
см. UPD перед js файлом
Небольшие косметические изменения все и вроде все работает
Немного подправил пути к файлам...
А так в целом все работает безупречно!
Большое спасибо!
Немного подправил пути к файлам...
А какие именно подправляли пути, уважаемый.
После того, как внес поправки описанные выше при создании и редактировании поста попадаю в пустую страницу.
добавил указанные функции в файл template.php находящийся в папке с темой, но форум не изменился
в чем я не прав?
<?php ... ?> убрали?
название вашей темы в названиях функций вместо MY-THEME-NAME исправили?
да "<?php" убрал.
и название исправил...
может тело в том что у меня в названии темы подчеркивание?
получается theme_new_forum_list
Применительно стандартной темы у меня получается garland_forum_list - при этом все работает, правда почему то когда в форуме создаю/изменяю пост или комментарий после нажатия кнопки "отправить" попадаю черт знает куда, причем изменения вносятся, а визуально в этот момент у меня белое окно. Т.е. при стандартных установках после нажатия я попадаю, например ...node/4#comment-4, а с этими изменениями/улучшениями я попадаю в ...comment/edit/4
У кого такая же беда, подскажите, как исправить, я в пхп не сильно шарю, поэтому испытываю определенные сложности с этим делом.
Заново приклеил все функции в DW к исходному файлу, перезалил - всё работает. Странно. Так и не разобрался в чем была проблема. Пока работает и ладно.
Автору ещё раз спасибо. Ждем новых введений.
у меня тоже все починилось, просто перезалил еще раз. спасибо
все прекрасно работает, автору спасибо
Не побоюсь этого слова, здорово! Но один из админов установил FlatForum и количество просмотров после установки этого кода не просматривается. Они конфликтуют?
И еще наивный вопрос - куда класть myforum.js и нужно ли его специально вызывать из кода (дописывать шаблон), или достаточно просто закачать файл?
!!! заметил, что после вышеописанных процедур, информация о последних сообщениях показывается только для тех у кого в правах доступа разрешено управлять материалами (модуль node)
а кому запрещено, показывает, что последних сообщений нет.
что за зверь то такой и как с ним бороться?
всему причина – модуль Forum Access
удалил, обновил в «Публикациях» правила доступа
всё! теперь всем доступен этот чудный фейс форума
ох как я доволен!
studmedia_red ,
1. По поводу FlatForum не знаю, но догадываюсь что конфликтуют,
если кол-во просмотров не видно значит флат форум переопределил ту же функцию что и я переопределял.
2. myforum.js клади куда хочешь, я положил в /misc
и в функции:
> function MY-THEME-NAME_forum_list($forums, $parents, $tid) {
.. я указал откуда его брать
drupal_add_js('misc/myforum.js');
SlavviR , у меня таких проблем нет, смотрите права доступа к форумам и нодам для анонимов,
у меня все и незарегистрированный пользователь тоже видят число сообщений.
Я - начинающий друпаловод Объясните, пожалуйста, что значит: "Для решения этих задач переопределяю функцию theme_forum_list". Это мне надо в template.php добавить этот код??? И если да, то в какой участок?
да, надо добавить код в template.php заменив при этом "theme" названием свой темы, без разницы в какой участок.
если не понятно - посмотрите видео
http://drupaldojo.com/lesson/theming-like-a-pro
неперекрывается функция
ставлю в template.php
function mytheme_forum_list($forums, $parents, $tid) {
echo "gfmgfmhghmhj";
}
и не ничего не выводится
а к 6 весии Drupal такого кода нет?
Явно нету(
Друзья.. готов ли кто нибудь поделится аналогом решения под 6 Друпал?