Как определить следующую статью в связанном списке - vorst.ru

Кто за кем


Какую статью выбрать следующей или предыдущей

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

Кто за кем

Какую статью выбрать следующей или предыдущей

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

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

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

Но есть одно "но".


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

Найти такие статьи не сложно. Изменим немного метод Previous() в модели common\models\Post.

public function Previous()
{
  $a = [];
  $previous = $this->previous;
  while($previous)
  {
    $post = static::findOne($previous);
    $a[] = $post->getTitleLink();
    $previous = $post->previous;
  }
  if($a)
    return $a;
  elseif($post = static::find()
    ->where('status=' . self::STATUS_PUBLISHED . ' AND id<>' . $this->id)
    ->orderBy('created_at DESC')
    ->one()
  )
    return $post->getTitleLink();
  return '';
}

Теперь будем возвращать массив ссылок на заголовки статей, если это статьи по теме и просто ссылку (строку) на статью, если это предыдущая статья из блога.

Тогда и во frontend/views/post/view.php нужно добавить сравнение и обработку вывода ссылки на просто статью.

<?php if($links = $data->Previous() && is_array($links)): ?>
  <?php foreach($links as $link): ?>
    <p><?php echo $link; ?></p>
  <?php endforeach; ?>
<?php elseif($link = $links): ?>
  <p><?php echo $link; ?></p>
<?php endif; ?>

Очевидно, что аналогичные действия нужно выполнить и для следующих статей.

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

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

Добавим в модель common/modelsPost валидатор, который будет предотвращать возникновение этой проблемы.

public function already_selected($attribute, $params)
{
  if($this->$attribute && $this->find($attribute . '=' . $this->$attribute . 
    ($this->id ? ' and id<>' . $this->id : '')
  ))
    $this->addError($attribute, $params['message']);
}

И дополним правила проверки для модели.

public function rules()
{
  return array(
    ...
    [['previous', 'rubric'], 'integer'],
    ['previous', 'already_selected', 'message' => 'This article is already selected as the previous one.'],
    ...

Заключение

Рубрикатор хороший механизм для поиска статей, но имеет свои недостатки. Цепочки статей позволяют точно определять статьи относящиеся к теме.

Оставьте комментарий