2016-01-19 7 views
4

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

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

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

Я что-то упустил или есть другой способ визуализации формы с использованием ее идентификатора в файле шаблона?

+0

Вы выполняете итерации над DataObjects в этом контексте, а не классы контроллера и их методы. Также получение его для работы несколько трико: http://stackoverflow.com/questions/30404467/silverstripe-rendering-a-userforms-page-type-in-a-template-loop –

+0

В зависимости от форм и их «функциональных возможностей», было бы проще «просто» просто добавить к ним заполнители для них и использовать js для замены заполнителей iframe, который расширяется до размера содержимого формы. –

ответ

4

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

Создайте функцию в контроллере владельца страницы, чтобы получить форму от определенного ребенка (должна быть страница 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 %> 

Это должно (код тестировался) возвращает форму, которые вы хотите.

+0

Прекрасно работает! – stillfire

3

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

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

  • Прыжки возможности для вашего контроллера, чтобы передать идентификатор, чтобы получить форму
  • Дополнительная DB запрос
  • требует, чтобы все детские страницы должны быть типа 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, вам не нужен ваш собственный контроллер.
Смежные вопросы