Дорогие друпаловоды, столкнулся с проблемой, никак не найду решение
Вывожу в ноде поля из профиля2, обычные поля, заполненные пользователем, выводятся без заголовка вот так:
<?php$profile = profile2_load_by_user($node->uid) ;
print render(field_view_field( 'profile2' , $profile [ 'main' ] , 'field_name', array('label' => 'hidden') )) ; ?>
Но в случае, если значение поля является термином таксономии, то вот это:
<?phparray('label' => 'hidden')?>
не работает
Выводится и заголовок, и ссылка на термин.
Если ссылка меня устраивает, то заголовок никак не вписывается в node.tpl и дизайн.
Гуглёж не помог, может кто подскажет кусочек кода или куда смотреть?
UPD: вопрос с со скрытием заголовка решил (ниже написано), остался вопрос с обёрткой...
Комментарии
Вопрос решил с помощью вот такой конструкции:
<?php
$options = array(
'type' => 'taxonomy_term_reference_plain',
'label' => 'hidden',
);
$profile = profile2_load_by_user($comment->uid) ;
print
render(field_view_field( 'profile2' , $profile [ 'main' ] , 'field_name', $options )) ;?>
Одна проблема, значение поле выводится в обёртке Куча дивов ненужных..
Подскажите, пожалуйста, как исправить? Конкретно в моём случае, с print render...
Причём мне нужно именно это поле вывести в одном месте как значение, глобально вывод поля менять не нужно, так как оно выводится также и в других местах как надо...
Куда копать?
Спасибо всем, кто не прошёл мимо!
Установи Devel модуль на сайте. В шаблоне вывали свои данные в девел: dpm($profile); Найди в массиве нужное тебе поле и выведи его значение напрямую! Например, так: print $profile['field_name'][LANGUAGE_NONE][0]['value']; Это как пример, у тебя там будет что-то другое. LANGUAGE_NONE - это und (языковая принадлежность).
Такой вывод поля является дурным тоном:) Особенно для проектов с entity translation
Автору - либо используйте https://api.drupal.org/api/drupal/modules!field!field.module/function/fi..., либо просто переопределите шаблон поля, удалив из него лишние обертки, и тогда ваш метод тоже будет рабочим.
Вот я тоже смотрел на эту функцию, но как её использовать совместно с моим рабочим вариантом так и не понял
Просто заменить вот это
<?phpprint render(field_view_field( 'profile2' , $profile [ 'main' ] , 'field_name', $options )) ;?>
на это
<?phpprint render(field_view_field( 'profile2' , $profile [ 'main' ] , 'field_name', $options )) ;?>
не получится Или я не понял, как определить эту функцию в templait.php
Ну во первых LANGUAGE_NONE, как раз и не зависит от языка, в этом его фишка. А во вторых, сам вывод кучи мусора в шаблон - это бич Друпал! Само понятие шаблона отсутствует напрочь. Так как вам в шаблон вываливает кучу markup мусора. И вместо того, чтобы в шаблоне делать именно то, для чего он предназначен, а именно темизировать сырые данные, приходиться заниматься извращениями на подобии очистки от лишних враперов, классов и другой пурги, применяя при этом кучу функций ядра и нагружая сервер. И ради чего? Ради очистки от врапера? Не находите этот друпал вэй бредовым? Это кстати один из моментом, за что я ненавижу Друпал (не смотря на любовь к нему).
Ну-ну, https://api.drupal.org/api/drupal/includes!bootstrap.inc/constant/LANGUA...
А тут уже все зависит от того, как именно вы будете организовывать систему переводов. Я чаще всего делаю, как локализацию. Вон http://best-house.org двух язычный. Все пашет без проблем. Правда перевод только интерфейса, без контента. Но так ведь и при получение значения поля через функции ядра, вам тоже нужно передать $language->language Если вы используете не локализацию, а перевод!
Ах да. Я еще использую по умолчанию язык нейтральный (und)!
Вы явно не разбираетесь в том что пишите, извините, но подучите документацию, что ли.
Не нужно извинятся. Может я и не прав. Тогда ткните носом, буду благодарен. А ваш ответ смахивает на: ты неправ, вали отсюда, кури доки, учи матчасть. Хамство за вежливым ответом не спрятать.
Вообще я не хамил, ссылки на доки приводил, хотя хамство на этом форуме - обычное дело:)
«А тут уже все зависит от того, как именно вы будете организовывать систему переводов. Я чаще всего делаю, как локализацию. Вон http://best-house.org двух язычный. Все пашет без проблем. Правда перевод только интерфейса, без контента. Но так ведь и при получение значения поля через функции ядра, вам тоже нужно передать $language->language Если вы используете не локализацию, а перевод!
Ах да. Я еще использую по умолчанию язык нейтральный (und)!»
Где бред тут? Конкретно по сути?!
Спасибо. Вот такие вывел devel:
Вот как мне прописать функцию и распечатать?
Так? print $profile['field_numofholding'][LANGUAGE_NONE][0]['taxonomy_term'];
Смотря, что тебе нужно вывести. Если полностью сущность поля, то:
print render($profile['field_numofholding']);
Если имя термина, то путь к имени термина без рендера.
Кликаешь дважды на поле и тебе открывается путь к нему: $...массив. Вместо $... ставишь название своей переменной, например $profile.
Спасибо! Кое-что получилось
Код такой:
<?php$profile = profile2_load_by_user($comment->uid) ;
print $profile['main']->field_numofholding['und'][0]['taxonomy_term']->name;?>
Но дело в том, что поле выводится только у автора ноды (в двух словах, есть форум, есть комменты, в tpl комментария я вставляю выше написанный код, чтобы отобразить определённое поле в каждом комментарии, относящееся к профилю автора комментария).
У автора темы выглядит так:
У других комментаторов так:
Как выглядит, если выводить данные из массива со всей друпаловской неотключаемой обёрткой:
Я где-то ошибся в функции?
Если вы потом рендерите весь контент, то вы опять выводите те поля, которые уже вывели. К примеру получаем название:
$name = $profile['main']->field_numofholding['und'][0]['taxonomy_term']->name;
print $name; - вывели где надо вам это значение. И если вам данные этого поля больше не нужны и вы не хотите их выводить, то удалите их:
unset($profile['main']->field_numofholding); - это вы полностью грохнули поле из массива
Грохнуть не есть хорошо, комментаторы повторяются же в теме
В вашем примере у меня поле выводится только у первого комментария, где его автор является автором ноды (темы).
Я подозреваю, что проблема тут
$profile = profile2_load_by_user($comment->uid) ;
Эта схема работает при выводе массива print render(field_view_field, а вот просто вывод поля
<?php$profile = profile2_load_by_user($comment->uid) ;
print $profile['main']->field_numofholding['und'][0]['taxonomy_term']->name;?>
в этом случае не работает для всех комментаторов
Мы сейчас обсуждаем не совсем понятно что. Какой шаблон, комментариев? Какая задача стоит, четко только и понятно. Может вообще все по другому можно сделать или должно быть.
Кирилл, да вроде задачу озвучил, но попробую ещё раз.
1. Есть сайт, на нём пользователи с ролями. Также через модуль Profile2 заполняются поля.
Часть полей заполняет пользователь сам (номер телефона, город и тд), часть полей выбираются из списков (термины таксономии).
Одно из полей - это номер владения (участка/дома), номера выбираются из списка терминов таксономии.
2. На сайте есть форум (не Advanced), в нём создаётся нода (тема), к ней идут комментарии (посты).
Как и на любом форуме, каждая тема (автор ноды) и коммент (автор коммента) имеют определённый вид (стиль).
Например, как тут, где вы с вами общаемся сейчас.
У комментария выводится его автор, аватар, дата и тд.
3. У меня есть желание вывести в комментариях поля (пока речь об одном поле) из заполненного профиля.
Кое-что у меня уже получилось, но либо поле в друпаловской обёртке, либо чистое значение, но только у автора ноды (темы).
На картинках ниже автор темы Екатерина. А комментатор Л.С..
У автора темы выглядит так:
У других комментаторов так:
Как выглядит, если выводить данные из массива со всей друпаловской неотключаемой обёрткой:
Мне нужно, чтобы значение поля выводилось у всех комментаторов (как на скринах выше) но в таком виде как на скринах ниже
В вашем примере у меня поле выводится только у первого комментария, где его автор является автором ноды (темы).
Я подозреваю, что проблема тут
<?php$profile = profile2_load_by_user($comment->uid) ;?>
Эта схема работает при выводе массива print render(field_view_field, а вот просто вывод поля
<?php$profile = profile2_load_by_user($comment->uid) ;
print $profile['main']->field_numofholding['und'][0]['taxonomy_term']->name;?>
в этом случае не работает для всех комментаторов
Я почитал доки, попробовал разные способы, сработали только два.
Первый с обёрткой:
<?php
$options = array(
'type' => 'taxonomy_term_reference_plain',
'label' => 'hidden',
);
$profile = profile2_load_by_user($comment->uid) ;
print
render(field_view_field( 'profile2' , $profile [ 'main' ] , 'field_name', $options )) ;?>
Второй чистый, но только если комментатор является автором ноды:
<?php$profile = profile2_load_by_user($comment->uid) ;
print $profile['main']->field_numofholding['und'][0]['taxonomy_term']->name;?>
Так ведь смотрите в чем беда, вы ведь получаете из профиля идентификатор именно автора ноды $comment->uid
А вам нужно взять идентификатор каждого пользователя в каждом комментарии! Для этого нужно более внимательно посмотреть структуру массива в dpm. Если у вас выводится десять комментариев, то в массиве должно быть десять ключей со своими массивами. И в каждом есть информация о пользователе и его uid. Вы можете прогнать циклом эти значения и добавить к каждому, например, префикс с данными (как один из вариантов). Например, как-то так (это только общая идея):
foreach ($content['data_about_user'][LANGUAGE_NONE] as $key => $value) {
$profile = profile2_load_by_user($value->uid); // Если данные - это объект или $value['uid'], если массив
$content['data_about_user'][LANGUAGE_NONE][$key]['#prefix'] = $profile['main']->field_numofholding[LANGUAGE_NONE][0]['taxonomy_term']->name;
}
И это все. Пусть работает стандартный рендер. Это просто показательный пример, как идея построения алгоритма. У вас нужно смотреть, как данные сформированы. Но суть вы, думаю, уловили.
Только что глянул шаблон анвансед форума, понятно что у вас другой, но все же. Так вот данные не вываливаются полностью в шаблон, а страница собирается на лету, дергая все время шаблон. То есть всего массива с данными там нет. А значит нужно найти переменную в которую передается информация о комментаторе. Как правило, переменные описываются в начале шаблона в комментарии. В адвансед форуме это $account. Из нее вытаскиваем ид юзверя: $account->uid А дальше вы уже получаете нужное вам поле и записываете его префикс или еще как.
Я заметил такую закономерность.
Вот такой код работает
<?php$options = array(
'type' => 'taxonomy_term_reference_plain',
'label' => 'hidden',
);
$profile = profile2_load_by_user($comment->uid) ;
print render(field_view_field( 'profile2' , $profile [ 'main' ] , 'field_numofholding', $options )) ;
print $profile['main']->field_numofholding['und'][0]['taxonomy_term']->name;?>
Но выглядит так:
Комментатор (автор ноды:
Комментатор (не автор ноды):
Из чего я делаю вывод: чтобы вывести значение поля print $profile['main']->field_numofholding['und'][0]['taxonomy_term']->name; , нужно сначала вывести массив: print render(field_view_field( 'profile2' , $profile [ 'main' ] , 'field_numofholding', $options )) ;
И ещё я забыл добавить, что у меня в шаблоне node.tpl тоже используется вывод (но подставляется id ноды:
<?php
$options = array(
'type' => 'taxonomy_term_reference_plain',
'label' => 'hidden',
);
$profile = profile2_load_by_user($node->uid) ;
print render(field_view_field( 'profile2' , $profile [ 'main' ] , 'field_numofholding', $options )) ;
?>
Шаблон ноды загружается первым, и без этого рендера не работает вывод в шаблоне коммента.
Короче, я ещё покопаю в эту сторону. Я в php чайник, но мне кажется, что так можно заставить работать, если скрыть отображение поля из массива в обёртке (но всё же программно выводить). Пока не знаю как, но где-то видел пример кода, как части вывода контента в шаблоне сначала скрываются hide render..., а потом выводятся.
Может быть быть, вы увидите какую-то логику и подскажете, как чего, а я вечером приеду и попытаю счастье ):
Вы сделали так: print render(field_view_field( 'profile2' , $profile [ 'main' ] , 'field_numofholding', $options )) ; У вас ничего не вывело! Пустое значение. Это грубо говоря, первая строка. Для проверки засуньте функцию в девел: dpm(field_view_field(...));
Потом вы сделали вывод термина таксономии: print $profile['main']->field_numofholding['und'][0]['taxonomy_term']->name; Это у вас вывело имя термина, строка номер два.
А в строке номер три у вас отработал рендер всего массива, в котором есть ваше термин таксономии, и который вывелся на страницу при рендере.
Если в программировании вы не разбираетесь, то тут на пальцах не объяснить. А зачем вы вообще модуль профиля используете, если этот функционал уже встроен в ядро семерки? Все это можно сделать в настройках пользователя! И работать с профилем, как белый человек: user_load(), user_view().
Кирилл, спасибо вам за ответы. В любом случае, для развития мне всё это интересно.
Скажу честно, учебник по PHP я весь прочитал лет 8 назад, но без практики программирования даже поверхностное понимание вопроса слабое.
Но при этом на уровне шаблона вроде примерно понятно, как в html разметке работают php вставки.
То что вы пишете, я понимаю, что вывод поля дважды происходит. Но, возможно, меня оно бы устроило, если можно убрать (скрыть) ту строку, где поле выводится в обёртке,
но почему вы пишете, что строка print render(field_view_field( 'profile2' , $profile [ 'main' ] , 'field_numofholding', $options )) ; не выводит поле? Вроде как раз эта строка и выводит номер участка в обёртке, а эта print $profile['main']->field_numofholding['und'][0]['taxonomy_term']->name; выводит сырое значение
Короче, я уже подумываю, а не отказаться бы мне от этой затеи вообще, раз не получается Друпал - штука крутая, но такие простые вещи должны решаться простыми моделями или в ядре, через админку, я считаю.
Конечно, я рассматривал возможность использовать настройки пользователя, но для решения моей задачи это почему-то не подошло, уже и не помню почему, в 2011 году я этим занялся (некоммерческий проект), с вордпрессом мне проще немного на личном сайте.
Тут все это разжевано http://habrahabr.ru/post/163501/
Спасибо! Эта статья растиражирована на всех сайтах Её я изучал в первую очередь.
Хотя в итоге мне помог какой-то другой обзор.
В моём случае, не получилось, так как в примере идёт пример с полями ноды, а с полями профиля фокус не проходит, я пробовал разные конструкции
Эти функции как раз универсальны, они предназначены для работы с полями любых сущностей:
http://coder1.com/articles/printing-or-rendering-node-field-or-profile2-...
Вот именно так я и сделал + настроил в options cокрытие label, как убрать обёртку так и не понял.
Переопределить вывод поля - это значит, что оно везде будет без обёртки, а мне нужно только в одном месте в собственной обёртке css, или вообще в виде просто значения. А получается, что это можно сделать таким способом, каким лучше не делать (как привели в пример выше)
Получить значение поля можно https://api.drupal.org/api/drupal/modules!field!field.module/function/fi...
Прочитайте ее сами еще раз, вместе со всеми комментариями!
Для вывода полей (при необходимости это сделать за пределами шаблона ноды) я использую field_get_items(), field_view_field(), field_view_value(). Есть неплохой вариант с использованием Entity API - http://xandeadx.ru/blog/drupal/549. Что конкретно вы хотите чтобы я еще раз прочитал? Что LANGUAGE_NONE = 'und'? Так это для меня не новость.
Я хочу сказать, что использование функций ядра для получения каких либо данных, или еще чего-то в ШАБЛОНЕ - ЭТО ЗЛО!!!!!!!!! Черное и гадкое! И это можно называть правильным друпал путем или еще как-то, но все телодвижения с ядром, должны оставаться в контроллере, в нашем конкретном случае, в модуле, отправляющем данные в шаблон. Шаблон - это оперирование с финальными данными. Одевание во враперы, прикрепление классов и т.п. Поэтому, все функции field_get_items(), field_view_field(), field_view_value() и др. которые используются именно в шаблоне - это костыль, а не правильное использование Друпал. Вы только вдумайтесь, вы получаете в шаблон готовый объект ноды, которая уже содержит все необходимые вам поля! Но что вы делаете? Вы опять дергаете ядро, и отсылаете на сервер опять объект ноды! И только для того, чтобы ядро вам выгрызло из ноды одно единственное поле, очищенное от мусора. ЭТО ЖЕ МАРАЗМ самого понятия разработки!!! Вот что нужно понять. Мне не хочется, что бы в среде разработки на Друпал, появлялись друпало-дрочеры, как это произошло с аппл гаджетами.
Хороший разработчик, это не тот, кто делает все то, что ему написали в документации, под красивым соусом стили жизни. А тот, кто умеет пользоваться своими мозгами и находит реально узкие места в системе! А половина всего Друпал АПИ состоит из пары строчек пхп кода. При этом каждый раз загружается бутстрап. И зачем?
«отсылаете на сервер опять объект ноды» - тут вы превзошли сами себя:) По делу: ваш способ можно использовать для простых текстовых или числовых полей, но при этом нужно проверять существование поля, чтобы избежать ошибок, а также учитывать возможную локализацию. А что если у вас в поле, например, entity reference, field collection или views или хотя бы картинка, при этом способ отображения любого из этих типов поля задается в админке?
«отсылаете на сервер опять объект ноды» - к словам цепляетесь, суть вы уловили.
В энтити риференс вам будет сразу доступен объект ноды(StdClass), если не в курсе (или по вашему что произойдет при рендере?)! Проверять поле нужно, это факт. Но разве для вас if else - это проблема? С вьсом вообще никаких проблем, работать просто красота! Выводите данные в шаблон таблицы! И получаете сырой массив данных $rows. Делайте с ним, что хотите. Учитывать локализацию, это вы о чем? Вместо und, eng или ru? Это проблема? Сдвигать массивы умеете?
И вы думаете, что рендерить можно только контент целиком? Типа print render($content)? А про hide($content['field_image']); не слыхали? А про print render($content['field_image'][0]); ?
Давайте прекратим этот спор, ок? На этом сайте есть в доступе достаточно моих модулей, чтобы вы поняли, что говорите не с хвастливым задротом. С удовольствием бы ваши модули взглянул.
«В энтити риференс вам будет сразу доступен объект ноды(StdClass), если не в курсе (или по вашему что произойдет при рендере?)! Проверять поле нужно, это факт. Но разве для вас if else - это проблема? С вьсом вообще никаких проблем, работать просто красота! Выводите данные в шаблон таблицы! И получаете сырой массив данных $rows. Делайте с ним, что хотите. Учитывать локализацию, это вы о чем? Вместо und, eng или ru? Это проблема? Сдвигать массивы умеете?» - я говорил о выводе сложных типов полей с настройками, задаваемыми в админке, а не хардкодно. Еще пример - поле типа Link.
«И вы думаете, что рендерить можно только контент целиком? Типа print render($content)? А про hide($content['field_image']); не слыхали? А про print render($content['field_image'][0]); ?» - слыхал, слыхал. И использовал даже. В node.tpl.php. Но не в page.tpl.php или в других местах.
Да, давайте, не спорить. Разработкой модулей я особо не занимаюсь. Те, что есть, никуда не выкладывал, они делались под конкретные разовые задачи.
В итоге решил темизировать поле через шаблон field--field-name.tpl.php
Жаль, что не разобрался с выводом значения поля так, как было удобно, не переопределяя вид самого поля, а просто тупо вывести значение в любом месте.
Но главное, что получил желаемое.
Если вдруг кому будет интересна эта тема, буду рад более свежим или верным решениям.
Всех с Новым Годом!
Правильный вывод поля такой:
<?php$options = array(
'type' => 'taxonomy_term_reference_plain',
'label' => 'hidden',
);
$profile = profile2_load_by_user($node->uid) ;
$numofholding = field_view_field( 'profile2' , $profile [ 'main' ] , 'field_numofholding', $options ) ;
print render($numofholding);?>
Ну и + темизация поля, как я писал выше.
Но тут появилась другая проблема
Это поле профиля есть только у определённого типа профиля ( main), тип профиля соответствует своей роли.
Если на форуме создаёт или комментирует тему пользователь другой роли, то вылазит ошибка:
EntityMalformedException: Отсутствует связующее свойство у сущности типа profile2. в функции entity_extract_ids() (строка 7879 в файле .../includes/common.inc).
На сайте произошла непредвиденная ошибка. Пожалуйста, повторите попытку позже.
Как можно сделать условия, чтобы поле выводилось только у пользователя одной роли?
Что-то типа
if (
isset($GLOBALS['user']->roles[1])
Нужно определить именно роль того, кто постит ноду, а не роль посетителя страницы.. Никак не пойму как сюда это приписать:
<?php
$options = array(
'type' => 'taxonomy_term_reference_plain',
'label' => 'hidden',
);
$profile = profile2_load_by_user($node->uid) ;
$numofholding = field_view_field( 'profile2' , $profile [ 'main' ] , 'field_numofholding', $options ) ;
print render($numofholding);?>
Други, выручите, спасите-помогите, не справляюсь я
Попробовал через настройку темизации поля
<?php if (!$label_hidden): ?>
<div class="divvv"><?php print $label ?>: </div>
<?php endif; ?>
<?php foreach ($items as $delta => $item): ?><i class="fa fa-home"></i>
<?php if (isset($account->roles[4])):?>
<?php print render($item); ?>
<?php endif; ?>
<?php endforeach; ?>
не работает
Как же сделать вывод поля при условии, что это необходимо выводить его у одной роли (типа профиля).
У меня роль №4, ей соответствует тип профиля main.
Вот тут у человека как-то получилось, у меня не выходит
http://www.drupal.ru/comment/500600#comment-500600