Статьи из рубрики nested-set
Виджет для вывода списка рубрик Nested Set
Выбор всех статей по рубрике
В конце предыдущей статьи были указаны две вещи, которых не хватает для начала использования рубрикатора.
Первая из них - необходимо добавить поле rubric
в таблицу post
. С этой операцией связано и изменения в модели common/models/Post
, которые очевидно касаются методов rules()
и attributeLabels()
.
Кроме этого нужно добавить обработку выбранной пользователем рубрики в actionIndex()
контроллера frontend/controllers/PostController
.
Простые действия над деревом Nested Set
Что нужно учесть для CRUD
Все необходимые методы, для управления деревом Nested Set уже определены в расширении.
Поэтому изменения в стандартном контроллере совсем небольшие. Нужно, например, вместо стандартного метода save()
модели использовать метод prependTo()
расширения, а вместо delete()
, deleteWithChildren()
.
Представления для операций с Nested Set
Что нужно учесть в представлениях при редактировании Nested Set
Мы, в общих чертах, разобрались с деревьями Nested Set и создали модель для хранения дерева. В модели определили пару простых методов.
Теперь нужно разобраться с тем, как добавлять новые рубрики. Начнем с представлений.
Подключение расширения Nested Set
Определение данных и необходимых методов в модели
Мы получили общее представление о древовидной структуре данных называемой Nested Set. Теперь пришло время подключить к блогу соответствующее расширение.
Поведение выполняет работу по добавлению новых элементов в дерево, поиск всех подчиненных элементов для данного узла, удаление узла. И многое другое, что может быть использовано, например, при работе с каталогами товаров.
Как устроена структура данных Nested Set
Как сделать рубрикатор
Рубрикатор, как средство поиска интересных статей, имеет свои недостатки - трудно придумать иерархию, названия рубрик, трудно потом решить к какой конкретно рубрике относится статья. "Но, так принято" - скажите вы и будете правы.
Поэтому, давайте делать рубрикатор.
Поиск
Метки
Подключение расширения Nested Set
Определение данных и необходимых методов в модели
- 1. Как устроена структура данных Nested Set
- 2. Подключение расширения Nested Set
- 3. Представления для операций с Nested Set
- 4. Простые действия над деревом Nested Set
- 5. Виджет для вывода списка рубрик Nested Set
Мы получили общее представление о древовидной структуре данных называемой Nested Set. Теперь пришло время подключить к блогу соответствующее расширение.
Поведение выполняет работу по добавлению новых элементов в дерево, поиск всех подчиненных элементов для данного узла, удаление узла. И многое другое, что может быть использовано, например, при работе с каталогами товаров.
Наши задачи проще и сводятся к следующему:
- Управление рубрикатором - добавление и удаление рубрик, редактирование, отображение списка рубрик для визуального контроля.
- Закрепление статьи за рубрикой.
- Вывод списка рубрик для выбора нужной рубрики.
Для их решения, как обычно, нужна модель, контроллер, представления и еще виджет.
Data
Cоздадим таблицу, которая будет хранить дерево рубрик и введем обязательную корневую рубрику.
CREATE TABLE tbl_rubric ( id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, lft INT(11) NOT NULL, rgt INT(11) NOT NULL, level INT(11) NOT NULL, name VARCHAR(50) NOT NULL, KEY lft (lft), KEY rgt (rgt), KEY level (level) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; INSERT INTO tbl_rubric (id, lft, rgt, level, name) values(1, 1, 2, 1, 'Без рубрики')
Установим расширение Nested Set.
Model
Создадим модель common\models\Rubric.php
, подключив расширение и определив два служебных поля значение которых будет объяснено позже.
namespace common\models; use creocoder\nestedsets\NestedSetsBehavior; use yii\db\ActiveRecord; class Rubric extends ActiveRecord { public $parent_node; // the parent node for just added public $post_count; // posts count in a rubric ... public function behaviors() { return [ 'tree' => [ 'class' => NestedSetsBehavior::className(), 'depthAttribute' => 'level', ], ]; } ...
И напишем пару методов.
Первый из которых будем использовать для вывода названий рубрик. Для отражения уровня вложенности будем делать отступы. Формирование отступов зависит от вывода. Метод формирования будет разным для выпадающего списка и просто вывода в блоке.
public function getPrettyName($dropdown = false) { return $dropdown ? str_repeat('-', ($this->level - 1) * 2) . ' ' . $this->name : '<span style="margin-left:' . (($this->level - 2) * 20) . 'px;">' . $this->name . '</span>'; }
Второй метод нужен для формирования выпадающего списка, который будет использоваться во-первых при выборе рубрики, за которой будет закреплена статья и во-вторых для выбора рубрики, которая является родительской рубрикой для вновь добавляемой рубрики.
Цели добавления новой рубрики и служит одно из дополнительных полей модели - $parent_node
. Добавляя новую рубрику мы должны определить ее предка. Именно за ним и будет вставлен "новичок".
Итак, метод items()
public function items($rootTitle = null) { if(!$rootTitle) $rootTitle = \Yii::t('app', 'Root'); $a = []; $a[1] = $rootTitle; foreach(Rubric::find()->where('id>1')->orderBy('lft ASC')->all() as $node) $a[$node->id] = $node->getPrettyName(true); return $a; }
Теперь посмотрим, как же мы будем добавлять новую рубрику, просматривать результат добавления, редактировать названия? То есть перейдем к представлениям.
Заключение
Для создания рубрикатора не обязательно вникать в детали работы программы-расширения, которая выполняет всю основную работу.
Оставить комментарий
Только авторизованные пользователи могут оставлять комментарии. Пожалуйста авторизуйтесь или пройдите регистрацию.
Можно авторизоваться, используя социальную сеть-
-
-
-