Теги

Сначала надо создать 3 таблицы: posts (для постов) tags (для тегов) и posts_tags (связка постов и тегов). Если одна из таблиц уже существует, надо пропускать первый вариант настройки тегов.

CREATE TABLE `posts` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(255) NOT NULL,
  `content` text NOT NULL,
  `created` DATETIME,
  `modified` DATETIME,
  PRIMARY KEY  (`id`)
) ENGINE=INNODB;

CREATE TABLE `tags` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=INNODB;

CREATE TABLE `posts_tags` (
  `post_id` INT,
  `tag_id` INT,
  INDEX post_id (`post_id`),
  INDEX tag_id (`tag_id`),
  FOREIGN KEY (post_id) REFERENCES `posts`(id) ON DELETE CASCADE,
  FOREIGN KEY (tag_id) REFERENCES `tags`(id) ON DELETE CASCADE
) ENGINE=INNODB;

1-ый способ: CRUD

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

Через консоль надо запустить команду ниже, чтобы создать нужные файлы.

cd app/
Console/cake bake all

В результате будут созданы файлы для страниц /posts и /tags. Эти страницы также можно открывать и редактировать. При создании поста можно выбирать теги (должны быть заранее созданы).

На странице поста будут выводится его теги, а на странице тега будут выводиться посты с данным тегом.

2-ой способ: вывод тегов

Если одна из таблиц в начале статьи уже существуют в проекте, то надо указать настройку тегов и их вывод на странице вручную.

Для этого надо добавить следующий код:

# app/Model/Post.php

class Post extends AppModel {
    // …

    public $hasAndBelongsToMany = array('Tag');

}

Через свойство $hasAndBelongsToMany посты и теги привязываются через таблицу «posts_tags». Например, допустим таблица «posts_tags» имеет следующие данные:

| post_id | tag_id |
--------------------
| 1       | 4      |
| 1       | 6      |

Это означает, что для поста с ИД 1 заданы теги с ИД 4 и 6. Данная структура называется «связь многие ко многим».

Вывести теги на странице поста можно через следующий код:

# app/View/Posts/view.ctp

// Имя поста
$post['Post']['name'];

// Теги
foreach ($post['Tag'] as $tag) {
    echo $tag['name'];
}

2-ой способ: сохранение тегов

Форма для сохранения тегов выглядит следующим образом.

# app/View/Posts/edit.ctp

$this->Form->create('Post');
    echo $this->Form->input('id');
    echo $this->Form->input('content');

    // код, формирующий поле формы для сохранения тегов
    echo $this->Form->input('Tag');

echo $this->Form->end('Редактировать');

В результате будет сгенерирован список для выборки тегов:

<select name="data[Tag][Tag][]" multiple="multiple" id="TagTag">
    <option value="1">Тег один</option>
    <option value="2">Тег два</option>
</select>

В формате POST-запроса данные для сохранения будут выглядеть примерно следующим образом:

array(
    'Post' => array(
        'id' => '1',
        'name' => 'Название страницы',
        'content' => 'Контент'
    ),
    'Tag' => array(
        'Tag' => array(
            (int) 0 => '4',
            (int) 1 => '6'
        )
    )
)

Для сохранение тегов для поста достаточно вызвать метод save() c переданными данными.

# app/Controller/PostsController.php

public function edit($id = null) {
    // …
    if ($this->request->is(array('post', 'put'))) {
        $this->Post->save($this->request->data);
    }
}

2-ой способ: вывести посты по тегам

Чтобы выводить посты для тегов, надо создать файл app/Controller/TagsController.php, в котором создать страницу тега.

# app/Controller/TagsController.php

App::uses('AppController', 'Controller');

class TagsController extends AppController {

    public function view($id = null) {
        if (!$this->Tag->exists($id)) {
            throw new NotFoundException(__('Invalid tag'));
        }
        $this->set('tag', $this->Tag->findById($id));
    }

}

Затем надо создать файл app/Model/Tag.php.

# app/Model/Tag.php

App::uses('AppModel', 'Model');

class Tag extends AppModel {
    public $hasAndBelongsToMany = array('Post');
}

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

Выводятся посты для тегов через следующий код:

# app/View/Tags/view.ctp

// Имя тега
$tag['Tag']['name'];

// Посты
foreach ($tag['Post'] as $post) {
    echo $post['name'];
}