Сниппет, выводящий анонсы материалов для определенного термина словаря
Прислано: anpal
пн, 23/02/2009 - 07:23
Знатоки PHP подскажите как откорректировать сниппет
(повторно http://www.drupal.ru/node/24907)
Имеется сниппет, который выводит блок меню с терминами словаря, каждый термин выводит список анонсов материалов по определенной теме. Вот этот сниппет:
<?php
$vid = 7; // Номер словаря
$pole = array();
$items = array();
$terms = taxonomy_get_tree($vid);
//var_dump($terms);
foreach ( $terms as $term ) {
$count = db_result(db_query("SELECT COUNT(nid) FROM {term_node} WHERE tid = %d", $term->tid));
$pole[]=Array ( l($term->name, "taxonomy/term/$term->tid", array( "title"=>$term->description)), $term->depth, $count, $term->tid);
}
$depth =-1;
foreach ($pole as $list) {
//$depth- глубина предыдущего уровня
//$list[1] - глубина текущего элемента
if ($list[1] == $depth) {
echo "</li>";
next;
}
while ($list[1] != $depth) {
if ($list[1] > $depth) {
$depth++;
echo "\n<ul class='menu'>";
next;
}
if ($list[1] < $depth) {
$depth--;
echo "\n</li>\n</ul>";
}
}
echo "\n<li class='leaf'>$list[0]";
$depth=$list[1];
}
//Закрываем все открытые теги до нулевого уровня:
$depth=0;
while ($list[1] != $depth) {
if ($list[1] > $depth) {
$depth++;
echo "</li>\n</ul>";
}
}
?>Сниппет работает отлично для одноязыкового сайта.
Вопрос первый: как ввести в него переменную, чтобы можно было переключится на другой язык. Без такой переменной настройки сбрасываются.
Вопрос второй: упомянутый сниппет не выводит всплывающую подсказку пункта (термина) меню. Если заменить в нем эти две строки:
$pole[]=Array ( l($term->name, "taxonomy/term/$term->tid", array( "title"=>$term->description)), $term->depth, $count, $term->tid);
На другие две:
$pole[]=Array ("tid."' title='".$term->description."'>".$term->name."", $term->depth, $count, $term->tid);
Тогда сниппет выводит всплывающую подсказку термина, но привязка материалов к пунктам термина значительно хуже первого варианта и разумеется здесь тоже нет переменной, которая дала бы возможность переключения языка.
Для знающего PHP это простое решение. Потратил уже несколько дней над решением этих проблем, но метод тыка не увенчался успехом. Еще не утратил надежды на вашу помощь, хотя с каждым днем надежды все меньше и меньше. Благодарю
- anpal's blog
- Для комментирования войдите или зарегистрируйтесь
Чтобы вывести всплывающую подсказку - почитайте про функцию l() на api.drupal.ru.
У этой функции есть один из параметров, через который можно передать любые атрибуты ссылке, которую она делает.
По поводу многоязычности - ничего не могу подсказать.
- Для комментирования войдите или зарегистрируйтесь
<?php
$vid = 7; // Номер словаря
$language = 'ru'; // Язык
$pole = array();
$items = array();
$terms = taxonomy_get_tree($vid);
//var_dump($terms);
foreach ( $terms as $term ) {
$count = db_result(db_query("SELECT COUNT(n.nid) FROM {node} n
INNER JOIN {term_node} tn ON n.nid = tn.nid
WHERE tn.tid = %d AND n.language = '%s'", $term->tid, $language));
$pole[] = array(l($term->name, 'taxonomy/term/'. $term->tid, array('attributes' => array('title' => $term->description))), $term->depth, $count, $term->tid);
}
$depth =-1;
foreach ($pole as $list) {
//$depth- глубина предыдущего уровня
//$list[1] - глубина текущего элемента
if ($list[1] == $depth) {
echo "</li>";
next;
}
while ($list[1] != $depth) {
if ($list[1] > $depth) {
$depth++;
echo "\n<ul class='menu'>";
next;
}
if ($list[1] < $depth) {
$depth--;
echo "\n</li>\n</ul>";
}
}
echo "\n<li class='leaf'>$list[0]";
$depth=$list[1];
}
//Закрываем все открытые теги до нулевого уровня:
$depth=0;
while ($list[1] != $depth) {
if ($list[1] > $depth) {
$depth++;
echo "</li>\n</ul>";
}
}
?>
- Для комментирования войдите или зарегистрируйтесь
Павел с праздником Вас и всех друпальцев!
Большое спасибо, проверил, но к сожалению в коде какая-то ошибка. Все пункты меню друпал убрал и высветил этот сниппет, к сожалению определить ошибку не могу
- Для комментирования войдите или зарегистрируйтесь
я чесно не понял что же вам надо, какие термины выводить?, те в которые есть ноды определенного языка ? причем тут анонсы
- Для комментирования войдите или зарегистрируйтесь
2 penexe, там у тебя ошибачка с третьим параметром ф-ии l().
2 anpal, если не выводится подсказка, значит ее нет, проверяй, у меня все норм.
не понимаю зачем считаеш $count a потом нигде не используеш?
и не ясно с многоязычностью, кста обрамляй текст в t
- Для комментирования войдите или зарегистрируйтесь
2 penexe, там у тебя ошибачка с третьим параметром ф-ии l().
дану?
- Для комментирования войдите или зарегистрируйтесь
угу
http://www.w3.org/TR/html401/struct/links.html#edef-A
где ты там увидел то что выводит твой код?
...
<li class='leaf'><a href="/?q=taxonomy/term/62" attributes="">2 _R the two</a>
!!!attributes=""
...
афтар правельно прописал l() еще в верху
- Для комментирования войдите или зарегистрируйтесь
Павел!
С помощью этого сниппета создаю блок, например РАЗДЕЛЫ (наименование меню) в котором размещаю пункты меню, создав предварительно соответствующий словарь. При вызове конкретного пункта меню выводятся все анонсы материалов по этой конкретной теме, подобно тому как выводятся анонсы на главную страницу. Все это повторяется и для другого языка, но без включения переменной в код сниппета, друпал некорректно переключает языки, а переключение должно быть перекрестное, то есть, при любом переключении должен выводиться конкретный материал или соответственно группа материалов(анонсы) по определенной теме.
oblivion написал - зачем считаеш $count a потом нигде не используеш?
Просто слаб в PHP и не уверен, что правильно отредактирую, поэтому и попросил помочь.
- Для комментирования войдите или зарегистрируйтесь
угу
http://www.w3.org/TR/html401/struct/links.html#edef-A
где ты там увидел то что выводит твой код?
...
<li class='leaf'><a href="/?q=taxonomy/term/62" attributes="">2 _R the two</a>
!!!attributes=""
...
афтар правельно прописал l() еще в верху
не путайте 5ку и 6ку
- Для комментирования войдите или зарегистрируйтесь
базара ноль, признаю свою невнимательность
- Для комментирования войдите или зарегистрируйтесь
Павел!
С помощью этого сниппета создаю блок, например РАЗДЕЛЫ (наименование меню) в котором размещаю пункты меню, создав предварительно соответствующий словарь. При вызове конкретного пункта меню выводятся все анонсы материалов по этой конкретной теме, подобно тому как выводятся анонсы на главную страницу. Все это повторяется и для другого языка, но без включения переменной в код сниппета, друпал некорректно переключает языки, а переключение должно быть перекрестное, то есть, при любом переключении должен выводиться конкретный материал или соответственно группа материалов(анонсы) по определенной теме.
с языками я не работал никогда,НО друпал должен сам менять ссылки на соответствующие
а уж таксономия вибирает или нет только нужные ноды это я незнаю
<?php $vid = 7; // Номер словаря $pole = array(); $items = array(); $terms = taxonomy_get_tree($vid); //var_dump($terms); foreach ( $terms as $term ) { $pole[] = array(l($term->name, 'taxonomy/term/'. $term->tid, array('attributes' => array('title' => $term->description))), $term->depth); } $depth =-1; foreach ($pole as $list) { //$depth- глубина предыдущего уровня //$list[1] - глубина текущего элемента if ($list[1] == $depth) { echo "</li>"; next; } while ($list[1] != $depth) { if ($list[1] > $depth) { $depth++; echo "\n<ul class='menu'>"; next; } if ($list[1] < $depth) { $depth--; echo "\n</li>\n</ul>"; } } echo "\n<li class='leaf'>$list[0]"; $depth=$list[1]; } //Закрываем все открытые теги до нулевого уровня: $depth=0; while ($list[1] != $depth) { if ($list[1] > $depth) { $depth++; echo "</li>\n</ul>"; } } ?>
- Для комментирования войдите или зарегистрируйтесь
Где-то в вашем коде закралась ошибка и друпал игнорирует выполнение кода
- Для комментирования войдите или зарегистрируйтесь
Касательно многоязычности. Если в этот сниппет ввести переменую, которую необходимо ввести также и в settings.php, тогда вопрос переключения на любой язык решается без проблем
- Для комментирования войдите или зарегистрируйтесь
Где-то в вашем коде закралась ошибка и друпал игнорирует выполнение кода
да рабочий код 100%, у вас формат ввода php?
- Для комментирования войдите или зарегистрируйтесь
Извени дорогой, формат PHP, тут другое приключение, мне FCKeditor нагородил кучу тегов. Большое спасибо, вечером протестирую и обязательно сообщу результат, а блок выводит нормально. Несмотря на то, что я запретил в настройках редактора вносить коррективы, он гад все-таки не всегда слушается
- Для комментирования войдите или зарегистрируйтесь
К сожалению, ничего доброго не получилось.
1. Все варианты сниппетов по данной теме – рабочие;
2. Попытка сделать из таксономии навигационное меню, не получается: таксономия это классификационная система, а меню – навигационная система, здесь нужен специалист. Возможно, для одноязыкового сайта это реально с помощью ряда меню с таксономией (тщательно не проверял);
3. Для многоязычного видимо следует поступить иначе. Создать многоязычное меню с соответствующими пунктами и такой же словарь таксономии с теми же пунктами. При включении пукта меню, должен срабатывать небольшой сниппет (какая-то часть из первого сниппета, отраженного в начале темы, который выводил бы только анонсы материалов по определенной теме). Для другого языка и последующих языков все аналогично;
4. Самый оптимальный вариант – сделать такой модуль, но, похоже это далекая перспектива наших умельцев;
5. Полагаю, предложенное решение третьего пункта не самый оптимальный вариант, но вполне реальный. Просто я в ПХП никакой, поэтому излагаю описательно. Если в чем-то не прав, поправьте;
6. И последнее, подскажите пожалуйста этот вариант сниппета, выводящего только анонсы по определенной теме (пункт меню и словаря) и как привязать его к пункту меню, чтобы этот сниппет срабатывал. Заранее благодарю
- Для комментирования войдите или зарегистрируйтесь
В дополнение к предыдущему комментарию:
Специально проверил работу сниппета для одноязыкового сайта, работает прекрасно, а для многоязыкового нужна доработка
- Для комментирования войдите или зарегистрируйтесь
foreach ( $terms as $term ) {
$count = db_result(db_query("...
Дальше даже читать не стал. Это что, если у меня десятка терминов на ноду, то будет десять запросов к базе?!
Кэширование отсутствует.
Потом говорят, что друпал тормознутый. Он не тормознутый, он слишком гибкий.
- Для комментирования войдите или зарегистрируйтесь
to Dan
Если вы так хорошо разбираетесь в Друпале, то подскажите как лучше решить проблему и многие будут благодарны. Критика принимается, но где решение, критиковать проще. Меня вообще поразил факт, что в такой хорошей СМС нет двух основных модулей: нормального многоязычного меню (пришлось самому выкручиваться) и вывода анонсов по определенной теме на многоязычном сайте( и здесь до сих пор ищу решение вопроса - Друпал сбрасывает привязку отдельных терминов, при переключении на другой язык). Прошу учесть, очень многие поверхностно знают Друпал, им просто нужно создать для себя один, или от силы два сайта без Вьюз, ССК, и нет смысла углубляться, например в PHP. Наверняка есть решения, но они не выносятся на общее обозрение, а жаль. Хочется пожелать вам успехов, но просьба подсказать и решение этих вопросов.
Еще раз повторюсь:с помощью сниппета создаю блок меню, который выводит термины словаря как пункты меню (никаких дополнительных модулей не использую, хотя пытался подключить ряд дополнительных модулей типа taxonomy redirect и другие, для решения вопроса перекрестной навигации, но эффект нулевой), просто для вывода меню и анонсов работает один модуль taxonomy.
Результат: 1)для одноязыкового сайта анонсы выводятся нормально и привязка терминов не сбрасывается; 2)для многоязыкового сайта анонсы выводятся, но привязка отдельных терминов Друпалом сбрасывается, поэтому невозможна перекрестная навигация. Осталось лишь наладить перекрестную навигацию, но как, увы незнаю
- Для комментирования войдите или зарегистрируйтесь
Если вы так хорошо разбираетесь в Друпале, то подскажите как лучше решить проблему и многие будут благодарны. Критика принимается, но где решение, критиковать проще.
Решать проблему не буду - устал я уже подобные решать, а критику - пожалуйста.
1. Если нам просто надо получить количество нод у термина - лучше воспользоваться ф-цией
taxonomy_term_count_nodes. Это избавит нас от сырого SQL-кода и не возникнет проблем при смене версии друпал и таксономии.
2. Если уж решили использовать SQL, то лучше писать запрос на выдачу сразу полного результата.
3. Не понял сакрального смысла в ручной расстановке тэгов LI. Почему не используем theme('item_list, $items);
4. Про кэширование уже говорил - какова скорость добавления новых терминов и нового материала на сайт? Так ли необходимо при каждой загрузке страницы считать материалы и термины (для зарег. юзеров)? Сделайте модуль с выводом блока, блок сохраняем в кэше на опр. время или вешаем обновление на nodeapi - добавление, удаление, изменение ноды.
- Для комментирования войдите или зарегистрируйтесь
Даниэль!
Если бы у меня были познания на вашем уровне, я бы наверное решил самостоятельно и никого бы не беспокоил. Если найдете время, то постучите в асю 413864841. По первому пункту - страница пустая. Второй и третий с моими познаниями мне ни о чем не говорят. Четвертый пункт, разумеется мне не надо считать ни материалы, ни термины, но как правильно отредактировать сниппет я незнаю или тем более сделать блок. Мне просто нужен вывод анонсов по определенной теме словаря в алфавитном порядке. Естественно хочется сделать так, чтобы было как можно меньше запросов к базе, но уж как получится. Мне просто нужен на сегодня двуязычный сайт и решил немного разобраться, считаю это верный путь, иначе в работе были бы сплошные проблемы, правда очень уж это затянулось. Спасибо за ответ, с уважением Андрей Васильевич
- Для комментирования войдите или зарегистрируйтесь
To penexe
Сомневаюсь я в дельных предложениях, приношу искреннюю благодарность Павлу за хороший вариант сниппета и хотел лишь попросить вас упростить его, с учетом предложений DANа и на этом закрыть тему. Разумеется, если это вас не затруднит. В принципе, с учетом модуля nodetypeviews проблема решена и для многоязыкового сайта, а построение списка анонсов осуществляется по дате последней публикации и его можно оставить без корректуры. Похоже он более удачен, чем сортировать по алфавиту.
- Для комментирования войдите или зарегистрируйтесь







Комментарии