Silverstripe Несколько пользовательских форм на одной странице

Я пытаюсь создать одну страницу, которая будет отображать несколько пользовательских форм в виде вкладок. Например, основная контактная форма, форма запроса предложения и т. Д.

Я думал, что могу создать новый тип страницы и перебирать дочерние элементы для отображения форм, но переменная $ Form не отображает форму.

<% loop $Children %>
   <div>
     <h2>$Title</h2>
     $Form
   </div>
<% end_loop %>

Мне что-то здесь не хватает, или есть другой способ визуализировать форму, используя ее идентификатор в файле шаблона?


person stillfire    schedule 19.01.2016    source источник
comment
Вы перебираете объекты DataObjects в этом контексте, а не классы контроллеров и их методы. Также заставить его работать несколько сложно: stackoverflow.com/questions/30404467/   -  person Olli Tyynelä    schedule 21.01.2016
comment
В зависимости от форм и их функций может быть проще просто добавить заполнители для них в циклы и использовать js для замены заполнителей на iframe, который расширяется до размера содержимого формы.   -  person Olli Tyynelä    schedule 21.01.2016


Ответы (3)


Вы можете попробовать следующее.

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

public function ChildForm($pageID) {
  $page = UserDefinedForm::get()->byID($pageID);
  $controller = UserDefinedForm_Controller::create($page);
  return $controller->Form();
}

впоследствии вы вызовете эту функцию в своем цикле и передадите ей текущий дочерний идентификатор

<% loop $Children %>
   <div>
     <h2>$Title</h2>
     $Top.ChildForm($ID)
   </div>
<% end_loop %>

Это должно (код не протестирован) вернуть нужные вам формы.

person csy_dot_io    schedule 21.01.2016

Проблема здесь в разнице между _1 _ / _ 2_ и Controller. Цикл по $Children возвращает DataObject, тогда как функция Form и переменная шаблона являются частью контроллера UserDefinedForm.

Другой ответ показывает одно рабочее решение, но на нем есть волосы:

  • Переход к контроллеру для передачи идентификатора для получения формы
  • Дополнительный запрос к БД
  • Требует, чтобы все дочерние страницы были типа UserDefinedForm

Мы можем реализовать более общее решение, которое удалит некоторые из этих элементов и сделает ваш код более удобным в сопровождении.

Возьмите следующее, которое будет добавлено к классу Page (не к контроллеру):

function getInLoopForm() {
    if (in_array('UserDefinedForm', $this->ClassAncestry)) {
        $controllerName = $this->ClassName . '_Controller';
        $controller = $controllerName::create($this);
        if ($controller->hasMethod('Form')) {
            return $controller->Form();
        }
    }
    return false;
}

Первая часть проверяет, имеет ли текущий объект UserDefinedForm в своем классе. Если это так, мы создаем соответствующий контроллер и возвращаем форму.

Вместо этого код вашего шаблона будет выглядеть так:

<% loop $Children %>
   <div>
     <h2>$Title</h2>
     $InLoopForm
   </div>
<% end_loop %>

Это решение является универсальным по трем причинам:

  • В нашей getInLoopForm функции значение UserDefinedForm можно заменить любым классом, расширяющим Page. Если бы вы были так склонны, его можно было бы даже довести до значения YML.
  • Для SilverStripe имена контроллеров для страниц должны соответствовать "{PageClassName} _Controller", чтобы мы могли злоупотреблять этим, динамически определяя имя контроллера. Это позволяет вам расширять UserDefinedForm и его контроллер, и мы по-прежнему можем вызывать нужную функцию.
  • Вам нужен только ваш DataObject для доступа к форме, вам не нужен собственный контроллер.
person Turnerj    schedule 18.07.2016
comment
Похоже, отличное решение. Как это будет работать в Silverstripe 4, когда вам нужно использовать пространства имен? заранее спасибо. - person luukgruijs; 14.03.2018

Для SS 4 необходимо небольшое изменение кода:

public function getInLoopForm() {
    if (in_array('SilverStripe\UserForms\Model\UserDefinedForm', $this->ClassAncestry)) {
        $controller = UserDefinedFormController::create($this);
        if ($controller->hasMethod('Form')) {
            return $controller->Form();
        }
    }
    return false;
}
person luukgruijs    schedule 14.03.2018