Редирект на дочернюю страницу

В некоторых случаях не требуется показывать пользователю содержимое страницы, а перенаправить  его на какую-то другую; например, если корневая страница раздела не содержит информации.

Обычно для этого используют макрос %content redirect()%, указывая в параметре путь к целевой странице или id.

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

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

Было бы удобно иметь навигацию в стиле DOM - метод getFirstChild() - получить первый дочерний элемент. Сделаем это.

В /classes/content/__custom.php создаем методы:

public function getFirst($id = false){
  if(!$id) return NULL;
  $sel = new umiSelection();
  $sel -> addHierarchyFilter($id, 0);
  $sel->forceHierarchyTable();
  $sel->addLimit(1);
 
  $sel->setOrderByOrd();
  $sel->addActiveFilter(true);
  $result = umiSelectionsParser::runSelection($sel);
 
  if(!$result) return NULL;
  if(!isset($result[0])) return NULL;
  return $result[0]; 
 }
 

Здесь все просто. Выбираем первую активную дочернюю страницу и возвращаем ее id

 

2) собственно редирект

 public function redirectFirst($id = false){
  if(!$id) return NULL;
  if(!$first = self::getFirst($id)) return null;
  $this -> redirect($first);
 }

Теперь создаем шаблон в котором записваем макрос %content redirctFirst(%pid%)%

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

Естественно, не надо забывать, что при этом генерируются дополнительные запросы к базе

 

 

Аналогичный код с использованием нового класса selector. Класс selector работает быстрее прежнего umiSelection, поэтому рекомендую везде использовать именно его, если вам не важна совместимость с более древними версиями ЮМИ

public function top_banners_add($pid = false){
  if(!$pid) return '';
  $pages = new selector('pages'); 
  $pages->where('is_active')->equals(1);
  $pages->where('hierarchy')->page($pid)->childs(1);
  $pages->limit(0,1);
  $result = $pages->result();
 
  if(sizeof($result)){
    $el = $result[0];
    if(!$el->getIsActive()) return '';
      $result = что-то делаем
      return $result;
    }
    return '';
 }