Yii2 Виджеты. Примеры


Содержание материала:

Виджеты

Виджеты — это многократно используемые строительные блоки, используемые в представлениях для создания сложных и настраиваемых элементов пользовательского интерфейса в объектно-ориентированном стиле. Например, виджет выбора даты может генерировать фантастический выбор даты, который позволяет пользователям выбирать дату в качестве своего входа. Все, что вам нужно сделать, это просто вставить код в такое представление, как следующее:

В Yii имеется большое количество виджетов, например активная форма, меню, виджеты jQuery UI, виджеты Twitter Bootstrap.

Использование виджетов

Виджеты в основном используются в представлениях. Вы можете вызвать метод yii\base\Widget::widget() , чтобы использовать виджет в представлении. Этот метод принимает массив конфигурации для инициализации виджета и возвращает результат визуализации виджета. Например, следующий код вставляет виджет выбора даты, который настроен на использование русского языка и сохраняет входные данные в атрибуте from_date в $model .

Некоторые виджеты могут взять блок контента, который должен быть заключен между вызовом yii\base\Widget::begin() и yii\base\Widget::end() . Например, следующий код использует виджет yii\widgets\ActiveForm для создания формы входа. Виджет будет создавать открывающий и закрывающий теги в месте, где вызываются функции begin() и end() соответственно. Все, что находится между ними, будет отображаться как есть.

Обратите внимание, что в отличие от yii\base\Widget::widget() , который возвращает результат визуализации виджета, метод yii\base\Widget::begin() возвращает экземпляр виджета, который вы можете использовать для создания содержимого виджета.

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

Глобальные значения по умолчанию для типа виджета можно настроить через контейнер DI:

Создание виджетов

Чтобы создать виджет, нужно перейти от yii\base\Widget и переопределить методы yii\base\Widget::init() или yii\base\Widget::run() . Обычно метод init() должен содержать код, который нормализует свойства виджета, тогда как метод run() должен содержать код, который генерирует результат визуализации виджета. Результат визуализации может быть непосредственно «отражен» или возвращен в виде строки функцией run() .

В следующем примере HelloWidget HTML-кодирует и отображает содержимое, присвоенное свойству сообщения. Если свойство не установлено, по умолчанию будет отображаться «Hello World».

Чтобы использовать этот виджет, просто вставьте следующий код в представление:

Ниже представлен вариант HelloWidget, который принимает содержимое, заключенное в вызовы begin() и end() , HTML-кодирует его, а затем отображает.

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

Следующий код показывает, как использовать этот новый вариант HelloWidget:

Иногда виджету может понадобиться отображать большой кусок контента. Хотя вы можете вставлять контент в метод run() , лучше поместить его в представление и вызвать yii\base\Widget::render() для его рендеринга. Например:

Yii2: Использование виджета yii\jui\DatePicker, мои настройки

Самый простой пособ работы с датой (на любом сайте) — использовать обычный input, указав ему type date :

Самым простым способом работы с датой в Yii2 является использование виджета DatePicker jQuery UI , который поставляется «из коробки» (шаблон advanced).

Но теперь встаёт вопрос о том, как записать в базу выбранную дату в нужном формате. Дело в том, что из виджета в нашу форму приходит дата в формате dd.mm.yyyy , а в базe она храниться в числовом формате (тип поля integer) .

На этот случай у меня есть решение (опять же, одно из множества). Это небольшое поведение, которое необходимо подключить в модели:

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

В самой форме, помимо нашего поля для ввода даты определим ещё одно свойство:

Добавим в правила:

В представлении мы будем работать уже с нашей отформатированной для виджета датой:

Вместо вышеуказанного поведения можно воспользоваться напрямую функцией strtotime()

YII2 Как создать представление ListView + исходники.

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

Подготовка

Для начала необходимо создать проект на YII2 и подготовить данные которые мы будем выводить через наше представление. Предположим наша БД будет называтся «post» которую вы уже наполнили её рыбными данными, а также создали модель Post. Давайте добавим в наш контроллер Post ответ на запрос «list»:

Описанный медот формирует ответ на запрос по ссылке: /index.php?r=post/list и рендерит шаблон из list.php что расположен в папке /views/post/ Давайте посмотрим, как сделать представление ListView в list.php .

Настройка представления ListView

В самом простом примере вы просто выводите ListView передаёте dataProvider в list.php файл предствавления и всё готово!

Но в таком случае ListView просто отобращает список id материалов. По умолчанию он будет отображать список моделей key. Так что нам прийдётся немного настроить данное представление. В следующем изображении описанны наиболее важные опции для кастомизации ListView.

dataProvider

dataProvider используется для указания источника данных. это объект, который исполняется в yii\data\DataProviderInterface. Обычно этот объект является экземпляром ActiveDataProvider класса.

Options

options представляет собой массив, для создания HTML атрибутов обёртки List View представления. Например:

Layout

layout пределяет структуру разметки ListView. По умолчанию его значение является строкой со следующим содержимым: «

\n\n«. Это означает, во-первых, отрендерить заголовок ListView. Затем последовательность объектов массива и в конце пагинатоа. Вы леко можете это переопределить, например переместив пагинатор наверх, вот так:

itemView

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

Передача строки

Для передачи строки, строка должна быть именем файла из части шаблона. Например, мы можем создать _list_item.php часть шаблона для определения HTML-разметки каждого элемента списка. Затем мы передаём эту часть в основной шаблон представления itemView таким образом:

В такой конфигурации будет четыре переменные неявно передающиеся и доступные в _list_item части шаблона.

  • $model — элемент модели данных
  • $key — ключевое значение, связанное с элементом данных
  • $index — нулевой индекс элемента данных в массиве элементов, возвращенных в $dataProv > — Сам экземпляр виджета ListView.

Передача Callback’а

Альтернативным вариантом может послужить передача callback’а в itemView и данный callback будет вызыватся каждый раз при рендеринге элемента списка.

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

Шаблон элемента _list_item.php может иметь следующий вид:

Когда и почему

Итак, когда же мы должны передать callback в itemView? Я думаю, что при следующих сценариях будет очень удобно использовать функцию обратного вызова для itemView:

  • При изменении или форматировании данных модели до рендеринга
  • Вскрыв нормальный поток рендеринга. Например используя $index мы можем вставить рекламу после трёх пунктов элементов.
  • Рендеринг различных частей шаблона. Например мы можем отрендерить шаблонный текст, изображение или даже видео в соответствии с категорией модели в поле.

Пагинатор

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

Данный пагинатор абстранируется от классов навяззаных в yii\widgets\LinkPager. Для получения дополнительных возможностей кастомизации пагинатора ListView представления, обратитесь к официальной документации YII2 LinkPager.

Итоги

В итоге у нас есть образцы кода для настройки Yii2 ListView. Ниже пример кода собранный вместе:

Yii2 и виджеты: немного полемики

Насколько прекрасен и прост Yii2 в работе с backend (хотя, так с любым фреймворком: сколько бы ни ругался на Symfony, но 90% работы происходит с PHP, а не с ним), настолько отвратителен в виджетах и рендеринге. Не знаю, есть ли где-нибудь подобный треш, как в Yii2. Сравнивая с тем же Symfony: там разработчики решили остановиться на дефолтном шаблонизаторе twig и не внедрять в стартовые шаблоны никаких примеров чудо-виджетов. Спасибо, ребят!

Виджеты — ужасная штука. «Это самодостаточный блок», говорили они. «MVC», говорили они. Неужели попытки скрыть передачу данных под видом DataProvider во вьюху действительно не дают повода задуматься?

Как только приходится что-то поменять в виджете, начинается боль. Если вы хотите поменять расположение кнопок — должны потратить два часа на поиски и применение информации. Вы достаточно постигли стандартные виджеты типа GridView? Не волнуйтесь! Любой другой виджет, который вы установите, например, FileInput от Kartik — и вуаля, гуглите снова. Гуглите много.

Окей, я не буду голословным, вот вам код:


Серьёзно, он такой и есть. Выглядит интуитивно понятно и очень гибко. Можно поменять язык, можно настроить множественную загрузку файлов, главное что смотрится красиво! Гляньте:

Да, мне тоже нравится. Работа над плагином проделана большая. Но оставьте это плагином. Зачем делать из него такое, от чего мои глаза ( речь идёт про мои впечатления после использования виджета, и они нисколько не объективны, да ) кровоточили разочарованием в принятых решениях. Побуду циником: взамен предложить нечего. Возможно, потому что Yii2 не стоит лезть во frontend. Возможно потому что отделение backend от frontend есть самое логичное, что произошло с вебом. С тем же вебом, где ECMAScript5 до сих пор не определился, как регламентировать асинхронные процессы, и весь Ajax реализован как бы интуитивно, а не по стандарту ECMA (ну и здорово!).

Давайте вернёмся к коду. Вы заметили ‘pluginEvents’? Это элемент массива, значением которого является… JavaScript! Даже jQuery. Впрочем, на использование jQuery нас обрёк сам фреймворк, но ладно. Дело в том, что приходится писать текст JavaScript прямо в строках PHP. То есть, когда в html встречался коннект к БД, бывалые программисты пускают скупую слезу отчаяния, но сами пишут JavaScript в PHP. Почему? Потому что «виджет есть независимый самодостаточный блок». Тогда что можно назвать виджетом? Календарь? Зачем нам календарик, если мы с ним не можем взаимодействовать? Только в том случае, когда нужно выбрать конкретную дату (и только), он нам пригодится из коробки, как есть. Но если при перелистывании месяцев должно что-то меняться во фронте — о-о, да, запасайтесь кофе и зефирками, впереди долгие бессонные ночи.

Топ-пост этого месяца:  Ребрендинг что это, примеры ребрендинга в России и в мире

JavaScript должен уметь общаться с другим JavaScript. Если нет — в дело пойдут глобальные переменные и window.variable = ‘1’. Как только мы захотим привинтить к календарику что-то красивое, то 1) видим что он виджет и плачем 2) не можем спихнуть эту работу на фронтенда, кроме как заставить всё переписать.

Все видели HTML-разметку? Её обычно много, и в глазах рябит. Но вызывает ли сложности изменить разметку? Хм, обычно нет. Это работа лёгкая и скучная.

Но подождите, сейчас вы увидите на редкость грустную разметку.

Yii2: Виджеты. Примеры

От автора: приветствую вас, друзья. Мы продолжаем цикл статей, посвященных знакомству с фреймворком Yii2. В данной статье мы познакомимся с таким понятием фреймворка Yii, как виджеты. В Yii2 виджеты позволяют избежать повторения кода и могут быть использованы многократно в различных представлениях. Давайте же рассмотрим примеры создания простейшего виджета.

И так, виджеты – это некоторые компоненты, которые предназначены в первую очередь для реализации элементов интерфейса и которые можно использовать многократно. Классическим примером такого элемента может быть меню. Меню используется практически на каждой странице вашего сайта и от страницы к странице остается неизменным. То есть, от страницы к странице мы должны повторять один и тот же код для получения меню и его вывода. Но благодаря виджетам мы можем избежать этой утомительной процедуры и создать меню только один раз, а затем просто вызывать его.

В Yii2 уже имеется большое количество различных виджетов: для создания форм, меню, jQuery UI и другие. Кроме того, фреймворк позволяет нам создавать собственные виджеты. Давайте на простом примере разберем создание простейшего виджета.

Создаются они в папке components, которую мы можем создать в корне приложения. Для создания виджета мы должны унаследовать класс yii\base\Widget . Внутри класса виджета мы можем переопределить методы init и run. Также можем создавать и собственные методы. Метод init, как правило, используется для нормализации свойств виджета (установка значений), а метод run возвращает результат рендеринга. Результат можно вывести с помощью echo или вернуть через return.

Давайте создадим простой пример виджета, который будет приветствовать посетителей сайта.

class HiWidget extends Widget

public function run()

Hello!

Теперь попробуем вызвать созданный виджет в представлении. Для этого необходимо обратиться к созданному классу и вызвать статичный метод widget.

В результате на странице мы увидим выводимую приветственную строку. Что здесь может смущать? Пока что у нас всего одна строка и мы просто поместили ее в метод run. А что если мы формируем большое меню – например mega menu? В этом случае у нас будет много кода HTML. Но это не проблема. Yii предлагает нам создать рядом с классом виджета папку views, в которую и поместить представление для виджета. Само представление можно вызвать методом render. Давайте попробуем.

Создадим вид hi.php:

Hello!

А в методе run вернем его:

public function run()

На выходе мы получим все тот же вариант. В итоге мы с вами создали самый простейший вариант виджета, который можно использовать сколь угодно много раз. На самом деле данная тема далеко не ограничивается этими знаниями. Виджеты могут быть куда как сложнее, они могут быть настраиваемыми, то есть в них можно передавать параметры. Но это тема уже отдельной статьи. Мы же на этом пока что остановимся. Больше о фреймворке вы можете узнать из наших бесплатных или платных уроков. Также создание простейшего блога на Yii2 можно посмотреть в этом цикле уроков .

Как передать модель в пользовательский виджет yii2?

Добрый день.
Нужно вывести данные из нескольких моделей на главную страницу, в footer.
Виджет написал, но возник вопрос, как теперь динамически передавать модель в класс виджета?
Сейчас выгладит это так:

Не могу понять, как в public $data передать модель из вне, чтобы не писать для каждой модели

а в вызове виджета указать

  • Вопрос задан более двух лет назад
  • 733 просмотра

Можно конечно и имя класса передавать в модель, но это не правильно:

В идеале модель должна возникать в контроллере и передаваться в view, где дальше передаваться в виджет. Или в виджет должны попадать не сама модель, а определенные данные. Возможно Вам надо написать свой dataProvider. посмотрите на примере activedataprovider www.yiiframework.com/doc-2.0/guide-output-data-pro.

А если сделать так, в контроллере собрать все модели в один массив, используя пользовательский метод, и одним махом передать в виджет?
Массив такого плана:

Ну а в самом виджете перебрать массив и вывести данные.

Yii Framework

Создание полноценного виджета для Yii2

Создание полноценного виджета для Yii2

Сообщение GHopper » 2020.12.05, 16:56

/*голос из будущего*/
Вот что получилось:

Я веб-программист с многолетним стажем, работающий в компании над сложным интересным проектом. У нас свой git-сервер и свой фреймворк.

В качестве расширения кругозора хочу инвестировать часть свободного времени в изучение Yii2. Интересует не простой Hello word после прочтения документации, а что-то рабочее и реюзабильное. Парралельно хотелось бы разобраться с github (полноценный проект со всеми «модными иконками», packagist, и совместная работа над проектом).

В общем, предстоит путь долгий и тернистый. Разбил его на этапы:

1. Постановка задачи
2. Реализация исходного проекта
3. Размещение на github
4. Поддержка и развитие

Пункт первый выполнен. Хочу создать ползеный виджет, функционал которого вы можете оценить в гите (т.е. на 3 стадии). Рабочее название «map».

В данный момент идет работа над пунктом вторым. Виджет написан, он интегрируется во view и выполняет свой функционал. Имеются следующие вопросы:

1. В виджете есть assets (css, js) и view. Соответственно структура директорий следующая

Насколько это правильно?

3. Структура git-ропозитория. Что должно быть помещенов git (как я понимаю только дирретория components/map) и какая структура всего репозитория должна быть (исходники, тесты, примеры и т.п.).

4. Пару строк по офрмлению кода. Как я понимаю, в Yii2 принят некий формат, которому желательно следовать. Есть ли тулза, которая бы проверяла формат? Где почитать рекомендации? Какие-то сложные инструкции в phpDoc или все ограничивается описанием методов и членов?

Еще раз обращу внимание, что в результате п.2 хочу получить код, готовый к размещению на github, который будет удобно ипользовать в других проектах через composer. Поэтому такое внимание структуре директорий и namespace.

Re: Создание полноценного виджета для Yii2

Сообщение ElisDN » 2020.12.05, 17:31

1. Нормальная. Но если будете добавлять тесты и документацию, то лучше сделать папки src, tests и docs вместо скидывания всего в корень.

2. Все обычно публикуют с неймспейсом /

Так как неймспейсы с маленькой больше практически никто кроме Yii не называет.

4. Используются стили кодирования из общепринятых PSR:

Есть PHP Code Sniffer. Ставим в проект:

Re: Создание полноценного виджета для Yii2

Сообщение GHopper » 2020.12.05, 20:36

Спасибо за ответ.

Ок. Сырой проект создан. В git загружен.
Теперь давайте обсудим чуть больше конкретики.

Идея виджета — svg карта, создающаяся на основе входных данных.
Планирую получать данные из php-массива, js-файла либо запрашивать json по адресу. Сама карта будет выступать инструментом навигации по разделам, выбором региона, вызова js-функций и др. Т.е. такой инстумент, в который передаем paths с параметрами и получаем svg с заданными в параметрах событиями.
В качестве пример — карта России, позволяющая перейти в выбранный регион.

Палн ближайших работ:
— добавить анимацию при наведении курсора мыши
— добить обработчик клика
— добавить всплывающие подсказки

Никуда не тороплюсь, занимаюсь в образовательных целях, сроков вообще нет. Более того, frontend вообще не моя сфера интересов, поэтому сроки будут ограничены в т.ч. изучением кучи всего смежного (а это и формат svg, и git, и js и т.п.).

Вопросы:
1. Версионирование. Как автоматически увеличивать версии в репозитории? Сталкивался с тэгами, но было бы здоров автоматически добавлять версию непосредственно в phpDoc кода.

2. Как выполнить


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

3. Во многих гит-репозиториях вижу разные иконки, которые показывают «крутость проета». Покрытие тестами, лицензию и др. Где почитать про это?

4. Лицензия. Никогда не сталкивался. Какую указывать, чтобы люди безвозмездно брали и пользовались?

5. В файле svgMapWidgetAsset есть код:

Расхаркодить это как-то можно? Нужно? Подозреваю что здесь может быть источник ошибок.

P.S. Попытался добавить скриншот виджета, получил ошибку в DevTools:

Re: Создание полноценного виджета для Yii2

Сообщение ElisDN » 2020.12.05, 21:08

Уберите префиксы из классов. Вместо svgMapWidget называйте MapWidget.
Уберите закрывающий «?>» из файлов с классами.

1. Просто ставьте теги:

версия в PHPDoc не нужна.

2. Через registerJs():

3. Прямо в этих репозиториях взять иконки из README.md и позаходить на сайты, на которые они ведут при клике. А так на примере Yii2 посмотреть файлы конфигурации сервисов вроде .scrutinizer.yml и .travis.yml.

4. Скопируйте LICENCE.md у Yii2 или любого чужого компонента и поменяйте имена на свои. Удобнее всего BSD-3 и MIT.

5. Вместо метода init() присвойте сразу полю:

Re: Создание полноценного виджета для Yii2

Сообщение GHopper » 2020.12.05, 23:39

Название хотелось бы все-таки оставить svgMap, т.к. не просто карта, а карта svg-данных (т.е. может быть график, изображение, карта и др).

1. Удаление закрывающего «?>» чем обусловлено? С 1995 года люди закрывают, а здесь выясняется что все зря )

2. Моим следующим шагом планируется кастомизация виджета. Одно из направлений кастомизации — источник данных. Хочу добавить возможность передавать php-массив, адрес json и (как сейчас реализовано) js-файл. Для этого мне необходимо передвать в svgMapWidgetAsset параметры, чтобы подключать/не подключать js-файл и, если уж подключать, то передать название файла (т.к., например, может быть несколько стран и в зависимости от переданного параметра будет генерироваться карта выбранной страны).
Как это реализовать? На ум приходит только одна мысль — переопределить метод svgMapWidgetAsset::register()? Но метод этот статический.

Re: Создание полноценного виджета для Yii2

Сообщение ElisDN » 2020.12.06, 07:42

Тогда назовите SvgMap, чтобы все классы были с большой.

Топ-пост этого месяца:  Прямой эфир в Инстаграме как запустить и как смотреть

1. Обусловнено борьбой со случайной отправкой пробела, который может оказаться прсле закрытия в файле.

Re: Создание полноценного виджета для Yii2

Сообщение GHopper » 2020.12.06, 14:49

Вполне годный аргумент! Увы, по второму вопросу так и не получил ответ. Постараюсь дать пояснения:

1. Виджет строит svg-карту по переданным ему данным. На данный момнт я хочу реализовать следующие источники:
а) php-массив (как следствие данные из БД)
б) ссылка на json (как следствие работа с REST)
в) js-файл (массивы могут быть огромными, поэтому хочется подключать «на лету» только нужные)

Пример параметров виджета:

Как видим, среди прочего, захардкожен js-файл russia.js. Но для удобства, с виджетом может идти и, например, china.js. Так вот, как перенести параметр из SvgMapWidget в SvgMapWidgetAsset, чтобы динамически подключать нужные файлы?

P.S. сейчас вспомнил про перенос инициализации sourcePath из метода init(). Это просто общепринятое правило или тоже имеет свое обоснование?

2. Виджет имеет свой шаблон. Хотелось бы сделать его универсальным в плане поличества экземпляров. Сейчас в коде захардкожены id дивов, в которые мы будем аппендить созданные структуры:

Re: Создание полноценного виджета для Yii2

Сообщение caHek2x » 2020.12.06, 15:01

насчет id
например как сделано в ActiveForm yii2

ActiveForm наследуется от Widget

Re: Создание полноценного виджета для Yii2

Сообщение maleks » 2020.12.06, 15:30

Re: Создание полноценного виджета для Yii2

Сообщение GHopper » 2020.12.06, 16:01

Спасибо за ответ. Теперь у меня есть хоть какое-то решение.
Признаюсь честно, оно кажется мне не совсем удобным, т.к. придется захардкодить все имеющиеся файлы в AssetBundle. Более того — с виджетом идет набор «популярных карт», но ничто не должно мешать добавить свою. И в этом случае нужно будет передавать в AssetBundle ссылку на файл из публичной web-дирректории.

В общем круто, что решение нашлось. Но есть еще над чем подумать.

Re: Создание полноценного виджета для Yii2

Сообщение GHopper » 2020.12.07, 01:31

Я пришел к выводу, что от идеи с динамическим подключение js-файлов можно отказаться. Ни такая уж это и килл-фича. Пляшем дальше.

Продолжу с вопросами:

1. Карту рисует js-класс:

Как я уже упоминал, я вообще не силен в js, поэтому буду признателен любой критике и советам. Именно так мы становимся мудрее.
Как вы можете видеть, в методе SvgMap.createToolTipContext() формируется текст для всплывающих подсказок. Плюс есть SvgMap.mouseClick(), где происходит обработка клика.
Мне бы хотелось, чтобы пользователи виджета могли переопределять эти методы в своем коде. Можно выводить любые данные из svg (например добавить поле в каждый path «itemsCount»). Ну а обработчик клика я вообще не могу захардкодить.
Вопрос — как в js перегружать методы класса? Могу предположить, что эти методы можно передать как параметр при созднии объекта.

2. Как пользоваться тегами в git? Я добавил два тега v0.0.1 и v0.0.2 Появилось два релиза, но это как-то слабо смахивает на «релиз» ) В целом я не понимаю их надобность в таком вот виде. Переключаться между ветками/коммитами я и через tig могу (даже с большим удобством). Пакаджист почему-то вообще не показывает эти теги. В общем, непонял я этот инструмент. Расскажите.

3. Обработка ошибок в js.

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

Создание виджета темы сайта на Yii2

Краткий обзор создания виджета в Yii2 по переключению дневной/ночной темы сайта и некоторые нюансы при работе с куками

Вдохновило меня на написание переключалки ночной/дневной темы блога расширение Dark Reader. Он в приятном тёмном цвете представляет любой сайт, но бывает так, что на некоторых ресурсах может делать менее заметными ключевые детали, как например, некоторые заголовки и блоки с важной информацией, да и к тому же посетители сайта могут зайти из отличных от chrome/chromium браузеров. В принципе, я считаю что каждый уважаемый ресурс должен предоставлять своим пользователям такую фичу, а в приложениях (десктоп/мобильные) так и тем более. Поэтому с этой точки зрения, необходимо детально проработать собственную ночную тему таким образом, чтобы пользователям было комфортно читать страницы сайта и, что не менее важно, находить необходимую информацию.

Поделюсь реализацией виджета в Yii2, а именно старенькой 2.0.10 версии и некоторыми нюансами при работе с куками, которые у меня возникли в этом фреймворке. Сам виджет очень простой и представляет собой блок html кода, описывающий заголовок и две кнопки, для светлой (по умолчанию) и тёмной темы сайта:

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

По умолчанию валидация кук в yii включена и с этим связано получение куки напрямую из супер глобального массива. Валидацию можно отключить, установив свойство yii\web\Request::$enableCookieValidation в false, но делать это не рекомендуется (почитать об этом можно здесь). Поэтому для этого решения можно поработать с куками на чистом php, $_COOKIE , вместо объектно-ориентированного интерфейса во фреймворке, типа взять куки таким образом из request компонента: $cookies = Yii::$app->request->cookies; . Сначала, я не мог понять почему на бэкенде не могу прочитать куку в таком варианте, пока не отключил валидацию. Вообщем, я несколько был удивлён этим странным явлением, которое явно не прибавляет баллов в моей оценке yii2.. Но это лишь моя субъективная оценка.

Там где должен выводиться виджет, подключаем вызов статического метода из класса компонента LightDarkModeArea, которой мы объявим позже и прокидываем ему нашу куку:

И в области скриптов:

Файл lightnight.js. Собственно установка/переключение куки:

Компонент рисует html и в зависимости от проброшенной ему куки из основного шаблона, делает активной кнопку дневной или ночной темы.

Вот в целом и весь механизм, останется добавить иконки light и night.

Yii2: Виджеты. Примеры

This extension enhances or adds functionality to existing Yii Framework 2 Widgets to make available other bundled features available in Bootstrap 3.0, new HTML 5 features and affiliated Bootstrap extras.

NOTE: This extension has been revamped with release v3.4.1 on 05-Dec-2015. With release v3.4.0, each widget within this extension bundle has been logically regrouped and split into separate sub repositories. This change has been done to allow developers flexibility to install separately or specific widgets only (via composer) if needed. However, for new users installing this bundle should be the easiest way to give you access to all these important widget sub repositories in one shot. This change would not affect backward compatibility for any users already using the previous extension versions.

Widgets available in this bundle


The yii2-widgets bundle automatically includes extensions or widgets from these sub repositories for accessing via \kartik\widgets\ namespace.

Additional related widgets

This extension has now matured to contain the most needed basic widgets for Yii 2 input and navigation controls. In order to support this extension better, any additional input and navigation widgets will be created separately. Listed below are the additional widgets that are related to similar functionality like the yii2-widgets , but have been created as separate extensions (these widgets depend on kartik-v/yii2-widgets ).

  • yii2-dropdown-x: Extended Bootstrap 3 dropdown menu for Yii 2.0
  • yii2-nav-x: Extended Bootstrap 3 navigation menu for Yii 2.0
  • yii2-context-menu: Bootstrap 3 context menu for Yii 2.0
  • yii2-sl >

The preferred way to install this extension is through composer. Remember to refer to the composer.json for this extension’s requirements and dependencies.

Note: Check the composer.json for this extension’s requirements and dependencies. Read this web tip /wiki on setting the minimum-stability settings for your application’s composer.json.

to the require section of your composer.json file.

Refer the CHANGE LOG for details on changes to various releases.

The widgets currently available in yii2-widgets are grouped by the type of usage.

Extends Yii ActiveForm widget. Facilitates all three form layouts available in Bootstrap i.e. vertical, horizontal, and inline. Allows options for offsetting labels and inputs for horizontal form layout. Works closely with the extended ActiveField widget.

Extends Yii ActiveField widget. Allows Bootstrap styled input group addons to be prepended or appended to textInputs. Automatically adjusts checkboxes and radio input offsets for horizontal forms. Allows, flexibility to control the labels and placeholders based on form layout style (e.g. hide labels and show them as placeholder for inline forms). The extended ActiveField functionalities available are:

  • Addons
    • Prepend Addon
    • Append Addon
    • Icon Addon
    • Input Addon
    • Button Addon
    • Button Dropdown Addon
    • Segmented Button Addon
    • Prepend & Append
    • Input Group Settings
  • Inputs
    • Checkbox
    • Radio
    • Checkbox List
    • Radio List
    • Static Input
    • HTML 5 Input
  • Multi Select
    • Vertical Form
    • Horizontal Form
    • Radio List
    • Display Options

The DepDrop widget is a Yii 2 wrapper for the dependent-dropdown jQuery plugin by Krajee. This plugin allows multi level dependent dropdown with nested dependencies. The plugin thus enables to convert normal select inputs to a dependent input field, whose options are derived based on value selected in another input/or a group of inputs. It works both with normal select options and select with optgroups as well.

The Select2 widget is a Yii 2 wrapper for the Select2 jQuery plugin. This input widget is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results. The widget is specially styled for Bootstrap 3. The widget allows graceful degradation to a normal HTML select or text input, if the browser does not support JQuery.

The Typeahead widget is a Yii 2 wrapper for for the Twitter Typeahead.js plugin with certain custom enhancements. This input widget is a jQuery based replacement for text inputs providing search and typeahead functionality. It is inspired by twitter.com’s autocomplete search functionality and based on Twitter’s typeahead.js which is described as as a fast and fully-featured autocomplete library. The widget is specially styled for Bootstrap 3. The widget allows graceful degradation to a normal HTML text input, if the browser does not support JQuery. You can setup model validation rules for a model attribute that uses Typeahead widget for input like any other field. The widget comes in two variants:

TypeaheadBasic : This widget is a basic implementation of the typeahead.js plugin without any suggestion engine. It uses a javascript substring matcher and Regular Expression matching to query and display suggestions. VIEW DEMO

Typeahead : This widget is an advanced implementation of the typeahead.js plugin with the BloodHound suggestion engine and the Handlebars template compiler. VIEW DEMO

The DatePicker widget is a Yii 2 wrapper for the Bootstrap DatePicker plugin. The plugin is a fork of Stefan Petre’s DatePicker (of eyecon.ro), with improvements by @eternicode. The widget is specially styled for Yii framework 2.0 and Bootstrap 3 and allows graceful degradation to a normal HTML text input, if the browser does not support JQuery. The widget supports these markups:

  • Simple Input Markup
  • Component Markup — Addon Prepended
  • Component Markup — Addon Appended
  • Inline / Embedded Markup
  • Date Range Markup (from and to dates)

The TimePicker widget allows you to easily select a time for a text input using your mouse or keyboards arrow keys. The widget is a wrapper enhancement of the TimePicker plugin by rendom forked from jdewit’s TimePicker. This widget as used here has been specially enhanced for Yii framework 2.0 and Bootstrap 3.

The DateTimePicker widget is a Yii 2 wrapper for the Bootstrap DateTimePicker plugin. The plugin is a fork of the DateTimePicker plugin by @eternicode and adds the time functionality. The widget is similar to the DatePicker widget in most aspects, except that it adds the time functionality and does not support ranges. The widget is specially styled for Yii framework 2.0 and Bootstrap 3 and allows graceful degradation to a normal HTML text input, if the browser does not support JQuery. The widget supports these markups:

  • Simple Input Markup
  • Component Markup — Addon Prepended
  • Component Markup — Addon Appended
  • Inline / Embedded Markup

The TouchSpin widget is a Yii 2 wrapper for for the bootstrap-touchspin plugin by István Ujj-Mészáros, with certain additional enhancements. This input widget is a mobile and touch friendly input spinner component for Bootstrap 3. You can use the widget buttons to rapidly increase and decrease numeric and/or decimal values in your input field. The widget can be setup to include model validation rules for the related model attribute.

The FileInput widget is a customized file input widget based on Krajee’s Bootstrap FileInput JQuery Plugin. The widget enhances the default HTML file input with various features including the following:

  • Specially styled for Bootstrap 3.0 with customizable buttons, caption, and preview
  • Ability to select and preview multiple files
  • Includes file browse and optional remove and upload buttons.
  • Ability to format your file picker button styles
  • Ability to preview files before upload — images and/or text (uses HTML5 FileReader API)
  • Ability to preview multiple files of different types (both images and text)
  • Set your upload action/route (defaults to form submit). Customize the Upload and Remove buttons.
  • Internationalization enabled for easy translation to various languages

Future planned enhancements:

  • Drag and drop functionality
  • Realign/Rearrange the items in preview window
  • Better captioning for each file in the preview window
  • Support for previewing content other than image and text (e.g. HTML)

The widget runs on all modern browsers supporting HTML5 File Inputs and File Processing API. For browser versions IE9 and below, this widget will gracefully degrade to normal HTML file input. The widget is vastly inspired by this blog article and Jasny’s File Input plugin.

The ColorInput widget is an advanced ColorPicker input styled for Bootstrap. It uses a combination of the HTML5 color input and/or the JQuery Spectrum Plugin for rendering the color picker. You can use the Native HTML5 color input by setting the useNative option to true . Else, the Spectrum plugin polyfills for unsupported browser versions.

  • Specially styled for Bootstrap 3.0 with customizable caption showing the output of the control.
  • Ability to prepend and append addons.
  • Allow the input to be changed both via the control or the text box.
  • The Spectrum plugin automatically polyfills the HTML5 color input for unsupported browser versions.

The RangeInput widget is a customized range slider control widget based on HTML5 range input. The widget enhances the default HTML range input with various features including the following:

  • Specially styled for Bootstrap 3.0 with customizable caption showing the output of the control.
  • Ability to prepend and append addons (very useful to show the min and max ranges, and the sl >

The SwitchInput widget turns checkboxes and radio buttons into toggle switches. The plugin is a wrapper for the Bootstrap Switch Plugin and is specially styled for Bootstrap 3.

The StarRating widget is a wrapper for the Bootstrap Star Rating Plugin JQuery Plugin designed by Krajee. This plugin is a simple yet powerful JQuery star rating plugin for Bootstrap. Developed with a focus on utlizing pure CSS-3 styling to render the control.

The Spinner widget is a wrapper for the spin.js. It enables you to add an animated CSS3 loading spinner which allows VML fallback for IE. Since, its not image based, it allows you to configure the spinner style, size, color, and other CSS attributes. The major advantage of using the CSS3 based spinner, is that the animation can be made visible to user for non-ajax based scenarios. For example on events like window.load or window.unload (thereby enabling you to show a page loading progress without using ajax).

Extends Yii Menu widget. This widget offers a scrollspy and affixed enhanced navigation (upto 2-levels) to highlight sections and secondary sections in each page. The affix widget can be used to generate both the:

  • Sidebar Menu: Displays the scrollspy/affix navigation menu as a sidebar, and/or
  • Main Body: Displays the main body sections based on the section & subsection headings and content passed.

The parameters to pass are:

  • type The affix content type. Must be either menu or body . Defaults to menu
  • items : The affix content items as an array. Check the affix combined usage for a detailed example.

Note: If you have the header section fixed to the top, you must add a CSS class kv-header to the header container. Similarly, for a fixed footer you must add the class kv-footer to your footer container. This will ensure a correct positioning of the affix widget on the page.

This widget is a collapsible side navigation menu built to seamlessly work with Bootstrap framework. It is built over Bootstrap stacked nav component. This widget class extends the Yii Menu widget. Upto 3 levels of submenus are by default supported by the CSS styles to balance performance and useability. You can choose to extend it to more or less levels by customizing the CSS.

Extends the \yii\bootstrap\Alert widget with more easy styling and auto fade out options.

A widget that turns standard Bootstrap alerts into «Growl-like» notifications. This widget is a wrapper for the Bootstrap Growl plugin by remabledesigns.

Alert block widget that groups multiple \kartik\widget\Alert or kartik\widget\Growl widgets in one single block and renders them stacked vertically on the current page. You can choose the TYPE_ALERT style or the TYPE_GROWL style for your notifications. You can also set the widget to automatically read and display session flash messages (which is the default setting). Alternatively, you can setup and configure your own block of custom alerts.

You can see a demonstration here on usage of these widgets with documentation and examples.

Создание виджета темы сайта на Yii2

Краткий обзор создания виджета в Yii2 по переключению дневной/ночной темы сайта и некоторые нюансы при работе с куками

Вдохновило меня на написание переключалки ночной/дневной темы блога расширение Dark Reader. Он в приятном тёмном цвете представляет любой сайт, но бывает так, что на некоторых ресурсах может делать менее заметными ключевые детали, как например, некоторые заголовки и блоки с важной информацией, да и к тому же посетители сайта могут зайти из отличных от chrome/chromium браузеров. В принципе, я считаю что каждый уважаемый ресурс должен предоставлять своим пользователям такую фичу, а в приложениях (десктоп/мобильные) так и тем более. Поэтому с этой точки зрения, необходимо детально проработать собственную ночную тему таким образом, чтобы пользователям было комфортно читать страницы сайта и, что не менее важно, находить необходимую информацию.

Поделюсь реализацией виджета в Yii2, а именно старенькой 2.0.10 версии и некоторыми нюансами при работе с куками, которые у меня возникли в этом фреймворке. Сам виджет очень простой и представляет собой блок html кода, описывающий заголовок и две кнопки, для светлой (по умолчанию) и тёмной темы сайта:

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

По умолчанию валидация кук в yii включена и с этим связано получение куки напрямую из супер глобального массива. Валидацию можно отключить, установив свойство yii\web\Request::$enableCookieValidation в false, но делать это не рекомендуется (почитать об этом можно здесь). Поэтому для этого решения можно поработать с куками на чистом php, $_COOKIE , вместо объектно-ориентированного интерфейса во фреймворке, типа взять куки таким образом из request компонента: $cookies = Yii::$app->request->cookies; . Сначала, я не мог понять почему на бэкенде не могу прочитать куку в таком варианте, пока не отключил валидацию. Вообщем, я несколько был удивлён этим странным явлением, которое явно не прибавляет баллов в моей оценке yii2.. Но это лишь моя субъективная оценка.

Там где должен выводиться виджет, подключаем вызов статического метода из класса компонента LightDarkModeArea, которой мы объявим позже и прокидываем ему нашу куку:

И в области скриптов:

Файл lightnight.js. Собственно установка/переключение куки:

Компонент рисует html и в зависимости от проброшенной ему куки из основного шаблона, делает активной кнопку дневной или ночной темы.

Вот в целом и весь механизм, останется добавить иконки light и night.

Топ-пост этого месяца:  JavaScript методы alert, prompt и confirm
Добавить комментарий