Как взять значения из активных фасетных фильтров (term id) на странице и передать их в contextual filter другого блока?

17 апреля 2015 в 15:55
Аватар пользователя alex_t alex_t 0 14

Всем добрый день.
Бьюсь над проблемой не первую неделю - попробовал множество вариантов - правильно работающее решение не нашел. Нужна помощь.

пост удален

Комментарии

Нужно сделать CONTEXTUAL FILTERS
Indexed Node: Author
Путь примерно такой: /user/%/myannouncements
Также установить RELATIONSHIPS
Indexed Node: Author

Материал должен быть проиндексирован. Теперь по ссылке, где % - это uid пользователя будут доступны только те ноды, которые принадлежат данному пользователю из контекстного фильтра. А фильтры будут работать при любом раскладе.

В настройках самих фасетных фильтров (facet display) по умолчанию настроено показывать только те термины таксономии, которые принадлежат созданным нодам. Можно подобный пункт еще в настройках словаря глянуть.

17 апреля 2015 в 20:01

Дело в том, что если вы используете Entity Reference, связывая пользователя с нодой и при этом вам нужно еще иметь связь по таксономии, то вы не можете использовать два словаря таксономии и для пользователя и для ноды!!! У вас просто не будет пересечения по таксономии, так как пользователь и ноды используют свои независимые словари таксономии, которые ничего не знают друг о друге (ну во всяком случае без танцев с бубном).

Например, есть user 1, к которому нужно привязать все ноды с термином NEC (у пользователя словарь терминов). И есть ноды, которые относятся к NEC, допустим их пять (а тут словаря нет). Так вот, к этому пользователю нужно прикрепить связь на все пять этих нод. Или наоборот. Использовать ноды, как основные и там же словарь. А уже к нодам прикреплять пользователей. Тогда у вас сохраняется логическая связь.

Либо индексировать только ноды или пользователя. Выводить что есть в шаблон. В шаблоне получить, например, идентификаторы терминов, а по ним уже подтянуть ноды или пользователей (в зависимости от того, у кого словарь прикреплен).

А еще, я более чем уверен, что у вас не продумана архитектура. Вы скорее всего сели сразу разрабатывать, но не продумали все до мелочей.

На самом деле решений поставленной задачи много. И первое, что нужно сделать, это продумать, как это сделать красиво. А уже потом писать код.

П.С. Кстати, можно вообще не использовать Entity Reference. Если у вас свой словарь таксономии и в нодах и в пользователях, то можно делать связь через термины таксономии. А еще можно вообще не использовать фасетные фильтры, а пользоваться меню таксономии. Сделать вьюху для таксономии и выводить ее через модуль taxonomy display.

17 апреля 2015 в 23:50

kirill_dan спасибо за оперативные ответы!

задача конечно не тривиальная..
все связи есть (и словарь один для пользователей и для нод, и ноды связаны с пользователем)
архитектура продумана (как должно быть) и механизмы drupal/модули тоже подобраны - просто периодически упираюсь в drupal в проблемы связок одних модулей с другими.. или в отсутствие простых возможностей которые по идее должны быть штатными - приходится придумывать велосипед... ну да не суть...

нашел некое подобие решение Search API Combined Fields - получилось объединить два фильтра (по двум полям и от профилей и от нод по единому индексу) в один - все бы ничего, только модуль оказался глючным и кроме двух выбранных полей всасывает в себя лишние поля, и конечно не считает ноды...как всегда баги drupal

задачу временно решил через вывод двух фильтров - один для профилей - другой для нод, криво конечно (дубли фильтров), но до лучших времен буду использовать "времянку"...жаль (просто неужели нельзя как-то выцепить значения активных фасетных фильтров - получить tid и передать список tid в блок/ или тупо сделать sql запрос к базе на основе tid)

18 апреля 2015 в 0:09

alex_t wrote:
kirill_dan спасибо за оперативные ответы!

задача конечно не тривиальная..
все связи есть (и словарь один для пользователей и для нод, и ноды связаны с пользователем)
архитектура продумана (как должно быть) и механизмы drupal/модули тоже подобраны - просто периодически упираюсь в drupal в проблемы связок одних модулей с другими.. или в отсутствие простых возможностей которые по идее должны быть штатными - приходится придумывать велосипед... ну да не суть...

нашел некое подобие решение Search API Combined Fields - получилось объединить два фильтра (по двум полям и от профилей и от нод по единому индексу) в один - все бы ничего, только модуль оказался глючным и кроме двух выбранных полей всасывает в себя лишние поля, и конечно не считает ноды...как всегда баги drupal

задачу временно решил через вывод двух фильтров - один для профилей - другой для нод, криво конечно (дубли фильтров), но до лучших времен буду использовать "времянку"...жаль (просто неужели нельзя как-то выцепить значения активных фасетных фильтров - получить tid и передать список tid в блок/ или тупо сделать sql запрос к базе на основе tid)

Вы цепляете фильтр (один), по нему получаете в шаблон ноды. В ноде вы можете получить из массива все tid. Имея эти значения можете получить из базы всех пользователей, у которых есть такие же значения. Для того, чтобы получить в шаблоне красивый массив, нужно во вьюсах сохранять данные в виде таблицы. Таким образом вы получите переменную $rows, которую вам нужно прогнать через цикл foreach.

Иногда написать свою функцию проще и быстрее, чем воротить огород с кучи модулей. У меня на последнем проекте половина модулей вообще написана мной под мои конкретные задачи. Иначе будут вечные глюки и тормоза.

Но если бы вы мне объяснили общую идею вашей задумки, что и зачем, не вдаваясь в то, как вы это решаете или хотите решать, то это было бы лучше. Тем более, что моя основная специализация - это именно разработка архитектуры.

П.С. "и словарь один для пользователей и для нод, и ноды связаны с пользователем" Я вам уже говорил, что связь делается либо через таксономию (и у нод и у пользователей есть ссылка не термин одного словаря), либо через связывание с сущностью (но тогда ссылка на термин должна быть у кого-то одного). Это важно! Вы ведь делаете сейчас двойную связь! Если вы связали ноду и пользователя через термины таксономии одного словаря, зачем тогда еще связывать ноду с пользователем через Entity Reference? Простым языком это выглядит так. Есть машины и авто любители. Есть словарь таксономии Марки автомобилей. В ноде про характеристики авто вы указали термин на марку БМВ. А в профиле пользователя в поле его любимые машины, тоже выбрали БМВ. Теперь и пользователь и характеристики авто связаны общим термином БМВ. Зная термин можно теперь найти и характеристики и пользователя, которые принадлежат к этому термину! Зачем еще что-то лепить?

18 апреля 2015 в 1:20

Смысл ясен. Чего-либо сложного или нестандартного я не услышал. Все можно решить (большинство во всяком случае) просто через вьюсы. Момент номер один. В вашей конкретной задаче Entity reference нужно удалить и забыть вообще о его существовании. Поясню на примере. К примеру у вас есть нода - некая недвижимость. С сайта некий пользователь хочет сделать пред заказ на просмотр этой недвижимости на какое-то число. Сам заказ - это тоже нода. Которая содержит только дату просмотра и краткий комментарий. Единственный вариант связать этот заказ с этой нодой - это Entity reference. Так как нет никаких терминов таксономии, да вообще ничего нет! Это единственный случай когда можно связать несвязуемое! В вашем случае все вертится вокруг одного словаря таксономии. Этого вполне достаточно (смотрите базовый курс о реляционных базах данных). Это ваша первая ошибка.

Следующая ошибка. Это попытка применения фасетных фильтров. Этот тип поиска - это вообще отдельная тема для разговора. Это не просто поиск - это целое АПИ, которое работает в связке с Search API. Эти модули должны по уму работать с сервером Apache Solr, для которого нужно на сервере устанавливать Java. А сделано это все для того, чтобы можно было проиндексировать некоторые поля в нодах, для которых нужно организовать быстрый поиск по критерию. Настроенные поля индексируются и данные заносятся в базу данных поискового сервера. Это в свою очередь дает возможность производить очень быстрый поиск из поискового сервера по индексам, снижая тем самым нагрузку на память и процессор. А фасетные фильтры используются именно для удобства организации поиска по индексам! А вы же пытаетесь их приплести к логике работы ваших скриптов! Но они этого не умеют, и не должны уметь. У них совершенно другая задача.

Следующий момент. Это рейтинг о котором вы пишите. Тут уже нужно самому думать, как организовать рейтинг. Значение это может быть не линейным и каждый сам должен придумать логику. Пример. Есть два разработчика на сайте со своими профилями. У одного выполнено 30 работ. Установка модулей, правка шаблона и другие мелочи. А у второго разработчика выполнена только одна работы - разработка системы онлайн обучения на 800 часов. У кого рейтинг на сайте должен быть выше по вашему? Грубо говоря, ламер с кучей халтурок и профи с огромнейшим и сложнейшим проектом. Люди будут искать того, у кого рейтинг больше (вроде сделал много работ и люди были им довольны) и будут находить не профессионала, а этого ламера. Хотя цена работы у них может быть одинакова. Надеюсь, смысл проблемы вы поняли.
Если организовать рейтинг через голосования, то можно просто поставить модуль Vote API и установить на него, к примеру - Five stars. И не морочить себе голову. Но такие "рейтинги" годятся к фильмам. Людей и их возможности оценить алгоритмом не реально. И кто судить-то будет? Заказчики, которые во всем этом полные нубы?

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

Опять вышло много букв Smile

18 апреля 2015 в 20:11

Заходите в настройки вашего словаря таксономии и отмечаете пункт Hide empty terms. Что означает скрывать пустые термины. И вуаля. Те термины, которые не назначены не одной ноде больше не будут отображаться. Выводить в блок можно термины модулем Taxonomy menu. Хотите использовать индексацию и фасетные фильтры, значит архитектуру нужно продумать таким образом, чтобы не было головняка с кучей взаимосвязей. Или выводить ноды только одного типа во вьюсы. Так как индексированные поля ничего не знают о других полях. Такова логика работы. Иначе, либо кода тонны писать, либо потеряться и зачахнуть. Если не используете отдельный сервер индексации, а все пишется в ту же друпаловскую базу, то это прямой путь не к облегчению поиска, а к великому геморрою. Вот почти завершенный проект с фасетными фильтрами на друпале http://best-house.org/en/daily_rent
На него уже потрачено более 500 часов самописного кода. Допустим, когда вы выделяете фильтр в фасетах, то отменить действие можно только сняв чекбокс с того же фильтра. Очень не удобно. Пришлось самому написать функцию, которая в блоке выводит выбранные фильтры с возможностью их отмены. Звучит, как мелочь. А кода написано ого-го. И такого добра от мелочи до огромного функционала вагон и маленькая тележка.

18 апреля 2015 в 21:39

"alex_t" wrote:
но и вокруг связей словарей и нод и юзеров.. и в сцепках как раз проблема)

Надо писать код. Нельзя решить задачу без кода. По моей аналогии это бы выглядело так. Слева поиск недвижимости по критерию. Справа ноды. А еще у хозяина этой недвижимости есть пять квартир, которые он тоже сдает. И есть в профиле у него, допустим разные специализации с которыми он работает. Как все вывести сразу в нодах? Делаем вьюху из индексов. Создаем табличный шаблон. Шаблон создаем в теме и кидаем в папку вьюс. Теперь в шаблон будет попадать массив с данными каждой ноды. Из массива могу поличить уид автора, а значит я могу с помощью lode_user($uid) подтянуть весь его профиль. Также я могу подтянуть все ноды нужного типа, которые принадлежат этому пользователю прямо из базы. Грубо говоря, я подтянул в одномерном массиве пять нидов его недвижимости. И могу сразу посчитать количество: $amount = count(массив с нидами);.

Далее прямо в шаблоне делаю: print "<див>У пользователя $переменная с именем юзверя есть еще $amount-1 квартир<закрыли див>";

Это очень грубо! Всего пару строчек кода!

19 апреля 2015 в 13:18

kirill_dan - вернулись к началу Smile без когда никуда.... ну что ж сначала доработаю структуру - потом, судя по всему, опять придется куски кода писать - жаль.

19 апреля 2015 в 16:49

alex_t wrote:
kirill_dan - вернулись к началу Smile без когда никуда.... ну что ж сначала доработаю структуру - потом, судя по всему, опять придется куски кода писать - жаль.

Давай на ты перейдем. А расскажи мне о своей идее стартапа, можно в личку. Может сможем чем-то друг другу помочь. Ну уж мне так точно есть чем тебе помочь Wink Если проект интересный, то смогу тебе помочь за помочь в чем-то мне с моими проектами. Если интересно, то пиши. Один в поле не воин, особенно с твоим знанием Друпала.

20 апреля 2015 в 0:56