Блог Статьи

InstantCMS 2.7 — делаем несколько страниц с опциями в админке компонента

Система управления контентом InstantCMS 2.7 содержит в себе ряд уже готовой функциональности для облегчения процесса создания компонента. Есть готовый механизм построителя форм, есть механизм событий (hooks), можно создавать собственные объекты на уровне движка, есть даже бесплатный компонент для создания компонентов и многое другое.

Однако, как и у любой CMS всегда найдутся вещи, которые можно «допилить». И в рамках данной статьи я расскажу как можно сделать несколько страниц с опциями в админке компонента.

Если вы смотрели хотя бы видео-туториалы, то могли отметить, что есть неплохая задумка для быстрой организации страницы с настройками компонента. Достаточно создать файл с настройками формы, создать файл шаблона и указать в контроллере backend параметр:

public $useDefaultOptionsAction = true;

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

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

И сделать это на самом деле очень просто. Дело в том, что в ядре InstantCMS есть уже почти готовая функция (Сама функция называется «actionOptions») и настройки компонента она сохраняет методом добавления и перезаписи. Проще говоря, перед сохранением используется следующий код:

$options = array_merge( $options, $form->parse($this->request, true) );

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

protected function _actionOptions($actionAndFormName){
    // Эта строчка не нужна
    //if (empty($this->useDefaultOptionsAction)){ cmsCore::error404(); }

    // Тут заменяем конкретное имя формы на параметр $actionAndFormName
    //$form = $this->getForm('options');
    $form = $this->getForm($actionAndFormName);

    if (!$form) { cmsCore::error404(); }

    $form = $this->addControllerSeoOptions($form);

    $options = cmsController::loadOptions($this->name);

    if ($this->request->has('submit')){

        $options = array_merge( $options, $form->parse($this->request, true) );
        $errors  = $form->validate($this, $options);

        if (!$errors){

            cmsUser::addSessionMessage(LANG_CP_SAVE_SUCCESS, 'success');

            cmsController::saveOptions($this->name, $options);

            $this->processCallback(__FUNCTION__, array($options));

            // Заменяем указание возврата
            //$this->redirectToAction('options');
            $this->redirectToAction($actionAndFormName);

        }

        if ($errors){

            cmsUser::addSessionMessage(LANG_FORM_ERRORS, 'error');

        }

    }

    $template_params = array(
        'toolbar' => $this->getOptionsToolbar(),
        'options' => $options,
        'form'    => $form,
        'errors'  => isset($errors) ? $errors : false
    );

    // Заменяем подгрузку файла шаблона
    // если задан шаблон опций в контроллере
    //if($this->cms_template->getTemplateFileName('controllers/'.$this->name.'/backend/options', true)){
    if($this->cms_template->getTemplateFileName('controllers/'.$this->name.'/backend/' . $actionAndFormName, true)){

        // Заменяем указание рендера
        //return $this->cms_template->render('backend/options', $template_params);
        return $this->cms_template->render('backend/' . $actionAndFormName, $template_params);

    } else {
        // Оставляем как есть, так как стандартная форма используется одна и та же
        $default_admin_tpl = $this->cms_template->getTemplateFileName('controllers/admin/controllers_options');

        return $this->cms_template->processRender($default_admin_tpl, $template_params);

    }

}

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

public function actionPage1() {
  return $this->_actionOptions('page1');
}

public function actionPage2() {
  return $this->_actionOptions('page2');
}

public function actionPage3() {
  return $this->_actionOptions('page3');
}

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

  1. Разные формы могут позволять редактировать одни и те же настройки
  2. Вы можете добавлять свои дополнительные проверки при выполнении действий. К примеру, сохранять или подгружать часть данных из собственных таблиц
  3. Добавлять свои сообщения при сохранении данных