Как вывести views в Drupal 7 c переключателем отражения материала?

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

Аватар пользователя engenes engenes 30 ноября 2016 в 20:36

Давно мучает этот вопрос, есть представление например "каталог товаров", когда заходим на страницу */catalog, то материалы открываются списком.

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

Думаю, что можно подставить в адрес аргумент, например так: */catalog?big (чтобы views все-таки понимал, что нужно выводить, если мы перешли по прямой ссылке), то есть по умолчанию в представлении выбран формат: «таблица > поля», если нажали на соответствующий заначек, и адрес принял вид типа: */catalog?big, то представление должно выводиться в формате: «неформатированный список, готовая к выводу сущность».

Читал views API но пока безрезультатно, подскажите куда копать? Может быть есть hook, который распечатает код представления, внедрившись в который можно будет поменять формат в зависимости от условий?

Сейчас знаю способ только с помощью js и css, но это неправильно настраивать стили, если при изменении формата, мне нужно в корне перестроить html структуру отражения типа материала.

Лучший ответ

Комментарии

Аватар пользователя engenes engenes 30 ноября 2016 в 21:04

а если постраничный навигатор? а если ajax views? а если я переключился на n-ную страницу, а затем поменяю таб, то на какой странице окажусь? несколько представлений значит несколько раз один и тот же материал выведится на странице, это еще и увеличение времени загрузки страницы.
Просто но неуниверсальный способ, это костыль

Аватар пользователя VasyOK VasyOK 30 ноября 2016 в 21:20

Если отдельные дисплеи на каждый табик вешать - получаем несвязанность этих дисплеев. А если к ним фильтры подключены (сортировка по цене, выбор производителя)?
+ сеонисты будут трындеть, что на одной странице дублируется контент в HTML

Можно
1) Вывести фото товара, цену, описание.
2) Через JQuery сделать переключатель классов на области контента views.
3) один класс скрывает описание и устанавливает ширину ячейки 33% - типа вывод клетками по 3 шт в ряд.
другой класс показывает описание и устанавливает ширину ячейки 100% - типа вывод строками.

Аватар пользователя engenes engenes 30 ноября 2016 в 21:35

это можно)) то же самое в вопросе писал, но опять же костыль. Тем более,если по умолчанию выводится таблица, с шапкой да еще и с какой нибудь сортировкой по полям в шапке, а нам эту таблицу нужно будет перестроить в полноценные карточки товара, еще и адаптировать потом, да там голову сломать можно.. да и клавиатуру. Тут необходимость менять именно html структуру, да js и это может сделать, до первой перезагрузки через ajax и тут уже придется писать прилично кода для того чтобы после срабатывания ajax запроса у нас снова срабатывал скрипт, а это уже тонны ненужного кода, другое дело, решить вопрос еще на стороне сервера коротко и надежно. Попробую решить вопрос воспользовавшись материалами из источников в первом ответе.

Аватар пользователя dgastudio dgastudio 30 ноября 2016 в 21:35
2

2 кнопки, на них вешаете js (хотите через друпал ajax, хотите через jquery)

при клике, создаем куку + перезагружаем страницу

создаем views с нужными полям, смотрим файлы tpl.php. В них, пишем простейшую логику (if($_SESSION['display_type'] == 'grid'))...

Аватар пользователя engenes engenes 8 декабря 2016 в 9:39

Написал условие в модуле, все работает отлично, $_COOKIE принимает мою куку но после ухода на другую страницу кука куда-то пропадает, то есть она работает локально только внутри одной страницы, при чем если понажимать на всех страницах, то для каждой страницы запомнится своя кука.
Не подскажите как сделать чтобы браузер запомнил ее как то абсолютно для всего сайта.
1. мой html
1
-------
-
2. мой js
2
-------
-
3. тут распечатал в консоли мои куки после того как нажал на элементы из 1 рисунка.
3
-------
-
4 моя консоль после того как я ушел на другую страницу. При том если вернусь обратно, все снова работает.
4

Аватар пользователя postgres postgres 1 декабря 2016 в 10:43

Коллеги, кхм-кхм

Вопросы css должны решаться только средствами css, а смена класса - $('.my-view-item').addClass('tail').removeClass('list');

Что касается дополнительных дисплеев - не издевайтесь над Яндексом и Гуглом, не плодите дубли страниц

Аватар пользователя dgastudio dgastudio 1 декабря 2016 в 11:08

возможно, но, если верстка и кол-во элементов кардинально отличается между видами, проще сделать их на уровне кода а не на уровне стилей

при подходе с темизацией, гуглу всегда будет скармливаться первый дисплей, в чем проблема?

Аватар пользователя postgres postgres 1 декабря 2016 в 14:32

в том, что у вас в итоге будет 2 url с сильно похожим содержимым. И вес страницы будет поделен на 2.
И Вам придется выбрать какой url является каноническим. И писать это в head. В то же время вы можете через css скрыть избыточные на ваш взгляд блоки на той же самой странице, без запроса к серверу, как это делает например тот же bootstrap.

Верстка и количество элементов действительно могут сильно меняться, но только если речь идет о мобильной версии против десктопа. Эту ситуации и поисковики тоже рассматривают как вынужденную. Все остально гугл будет воспринимать "с подозрением"

Аватар пользователя dgastudio dgastudio 1 декабря 2016 в 15:06
1

почему 2 урла? перечитайте топик.

по клику создаем куку, эту куку цепляем в шаблоне views, в зависимости от нее выводим один формат или другой
views остается неизменным, урл остается неизменным

пример такого функционала
http://rigaway.ru/kottedzhi-na-novorizhskom-shosse

Аватар пользователя engenes engenes 1 декабря 2016 в 17:24

Так и хочу сделать, формат будет меняться а url тот же, хотя на сайте DNS к url приписывается ?аргумент и в зависимости от того есть он или нет выводятся разные форматы. Но мне кажется идеальным будет иметь абсолютно одинаковые адреса, и но менять только форматы по клику

Аватар пользователя engenes engenes 2 декабря 2016 в 7:32

«по клику создаем куку, эту куку цепляем в шаблоне views, в зависимости от нее выводим один формат или другой»
создал тестовое представление как я понял за формат отвечает вот этот шаблон? (по названию и содержанию он ближе всего)

Аватар пользователя engenes engenes 2 декабря 2016 в 11:38

Подождите, я правильно понял, вы создали одно представление но в нем несколько отражений к примеру page_1 "таблицы",page_2 "Неформатированный список", и при клике просто переключаетесь между представлениями?

Аватар пользователя dgastudio dgastudio 2 декабря 2016 в 11:57

есть 3 варианта реализации этой задачи
1. сугубо через css
2. через темизацию друпала на уровне одного дисплея (в шаблоне views прописываете условия и все)
3. через хук views, который переключает дисплей в зависимости от условия

второй, по мне, самый оптимальный, если количество отображаемых полей не меняется кардинально (в одном варианте 5, в другом 25), и, запрос всегда будет идентичен

третий, меняет сам views, то есть меняется кол-во полей и сам запрос к базе (само собой кеш и прочие прелести).

Аватар пользователя goodboy goodboy 1 декабря 2016 в 21:27

Извините, но данный пример мне кажется вырожденным. Не меняется количество записей на странице, комбинация полей. В общем случае, дисплеи могут ведь качественно отличаться. Например, новости с тизером и фоткой (10 на странице) и список заголовков (30 на странице). Такое шаблонами долго делать

Аватар пользователя goodboy goodboy 1 декабря 2016 в 21:07

Скажите, а если скажем вывожу новости в виде /news?city=moscow и все новости московские, т.е. /news и /news?city=moscow показывают одинаковое, или вообще /news?city=all . В этом случае, гугл тоже подозревает в чем-то? Каноникал пишется автоматически модулем метатег.

Африканские друпалеры написали модуль views_modes, в котором тупо дают параметр mode (mode=table или mode=list). Что в get плохого? Например, можно дать ссылку другу с указанием mode и друг увидит такой же дисплей, как и вы.

Аватар пользователя negociant negociant 1 декабря 2016 в 15:25

goodboy wrote:


Мне одному кажется, что разметку формировать в функции не совсем верно? Есть же hook_theme и далее шаблон.

Аватар пользователя goodboy goodboy 1 декабря 2016 в 20:39

В функции разметка не формируется, а переключается view display. Я часто таким пользуюсь, или правя hook_views_pre_view в кастом-модуле или используя собственный views плагин.

Общий смысл такой:

if (УСЛОВИЕ) {
  $view->set_display('display1');
}
else {
  $view->set_display('display2');
}

В качестве УСЛОВИЯ может быть значение get, кука, текущая тема, права доступа или что-то другое.

Не понимаю, при чем тут hook_theme и шаблон. Накликивается вьюв, два дисплея, внешняя переключалка (множество вариантов), скрипт из пары строк и т.д. В вопросе ТС речь же шла о представлениях

Аватар пользователя engenes engenes 1 декабря 2016 в 22:25

Display1 и display2 это два настроенных отражения в одном представления?
То есть в одном настроен табличный вывод, во втором к примеру плиточный, вы это имели в виду?

Аватар пользователя engenes engenes 2 декабря 2016 в 6:53

Да, это требовалось, но насчёт контекстной фильтрации по терминам таксономии немного непонятно. Вот в настройках словаря, нужно выбирать представление, и одно из отражений, которое будет открываться при переходе на страницу термина. А тут у нас выходит, что будет открываться неприкрепленное представление, но скорее всего будет пустая страница (не уверен, надо проверять, но для чего-то же эта настройка в словаре существует).

Аватар пользователя engenes engenes 2 декабря 2016 в 6:46

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

Аватар пользователя VasyOK VasyOK 6 декабря 2016 в 17:21

Кароче выставил так. Что тут может не устраивать (?):
http://florange-konsultant.ru/nizhnee-bele-komfort/nabila - рузультат

Кусок из CSS:

.variants .views-row { /*строками*/
    clear: both;
    float: left;
    width: 100%;
}
 .kletkoi .variants .views-row { /*клеткой*/
    clear: none;
    float: left;
    width: 33.33%;
}

JS:

(function ($) {
 Drupal.behaviors.underwearTheme = {
  attach: function(context, settings) {                    
           
    function setMyCookie() {
      myCookieVal = $('.t-content').hasClass('kletkoi') ? 'isActive' : 'notActive';
      $.cookie('myCookieName', myCookieVal, { path: '/' });    
    }

    if ($.cookie('myCookieName') == 'isActive') {
        $('.t-content').addClass('kletkoi');    
    } else {
        $('.t-content').removeClass('kletkoi');
    }
   
    $(".t-kletkoi").click(function(){
        $(".t-content").toggleClass("kletkoi",true);
        $(".t-content").toggleClass("strokami",false);          
        setMyCookie();
    });
   
    $(".t-strokami").click(function(){
        $(".t-content").toggleClass("kletkoi",false);        
        $(".t-content").toggleClass("strokami",true);
        setMyCookie();  
    });  
   
  }
 };

Аватар пользователя engenes engenes 6 декабря 2016 в 17:42

Материал можно вывести либо анонсом либо своим отражением, расположить из админки поля в том порядке как мне нужно, в этом случае я буду просто переключаться между отражениями, css и js в таком случае минимум, не нужно писать костыли, чтобы работало после.ajax перезагрузки (во время срабатывания фильтров сортировок и прочего) к тому же добавление нового поля скорее всего ничего не испортит, в некоторых случаях даже css дописывать не придётся

Аватар пользователя engenes engenes 6 декабря 2016 в 17:53

Ну вы ведь за то, чтобы решить мой вопрос только средствами js?
Я бы использовал этот вариант, если бы перестроения были минимальны (не сторонник нагружать сервак без нужды).
Но когда у меня строчно а нужно плиткой и поля располагаются в разных отражениях в разной последовательности, то я точно не буду их cssом таскать, мне кажется правильней будет, чтобы они при загрузке страницы уже были расположены примерно там где надо