Решено: включить/выключить блок на форуме

Главные вкладки

Аватар пользователя VladSavitsky VladSavitsky 5 января 2008 в 22:32

Если нужно НЕ выводить блок на страницах форума, то в настройках блока ставим:
"Показать, если данный 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'.

Комментарии

Аватар пользователя l_test l_test 6 января 2008 в 3:52

cwer wrote:
хм, ну это только отдельную ветку
в списке форума не покатит

Ну почему же? Указать путь forum/* и всё;-).

Аватар пользователя Ильич Рамирес Санчес Ильич Рамирес Санчес 7 января 2008 в 13:54

не всегда указать путь проще. Smile
Сам пользуюсь например когда не хочу адсенс отображать в админке или еще где.

Пути - там или "только запретить" или "только разрешить"

А теперь, господа хорошие учтите что пути иногда сам меняешь. то есть там у тебя уже не /node/212312 а чтото типа /vasya-pupkin-syel-sabaku

Да, есть мелкий недостаток метода. PHP кодом можно ошибицо и все завалить. Но это цена за гибкость.

Аватар пользователя VladSavitsky VladSavitsky 7 января 2008 в 19:27

forum/* - это то, что я попробовал в первую очередь. Результата это не дало.
Дело в том, что этот путь соответствует оглавлению всех форумов, а при просмотре отдельной ноды и путь другой (content/sdsdfsdf). Причём он такой же как и у остальных типов документов.
Поэтому и нужно было отделить именно по типу документа.

Аватар пользователя Гость Гость (не проверено) 7 января 2008 в 23:48

я когда то тоже пришел именно к node_load, честно говоря неприятное решение

<?php
if (arg(0) == 'node') {
    $node = node_load(arg(1));
    if ($node->type == 'forum') return 1;
}
?>
Аватар пользователя Ильич Рамирес Санчес Ильич Рамирес Санчес 8 января 2008 в 1:09

Гость wrote:
я когда то тоже пришел именно к node_load, честно говоря неприятное решение

<?php
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]; // возврат ревизии ноды из кеша Smile
}
........
?>

Так что не бойтесь. не сделает оно node_load дважды. Smile

Разве что просмотре версий. но так ли часто оно надо?

Короче, дергайте сколько хотите.

Аватар пользователя VladSavitsky VladSavitsky 8 января 2008 в 1:17

Почему?
Где-то здесь за углом говорили, что нода берётся из кеша, если она считала для показа в центре страницы. Лишней нагрузки не должно быть.

Аватар пользователя Ильич Рамирес Санчес Ильич Рамирес Санчес 8 января 2008 в 1:22

Влад, посмотри исходник функции. там нет кеша. есть на уровне самой функции. Все.

Это:
<?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));
}

?>
функция дернет полюбому.

на уровне хуков, да. может быть кеш. тока хзхз. Smile

Аватар пользователя axel axel 8 января 2008 в 14:01

Ну здрасьте... Смотрим чуть выше (ты же процитировал этот фрагмент):

<?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?

Аватар пользователя Ильич Рамирес Санчес Ильич Рамирес Санчес 8 января 2008 в 17:16

на тему node_load node_save - ты не прав... я пользую кешак собственного производства. вне базы.

И поверь дернуть все из файла было бы гораздо быстрее чем из БД

Есть идея патча на ядро на эти функции чтобы закешировать только запросы касательно таблицы node - то есть дать системе пользовательские данные тянуть потом. и на пару десятков запросов поджаться при выводе списка нод. Wink

Ясен пень что запросы легковесные, но когда их много... эм.... эм... тормоз это.

Аватар пользователя Ильич Рамирес Санчес Ильич Рамирес Санчес 8 января 2008 в 1:26

Кстати в 6ом друпале та же жопа... Sad
Хреново. Лишний запрос на каждую ноду даже при показе тизера.
10 нод на страницу - 10 запросов. 100 нод - 100 запросов.

Хорошо одно. запросы идут по индексу nid и быстрые. только на быстродействие тоже влияет в плохую сторону.

Аватар пользователя Ильич Рамирес Санчес Ильич Рамирес Санчес 8 января 2008 в 1:33

http://drupal.org/files/issues/node_62.patch примерный патч на кеширование.... учитывая кеш самого друпала...... эммм.... эмм....
ну все тут понятно...

Аналогичный патч надо на node_save чтобы cache_set пахало.

С моими патчами для кешака на файловой системе будет летучая хрень....

Вопрос: а какого х...я не включили энто дело в мейнстрим? Smile

Аватар пользователя VladSavitsky VladSavitsky 8 января 2008 в 14:11

Использовал в работе код от karinka.
<?php
if (arg(0) == 'node' && arg(1)){
$node = node_load(arg(1));
return ($node->type != 'forum');
}
?>
Спасибо за советы. Про оптимизацию даже не думал - а зря! Нужно будет выработать привычку.

Аватар пользователя VladSavitsky VladSavitsky 8 января 2008 в 15:36

А ведь всё таки НЕ РАБОТАЕТ!
Этот код я написал с самого начала, но от него отказался.
И знаете почему? Потому что на странице форума блок не показывается, но также он не показывается и на многих других (типа главная и др.) Эти страницы не являются нодами и для них мы даже не заходим в блок 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;
?>

Аватар пользователя Separator@drupal.org Separator@drupal.org 10 января 2008 в 9:24

Что я не вгоняю в это обсуждение, но вроде такой вот код точно не показывает блок на форуме:
<?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;
?>

Аватар пользователя mazta mazta 27 мая 2011 в 0:32

<a href="mailto:Separator@drupal.org">Separator@drupal.org</a> wrote:
Что я не вгоняю в это обсуждение, но вроде такой вот код точно не показывает блок на форуме:
<?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;
?>

Круто - работает. спс

Аватар пользователя VladSavitsky VladSavitsky 11 января 2008 в 22:50

Да, код от karink'и самый минимальный.

2 Separator@drupal.org:
ваш код исключит показ блока и при просмотре страницы типа "forum" и на странице со списком всех форумов (и контейнеров). Мне кажется, что он универсальный. Это хорошо.
Мой частный случай таков, что при просмотре списка всех форумов блоки вообще не выводятся (отключены в шаблоне темы), поэтому я даже не подумал отключать их в этом случае.

Спасибо всем за помощь.

Аватар пользователя VladSavitsky VladSavitsky 30 января 2008 в 1:58

Вот нашёл решение как включить блок ТОЛЬКО на страницах форума:
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;
?>

Аватар пользователя Natalie Natalie 30 января 2008 в 2:21

Кстати, если вы хотите убрать блок со страницы редактирования или добавления тем форума, то надо добавить

arg(2) ==null

Аватар пользователя VladSavitsky VladSavitsky 24 февраля 2008 в 0:50

Итак, подведём итоги. Код проверен лично:

Показать блок ТОЛЬКО на страницах форума
//Показать блок ТОЛЬКО на страницах форума (включая просмотр и редактирование нод форума)
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');
}
?>

Как показать блок только при просмотре и редактировании ноды типа форум догадайтесь сами...

Drupal CookBook - Готовить может каждый!Решение было сохранено на сайте DrupalCookBook.ru:
Показывать / НЕ показывать блок на страницах относящихся к форуму.
Авторы, предложившие решения также указаны в сохранённой статье.

Аватар пользователя mai.po mai.po 20 сентября 2008 в 8:17

"VladSavitsky" wrote:
Показать блок ТОЛЬКО на страницах форума (включая просмотр и редактирование нод форума)

А плюс к этому, при создании топика обеспечить видимость блока, как пропишется?