Если нужно НЕ выводить блок на страницах форума, то в настройках блока ставим:
"Показать, если данный PHP-код возвращает TRUE (PHP-режим, только для экспертов)."
А ниже вводим код:
<?php
$result=true;
if ((arg(0) == 'node') && is_numeric(arg(1))) {
$node = node_load(arg(1));
if ( $node->type == "forum" ) $result=false;
}
return $result;
?>
Код возвращает TRUE только, если в данный момент не просматривается документ типа 'forum'.
А раз так - блок выводится всегда, кроме случая просмотра документа типа 'forum'.
Комментарии
А добавить путь forum в настройках для блока хуже?
хм, ну это только отдельную ветку
в списке форума не покатит
Ну почему же? Указать путь forum/* и всё;-).
не всегда указать путь проще.
Сам пользуюсь например когда не хочу адсенс отображать в админке или еще где.
Пути - там или "только запретить" или "только разрешить"
А теперь, господа хорошие учтите что пути иногда сам меняешь. то есть там у тебя уже не /node/212312 а чтото типа /vasya-pupkin-syel-sabaku
Да, есть мелкий недостаток метода. PHP кодом можно ошибицо и все завалить. Но это цена за гибкость.
forum/* - это то, что я попробовал в первую очередь. Результата это не дало.
Дело в том, что этот путь соответствует оглавлению всех форумов, а при просмотре отдельной ноды и путь другой (content/sdsdfsdf). Причём он такой же как и у остальных типов документов.
Поэтому и нужно было отделить именно по типу документа.
кстати странно что оно не решено на уровне друпала. урлы ниче не дают
я когда то тоже пришел именно к node_load, честно говоря неприятное решение
if (arg(0) == 'node') {
$node = node_load(arg(1));
if ($node->type == 'forum') return 1;
}
?>
Вот тут вы не правы. Посмотрите иcходный код функции и поймете:
<?php
function node_load($param = array(), $revision = NULL, $reset = NULL) {
static $nodes = array(); // сюда идет своего рода "кеширование" загруженных нод
........
if (is_numeric($param)) {
if ($cachable && isset($nodes[$param])) {
return is_object($nodes[$param]) ? drupal_clone($nodes[$param]) : $nodes[$param]; // возврат ревизии ноды из кеша
}
........
?>
Так что не бойтесь. не сделает оно node_load дважды.
Разве что просмотре версий. но так ли часто оно надо?
Короче, дергайте сколько хотите.
Почему?
Где-то здесь за углом говорили, что нода берётся из кеша, если она считала для показа в центре страницы. Лишней нагрузки не должно быть.
Влад, посмотри исходник функции. там нет кеша. есть на уровне самой функции. Все.
Это:
<?php
if ($revision) {
array_unshift($arguments, $revision);
$node = db_fetch_object(db_query('SELECT n.nid, r.vid, n.type, n.status, n.created, n.changed, n.comment, n.promote, n.sticky, r.timestamp AS revision_timestamp, r.title, r.body, r.teaser, r.log, r.format, u.uid, u.name, u.picture, u.data FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revisions} r ON r.nid = n.nid AND r.vid = %d WHERE '. $cond, $arguments));
}
else {
$node = db_fetch_object(db_query('SELECT n.nid, n.vid, n.type, n.status, n.created, n.changed, n.comment, n.promote, n.sticky, r.timestamp AS revision_timestamp, r.title, r.body, r.teaser, r.log, r.format, u.uid, u.name, u.picture, u.data FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revisions} r ON r.vid = n.vid WHERE '. $cond, $arguments));
}
?>
функция дернет полюбому.
на уровне хуков, да. может быть кеш. тока хзхз.
Ну здрасьте... Смотрим чуть выше (ты же процитировал этот фрагмент):
<?php
static $nodes = array();
// тут пропущено
if (is_numeric($param)) {
if ($cachable && isset($nodes[$param])) {
return is_object($nodes[$param]) ? drupal_clone($nodes[$param]) : $nodes[$param];
?>
На запрос страницы каждая нода забирается из БД только один раз, независимо от числа вызовов node_load. Кешированные ноды хранятся в памяти - в статической переменной $nodes. Чем это не кеширование?
Если же сделать перманентный кеш в БД, то какая разница будет делаться запрос к таблице node_revisions или к таблице cache?
на тему node_load node_save - ты не прав... я пользую кешак собственного производства. вне базы.
И поверь дернуть все из файла было бы гораздо быстрее чем из БД
Есть идея патча на ядро на эти функции чтобы закешировать только запросы касательно таблицы node - то есть дать системе пользовательские данные тянуть потом. и на пару десятков запросов поджаться при выводе списка нод.
Ясен пень что запросы легковесные, но когда их много... эм.... эм... тормоз это.
Кстати в 6ом друпале та же жопа...
Хреново. Лишний запрос на каждую ноду даже при показе тизера.
10 нод на страницу - 10 запросов. 100 нод - 100 запросов.
Хорошо одно. запросы идут по индексу nid и быстрые. только на быстродействие тоже влияет в плохую сторону.
http://drupal.org/files/issues/node_62.patch примерный патч на кеширование.... учитывая кеш самого друпала...... эммм.... эмм....
ну все тут понятно...
Аналогичный патч надо на node_save чтобы cache_set пахало.
С моими патчами для кешака на файловой системе будет летучая хрень....
Вопрос: а какого х...я не включили энто дело в мейнстрим?
Поправка... нет в кеше по той причине что вид загруженой ноды зависитот юзера. Упс.
нужно написать модуль который будет добавлять в свойствах блока дерево таксономий (как при добавлении ноды) - и что-бы можно было указать в каких таксономиях показывать блок.
двайте еще пооптимизируем, мне тоже в шапке код не нравится
if (arg(0) == 'node' && arg(1)){
$node = node_load(arg(1));
return ($node->type != 'forum');
}
?>
Это вот на setegnom подойдет: Показывать/не показывать блок для типов документов и/или URL
Использовал в работе код от karinka.
<?php
if (arg(0) == 'node' && arg(1)){
$node = node_load(arg(1));
return ($node->type != 'forum');
}
?>
Спасибо за советы. Про оптимизацию даже не думал - а зря! Нужно будет выработать привычку.
А ведь всё таки НЕ РАБОТАЕТ!
Этот код я написал с самого начала, но от него отказался.
И знаете почему? Потому что на странице форума блок не показывается, но также он не показывается и на многих других (типа главная и др.) Эти страницы не являются нодами и для них мы даже не заходим в блок if. А когда увидел снова здесь, то подумал, что, возможно я ошибся в логике - всякое бывает.
<?php
if (arg(0) == 'node' && arg(1)){
$node = node_load(arg(1));
return ($node->type != 'forum');
}
?>
Вывод: лучшее враг хорошего!
Вот рабочий код:
<?php
$result=true;
if ((arg(0) == 'node') && is_numeric(arg(1))) {
$node = node_load(arg(1));
if ( $node->type == "forum" ) $result=false;
}
return $result;
?>
if (arg(0) == 'node' && arg(1)){
$node = node_load(arg(1));
return ($node->type != 'forum');
}
return 1;
?>
извините, все равно я за минимализм
Что я не вгоняю в это обсуждение, но вроде такой вот код точно не показывает блок на форуме:
<?php
if (arg(0) == 'node' && is_numeric(arg(1))){
$node = node_load(arg(1));
return ($node->type != 'forum');
} elseif (arg(0) == 'forum') {
return False;
}
return True;
?>
Круто - работает. спс
Да, код от karink'и самый минимальный.
2 Separator@drupal.org:
ваш код исключит показ блока и при просмотре страницы типа "forum" и на странице со списком всех форумов (и контейнеров). Мне кажется, что он универсальный. Это хорошо.
Мой частный случай таков, что при просмотре списка всех форумов блоки вообще не выводятся (отключены в шаблоне темы), поэтому я даже не подумал отключать их в этом случае.
Спасибо всем за помощь.
Вот нашёл решение как включить блок ТОЛЬКО на страницах форума:
Display block only for forums
Ладно - продублирую, чтобы далеко не ходить:
<?php
if (arg(0) == 'forum') {
return TRUE;
}
if (arg(0) == 'node' && ctype_digit(arg(1))) {
$node = node_load(arg(1));
if ($node->type == 'forum') {
return TRUE;
}
}
return FALSE;
?>
А чем вас is_numeric(arg(1)) не устраивает?
А какая разница?
Кстати, если вы хотите убрать блок со страницы редактирования или добавления тем форума, то надо добавить
arg(2) ==null
Похоже вы правы. Пока не проверял - форум отключен вообще. Заказчик решил интегрировать phpBB...
Итак, подведём итоги. Код проверен лично:
Показать блок ТОЛЬКО на страницах форума
//Показать блок ТОЛЬКО на страницах форума (включая просмотр и редактирование нод форума)
if (arg(0) == 'forum') return TRUE;
if (arg(0) == 'node' && is_numeric(arg(1))) {
$result= db_fetch_object(db_query("SELECT n.type FROM {node} AS n WHERE n.nid=%d LIMIT 1", arg(1)));
if ($result->type == 'forum') return TRUE;
}
return FALSE;
?>
НЕ показать блок на страницах форума:
//НЕ показать блок на страницах форума (включая просмотр и редактирование нод форума)
if (arg(0)=='node' && is_numeric(arg(1))){
$result= db_fetch_object(db_query("SELECT n.type FROM {node} AS n WHERE n.nid=%d LIMIT 1", arg(1)));
if ($result->type == 'forum') return FALSE;
} elseif (arg(0)=='forum') return FALSE;
return TRUE;
?>
НЕ показать блок ТОЛЬКО при просмотре и редактировании топика:
if (arg(0) == 'node' && arg(1)){
$result= db_fetch_object(db_query("SELECT n.type FROM {node} AS n WHERE n.nid=%d LIMIT 1", arg(1)));
return ($result->type != 'forum');
}
?>
Как показать блок только при просмотре и редактировании ноды типа форум догадайтесь сами...
Решение было сохранено на сайте DrupalCookBook.ru:
Показывать / НЕ показывать блок на страницах относящихся к форуму.
Авторы, предложившие решения также указаны в сохранённой статье.
А плюс к этому, при создании топика обеспечить видимость блока, как пропишется?