Вывод значения из поля профиля без обёртки дивами

Аватар пользователя Радосвет Радосвет 15 декабря 2015 в 9:39

Дорогие друпаловоды, столкнулся с проблемой, никак не найду решение Sad

Вывожу в ноде поля из профиля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')?>
не работает Sad

Выводится и заголовок, и ссылка на термин.
Если ссылка меня устраивает, то заголовок никак не вписывается в node.tpl и дизайн.

Гуглёж не помог, может кто подскажет кусочек кода или куда смотреть?

UPD: вопрос с со скрытием заголовка решил (ниже написано), остался вопрос с обёрткой... Sad

Комментарии

Аватар пользователя Радосвет Радосвет 22 декабря 2015 в 1:44

Вопрос решил с помощью вот такой конструкции:

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

Одна проблема, значение поле выводится в обёртке Sad Куча дивов ненужных..
Подскажите, пожалуйста, как исправить? Конкретно в моём случае, с print render...

Причём мне нужно именно это поле вывести в одном месте как значение, глобально вывод поля менять не нужно, так как оно выводится также и в других местах как надо...
Куда копать?
Спасибо всем, кто не прошёл мимо!

Аватар пользователя kirill_dan kirill_dan 22 декабря 2015 в 14:06

Установи Devel модуль на сайте. В шаблоне вывали свои данные в девел: dpm($profile); Найди в массиве нужное тебе поле и выведи его значение напрямую! Например, так: print $profile['field_name'][LANGUAGE_NONE][0]['value']; Это как пример, у тебя там будет что-то другое. LANGUAGE_NONE - это und (языковая принадлежность).

Аватар пользователя sergeybelya sergeybelya 22 декабря 2015 в 14:19

Такой вывод поля является дурным тоном:) Особенно для проектов с entity translation
Автору - либо используйте https://api.drupal.org/api/drupal/modules!field!field.module/function/fi..., либо просто переопределите шаблон поля, удалив из него лишние обертки, и тогда ваш метод тоже будет рабочим.

Аватар пользователя Радосвет Радосвет 22 декабря 2015 в 14:39

Вот я тоже смотрел на эту функцию, но как её использовать совместно с моим рабочим вариантом так и не понял Sad
Просто заменить вот это
<?phpprint render(field_view_field( 'profile2' , $profile [ 'main' ] , 'field_name', $options )) ;?>

на это
<?phpprint render(field_view_field( 'profile2' , $profile [ 'main' ] , 'field_name', $options )) ;?>
не получится Sad Или я не понял, как определить эту функцию в templait.php

Аватар пользователя kirill_dan kirill_dan 22 декабря 2015 в 16:28

Ну во первых LANGUAGE_NONE, как раз и не зависит от языка, в этом его фишка. А во вторых, сам вывод кучи мусора в шаблон - это бич Друпал! Само понятие шаблона отсутствует напрочь. Так как вам в шаблон вываливает кучу markup мусора. И вместо того, чтобы в шаблоне делать именно то, для чего он предназначен, а именно темизировать сырые данные, приходиться заниматься извращениями на подобии очистки от лишних враперов, классов и другой пурги, применяя при этом кучу функций ядра и нагружая сервер. И ради чего? Ради очистки от врапера? Не находите этот друпал вэй бредовым? Это кстати один из моментом, за что я ненавижу Друпал (не смотря на любовь к нему).

Аватар пользователя kirill_dan kirill_dan 22 декабря 2015 в 16:41

А тут уже все зависит от того, как именно вы будете организовывать систему переводов. Я чаще всего делаю, как локализацию. Вон http://best-house.org двух язычный. Все пашет без проблем. Правда перевод только интерфейса, без контента. Но так ведь и при получение значения поля через функции ядра, вам тоже нужно передать $language->language Smile Если вы используете не локализацию, а перевод!

Ах да. Я еще использую по умолчанию язык нейтральный (und)!

Аватар пользователя sergeybelya sergeybelya 22 декабря 2015 в 16:43

Вы явно не разбираетесь в том что пишите, извините, но подучите документацию, что ли.

Аватар пользователя kirill_dan kirill_dan 22 декабря 2015 в 17:01

Не нужно извинятся. Может я и не прав. Тогда ткните носом, буду благодарен. А ваш ответ смахивает на: ты неправ, вали отсюда, кури доки, учи матчасть. Хамство за вежливым ответом не спрятать.

Аватар пользователя sergeybelya sergeybelya 22 декабря 2015 в 17:03

Вообще я не хамил, ссылки на доки приводил, хотя хамство на этом форуме - обычное дело:)

Аватар пользователя kirill_dan kirill_dan 22 декабря 2015 в 17:14

«А тут уже все зависит от того, как именно вы будете организовывать систему переводов. Я чаще всего делаю, как локализацию. Вон http://best-house.org двух язычный. Все пашет без проблем. Правда перевод только интерфейса, без контента. Но так ведь и при получение значения поля через функции ядра, вам тоже нужно передать $language->language Smile Если вы используете не локализацию, а перевод!

Ах да. Я еще использую по умолчанию язык нейтральный (und)!»

Где бред тут? Конкретно по сути?!

Аватар пользователя Радосвет Радосвет 22 декабря 2015 в 20:06

Спасибо. Вот такие вывел devel:

массив

Вот как мне прописать функцию и распечатать?
Так? print $profile['field_numofholding'][LANGUAGE_NONE][0]['taxonomy_term'];

Аватар пользователя kirill_dan kirill_dan 22 декабря 2015 в 21:10

Радосвет wrote:

Вот как мне прописать функцию и распечатать?
Так? print $profile['field_numofholding'][LANGUAGE_NONE][0]['taxonomy_term'];

Смотря, что тебе нужно вывести. Если полностью сущность поля, то:
print render($profile['field_numofholding']);
Если имя термина, то путь к имени термина без рендера.

Кликаешь дважды на поле и тебе открывается путь к нему: $...массив. Вместо $... ставишь название своей переменной, например $profile.

Аватар пользователя Радосвет Радосвет 22 декабря 2015 в 22:08

Спасибо! Кое-что получилось Smile
Код такой:

uid) ; 
print $profile['main']->field_numofholding['und'][0]['taxonomy_term']->name;?>

Но дело в том, что поле выводится только у автора ноды (в двух словах, есть форум, есть комменты, в tpl комментария я вставляю выше написанный код, чтобы отобразить определённое поле в каждом комментарии, относящееся к профилю автора комментария).

У автора темы выглядит так:
автор
У других комментаторов так:
коммент

Как выглядит, если выводить данные из массива со всей друпаловской неотключаемой обёрткой:
автор

коммент

Я где-то ошибся в функции?

Аватар пользователя kirill_dan kirill_dan 22 декабря 2015 в 22:49

Если вы потом рендерите весь контент, то вы опять выводите те поля, которые уже вывели. К примеру получаем название:
$name = $profile['main']->field_numofholding['und'][0]['taxonomy_term']->name;

print $name; - вывели где надо вам это значение. И если вам данные этого поля больше не нужны и вы не хотите их выводить, то удалите их:
unset($profile['main']->field_numofholding); - это вы полностью грохнули поле из массива

Аватар пользователя Радосвет Радосвет 22 декабря 2015 в 23:04

Грохнуть не есть хорошо, комментаторы повторяются же в теме Smile
В вашем примере у меня поле выводится только у первого комментария, где его автор является автором ноды (темы).
Я подозреваю, что проблема тут
$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;?>
в этом случае не работает для всех комментаторов Sad

Аватар пользователя kirill_dan kirill_dan 22 декабря 2015 в 23:49

Мы сейчас обсуждаем не совсем понятно что. Какой шаблон, комментариев? Какая задача стоит, четко только и понятно. Может вообще все по другому можно сделать или должно быть.

Аватар пользователя Радосвет Радосвет 23 декабря 2015 в 0:37

Кирилл, да вроде задачу озвучил, но попробую ещё раз. Smile

1. Есть сайт, на нём пользователи с ролями. Также через модуль Profile2 заполняются поля.
Часть полей заполняет пользователь сам (номер телефона, город и тд), часть полей выбираются из списков (термины таксономии).
Одно из полей - это номер владения (участка/дома), номера выбираются из списка терминов таксономии.

2. На сайте есть форум (не Advanced), в нём создаётся нода (тема), к ней идут комментарии (посты).
Как и на любом форуме, каждая тема (автор ноды) и коммент (автор коммента) имеют определённый вид (стиль).
Например, как тут, где вы с вами общаемся сейчас.
У комментария выводится его автор, аватар, дата и тд.

3. У меня есть желание вывести в комментариях поля (пока речь об одном поле) из заполненного профиля.

Кое-что у меня уже получилось, но либо поле в друпаловской обёртке, либо чистое значение, но только у автора ноды (темы).

На картинках ниже автор темы Екатерина. А комментатор Л.С..

У автора темы выглядит так:
автор
У других комментаторов так:
коммент

Как выглядит, если выводить данные из массива со всей друпаловской неотключаемой обёрткой:
автор

коммент

Мне нужно, чтобы значение поля выводилось у всех комментаторов (как на скринах выше) но в таком виде как на скринах ниже Smile

В вашем примере у меня поле выводится только у первого комментария, где его автор является автором ноды (темы).
Я подозреваю, что проблема тут
uid) ;?>

Эта схема работает при выводе массива print render(field_view_field, а вот просто вывод поля

uid) ;
print $profile['main']->field_numofholding['und'][0]['taxonomy_term']->name;?>

в этом случае не работает для всех комментаторов Sad

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

Первый с обёрткой:

$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 )) ; 
?>

Второй чистый, но только если комментатор является автором ноды:

uid) ; 
print $profile['main']->field_numofholding['und'][0]['taxonomy_term']->name;?>
Аватар пользователя kirill_dan kirill_dan 23 декабря 2015 в 1:18

Так ведь смотрите в чем беда, вы ведь получаете из профиля идентификатор именно автора ноды $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;
}

И это все. Пусть работает стандартный рендер. Это просто показательный пример, как идея построения алгоритма. У вас нужно смотреть, как данные сформированы. Но суть вы, думаю, уловили.

Аватар пользователя kirill_dan kirill_dan 23 декабря 2015 в 1:49

Только что глянул шаблон анвансед форума, понятно что у вас другой, но все же. Так вот данные не вываливаются полностью в шаблон, а страница собирается на лету, дергая все время шаблон. То есть всего массива с данными там нет. А значит нужно найти переменную в которую передается информация о комментаторе. Как правило, переменные описываются в начале шаблона в комментарии. В адвансед форуме это $account. Из нее вытаскиваем ид юзверя: $account->uid А дальше вы уже получаете нужное вам поле и записываете его префикс или еще как.

Аватар пользователя Радосвет Радосвет 23 декабря 2015 в 6:21

Я заметил такую закономерность.

Вот такой код работает

  '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 ноды:

$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..., а потом выводятся.

Может быть быть, вы увидите какую-то логику и подскажете, как чего, а я вечером приеду и попытаю счастье ):

Аватар пользователя kirill_dan kirill_dan 23 декабря 2015 в 14:59

Вы сделали так: 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().

Аватар пользователя Радосвет Радосвет 23 декабря 2015 в 15:17

Кирилл, спасибо вам за ответы. В любом случае, для развития мне всё это интересно.
Скажу честно, учебник по 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; выводит сырое значение Smile

Короче, я уже подумываю, а не отказаться бы мне от этой затеи вообще, раз не получается Smile Друпал - штука крутая, но такие простые вещи должны решаться простыми моделями или в ядре, через админку, я считаю.

Конечно, я рассматривал возможность использовать настройки пользователя, но для решения моей задачи это почему-то не подошло, уже и не помню почему, в 2011 году я этим занялся (некоммерческий проект), с вордпрессом мне проще немного на личном сайте.

Аватар пользователя Радосвет Радосвет 22 декабря 2015 в 14:33

Спасибо! Эта статья растиражирована на всех сайтах Lol Её я изучал в первую очередь.
Хотя в итоге мне помог какой-то другой обзор.

В моём случае, не получилось, так как в примере идёт пример с полями ноды, а с полями профиля фокус не проходит, я пробовал разные конструкции Sad

Аватар пользователя Радосвет Радосвет 22 декабря 2015 в 14:43

Вот именно так я и сделал + настроил в options cокрытие label, как убрать обёртку так и не понял.
Переопределить вывод поля - это значит, что оно везде будет без обёртки, а мне нужно только в одном месте в собственной обёртке css, или вообще в виде просто значения. А получается, что это можно сделать таким способом, каким лучше не делать (как привели в пример выше) Sad

Аватар пользователя sergeybelya sergeybelya 22 декабря 2015 в 17:18

Для вывода полей (при необходимости это сделать за пределами шаблона ноды) я использую field_get_items(), field_view_field(), field_view_value(). Есть неплохой вариант с использованием Entity API - http://xandeadx.ru/blog/drupal/549. Что конкретно вы хотите чтобы я еще раз прочитал? Что LANGUAGE_NONE = 'und'? Так это для меня не новость.

Аватар пользователя kirill_dan kirill_dan 22 декабря 2015 в 17:40

Я хочу сказать, что использование функций ядра для получения каких либо данных, или еще чего-то в ШАБЛОНЕ - ЭТО ЗЛО!!!!!!!!! Черное и гадкое! И это можно называть правильным друпал путем или еще как-то, но все телодвижения с ядром, должны оставаться в контроллере, в нашем конкретном случае, в модуле, отправляющем данные в шаблон. Шаблон - это оперирование с финальными данными. Одевание во враперы, прикрепление классов и т.п. Поэтому, все функции field_get_items(), field_view_field(), field_view_value() и др. которые используются именно в шаблоне - это костыль, а не правильное использование Друпал. Вы только вдумайтесь, вы получаете в шаблон готовый объект ноды, которая уже содержит все необходимые вам поля! Но что вы делаете? Вы опять дергаете ядро, и отсылаете на сервер опять объект ноды! И только для того, чтобы ядро вам выгрызло из ноды одно единственное поле, очищенное от мусора. ЭТО ЖЕ МАРАЗМ самого понятия разработки!!! Вот что нужно понять. Мне не хочется, что бы в среде разработки на Друпал, появлялись друпало-дрочеры, как это произошло с аппл гаджетами.

Хороший разработчик, это не тот, кто делает все то, что ему написали в документации, под красивым соусом стили жизни. А тот, кто умеет пользоваться своими мозгами и находит реально узкие места в системе! А половина всего Друпал АПИ состоит из пары строчек пхп кода. При этом каждый раз загружается бутстрап. И зачем?

Аватар пользователя sergeybelya sergeybelya 22 декабря 2015 в 18:07

«отсылаете на сервер опять объект ноды» - тут вы превзошли сами себя:) По делу: ваш способ можно использовать для простых текстовых или числовых полей, но при этом нужно проверять существование поля, чтобы избежать ошибок, а также учитывать возможную локализацию. А что если у вас в поле, например, entity reference, field collection или views или хотя бы картинка, при этом способ отображения любого из этих типов поля задается в админке?

Аватар пользователя kirill_dan kirill_dan 22 декабря 2015 в 18:30

«отсылаете на сервер опять объект ноды» - к словам цепляетесь, суть вы уловили.
В энтити риференс вам будет сразу доступен объект ноды(StdClass), если не в курсе (или по вашему что произойдет при рендере?)! Проверять поле нужно, это факт. Но разве для вас if else - это проблема? С вьсом вообще никаких проблем, работать просто красота! Выводите данные в шаблон таблицы! И получаете сырой массив данных $rows. Делайте с ним, что хотите. Учитывать локализацию, это вы о чем? Вместо und, eng или ru? Это проблема? Сдвигать массивы умеете?

И вы думаете, что рендерить можно только контент целиком? Типа print render($content)? А про hide($content['field_image']); не слыхали? А про print render($content['field_image'][0]); ?

Давайте прекратим этот спор, ок? На этом сайте есть в доступе достаточно моих модулей, чтобы вы поняли, что говорите не с хвастливым задротом. С удовольствием бы ваши модули взглянул.

Аватар пользователя sergeybelya sergeybelya 22 декабря 2015 в 18:39

«В энтити риференс вам будет сразу доступен объект ноды(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 или в других местах.

Да, давайте, не спорить. Разработкой модулей я особо не занимаюсь. Те, что есть, никуда не выкладывал, они делались под конкретные разовые задачи.

Аватар пользователя Радосвет Радосвет 5 января 2016 в 1:03

В итоге решил темизировать поле через шаблон field--field-name.tpl.php
Жаль, что не разобрался с выводом значения поля так, как было удобно, не переопределяя вид самого поля, а просто тупо вывести значение в любом месте.
Но главное, что получил желаемое.

Если вдруг кому будет интересна эта тема, буду рад более свежим или верным решениям.

Всех с Новым Годом!

Аватар пользователя Радосвет Радосвет 17 января 2016 в 4:26

Правильный вывод поля такой:

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

Ну и + темизация поля, как я писал выше.

Аватар пользователя Радосвет Радосвет 17 января 2016 в 5:05

Но тут появилась другая проблема Sad
Это поле профиля есть только у определённого типа профиля ( 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);?>

Други, выручите, спасите-помогите, не справляюсь я Sad

Аватар пользователя Радосвет Радосвет 19 января 2016 в 10:20

Попробовал через настройку темизации поля

  <?php if (!$label_hidden): ?>
    <div class="divvv"><?php print $label ?>:&nbsp;</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; ?>

не работает Sad

Как же сделать вывод поля при условии, что это необходимо выводить его у одной роли (типа профиля).
У меня роль №4, ей соответствует тип профиля main.

Вот тут у человека как-то получилось, у меня не выходит Sad
http://www.drupal.ru/comment/500600#comment-500600