Esempio n. 1
0
 /**
  * Renders values as JSON
  *
  * @todo   Determine what use case exists for accepting only $nameOrModel
  * @param  string|Model $nameOrModel The script/resource process, or a view model
  * @param  null|array|\ArrayAccess $values Values to use during rendering
  * @throws Exception\InvalidArgumentException
  * @return string The script output.
  */
 public function render($nameOrModel, $values = null)
 {
     if ($nameOrModel instanceof Model) {
         // Use case 1: View Model provided
         // Non-FeedModel: cast to FeedModel
         if (!$nameOrModel instanceof FeedModel) {
             $vars = $nameOrModel->getVariables();
             $options = $nameOrModel->getOptions();
             $type = $this->getFeedType();
             if (isset($options['feed_type'])) {
                 $type = $options['feed_type'];
             } else {
                 $this->setFeedType($type);
             }
             $nameOrModel = new FeedModel($vars, array('feed_type' => $type));
         }
     } elseif (is_string($nameOrModel)) {
         // Use case 2: string $nameOrModel + array|Traversable|Feed $values
         $nameOrModel = new FeedModel($values, (array) $nameOrModel);
     } else {
         // Use case 3: failure
         throw new Exception\InvalidArgumentException(sprintf('%s expects a ViewModel or a string feed type as the first argument; received "%s"', __METHOD__, is_object($nameOrModel) ? get_class($nameOrModel) : gettype($nameOrModel)));
     }
     // Get feed and type
     $feed = $nameOrModel->getFeed();
     $type = $nameOrModel->getFeedType();
     if (!$type) {
         $type = $this->getFeedType();
     } else {
         $this->setFeedType($type);
     }
     // Render feed
     return $feed->export($type);
 }
Esempio n. 2
0
 /**
  * Render values as XML
  *
  * @param  string|ModelInterface $nameOrModel The script/resource process, or a view model
  * @param  null|array|\ArrayAccess $values Values to use during rendering
  * @return string The script output.
  */
 public function render($nameOrModel, $values = null)
 {
     if ($nameOrModel instanceof XmlModel) {
         return $nameOrModel->serialize();
     }
     // use case 3: Both $nameOrModel and $values are populated
     throw new Exception\DomainException(sprintf('%s: Do not know how to handle operation when both $nameOrModel and $values are populated', __METHOD__));
 }
Esempio n. 3
0
 /**
  * Renders values as Icalendar
  *
  * @param string|\Zend\View\Model\ModelInterface $oNameOrModel : the script/resource process, or a view model
  * @param null|array|\ArrayAccess $aValues : values to use during rendering
  *
  * @throws \DomainException
  * @return string The script output.
  */
 public function render($oNameOrModel, $aValues = null)
 {
     // Use case 1: View Models
     // Serialize variables in view model
     if (!$oNameOrModel instanceof IcalendarModel) {
         throw new \DomainException(__METHOD__ . ': Do not know how to handle operation when both $oNameOrModel and $aValues are populated');
     }
     return $oNameOrModel->serialize();
 }
 /**
  * @param ModelInterface $viewModel
  * @param callable $addToViewFromModel
  */
 protected function addChildrenToView(ModelInterface $viewModel, $addToViewFromModel)
 {
     if ($viewModel->hasChildren()) {
         foreach ($viewModel->getChildren() as $child) {
             $addToViewFromModel($child);
             $this->addChildrenToView($child, $addToViewFromModel);
         }
     }
 }
Esempio n. 5
0
 /**
  * @return mixed
  */
 public function notFoundByRequestedCriteria($criteriaErrors)
 {
     $zendResponse = $this->mvcEvent->getResponse();
     $zendResponse->setStatusCode(404);
     $this->viewModel->setVariable('message', 'The requested resource was not found by requested criteria');
     $this->viewModel->setTemplate('error/404');
     $this->mvcEvent->setResult($this->viewModel);
     return $this->viewModel;
 }
 /**
  * @param  string|\Zend\View\Model\ModelInterface $nameOrModel
  * @param  array|null $values
  * @return string
  */
 public function render($nameOrModel, $values = null)
 {
     if (!$nameOrModel instanceof ApiProblemModel) {
         return '';
     }
     $apiProblem = $nameOrModel->getApiProblem();
     if ($this->displayExceptions) {
         $apiProblem->setDetailIncludesStackTrace(true);
     }
     return parent::render($apiProblem->toArray());
 }
Esempio n. 7
0
 /**
  * Render the provided model.
  *
  * @param ModelInterface $model
  * @return string
  */
 public function render(ModelInterface $model)
 {
     if ($this->layout && !$model->terminate()) {
         $this->layout->addChild($model);
         $model = $this->layout;
     }
     // hack, force ZendView to return its output instead of triggering an event
     // see: http://mateusztymek.pl/blog/using-standalone-zend-view
     $model->setOption('has_parent', true);
     return $this->zendView->render($model);
 }
Esempio n. 8
0
 /**
  * Processes a view script and returns the output.
  *
  * @param  string|ModelInterface   $nameOrModel The script/resource process, or a view model
  * @param  null|array|\ArrayAccess $values      Values to use during rendering
  * @return string The script output.
  * @throws \LogicException
  */
 public function render($nameOrModel, $values = null)
 {
     $name = $nameOrModel;
     if ($nameOrModel instanceof ModelInterface) {
         $name = $this->resolver->resolve($nameOrModel->getTemplate(), $this);
         $values = (array) $nameOrModel->getVariables();
     }
     if (array_key_exists('helper', $values)) {
         throw new \LogicException('Variable $helper is reserved for Zend helpers and can\'t be passed to view.');
     }
     $values['helper'] = $this->helpers;
     return $this->engine->renderToString($name, $values);
 }
Esempio n. 9
0
 /**
  *
  * @param ModelInterface $model
  */
 protected function renderChildren(ModelInterface $model)
 {
     foreach ($model->getChildren() as $child) {
         $result = $this->render($child);
         $capture = $child->captureTo();
         if (!empty($capture)) {
             if ($child->isAppend()) {
                 $oldResult = $model->{$capture};
                 $model->setVariable($capture, $oldResult . $result);
             } else {
                 $model->setVariable($capture, $result);
             }
         }
     }
 }
Esempio n. 10
0
 /**
  * @param string|ModelInterface $nameOrModel
  * @param null                  $values
  * @return string|void
  */
 public function render($nameOrModel, $values = null)
 {
     if ($nameOrModel instanceof CacheModel) {
         $key = $nameOrModel->getCacheKey();
         if (false === $nameOrModel->getIsFetchable()) {
             $cacheService = $this->getCacheService($key);
             $result = $this->getDefaultPhpRenderer()->render($nameOrModel, $values = null);
             $cacheService->setItem($key, $result);
             return $result;
         } else {
             return $nameOrModel->getContent();
         }
     }
     return $this->getDefaultPhpRenderer()->render($nameOrModel, $values = null);
 }
Esempio n. 11
0
 /**
  * Processes a view script and returns the output.
  *
  * @param  string|ModelInterface $nameOrModel The script/resource process, or a view model
  * @param  null|array|\ArrayAccess $values Values to use during rendering
  * @return string The script output.
  */
 public function render($nameOrModel, $values = null)
 {
     /** @var  $nameOrModel \Stjornvisi\View\Model\CsvModel */
     $csv = $nameOrModel->getData();
     /** @var $csv \Stjornvisi\Lib\Csv */
     $string = implode(",", array_map(function ($data) {
         return "\"" . addslashes($data) . "\"";
     }, $csv->getHeader())) . PHP_EOL;
     foreach ($csv as $item) {
         $string .= implode(",", array_map(function ($data) {
             return "\"" . addslashes($data) . "\"";
         }, $item));
         $string .= PHP_EOL;
     }
     return $string;
 }
 /**
  * @param \Zend\View\Model\ModelInterface $oViewModel
  * @throws \DomainException
  * @return \BoilerAppMessenger\Media\Mail\MailMessageRenderer
  */
 protected function renderChildren(\Zend\View\Model\ModelInterface $oViewModel)
 {
     foreach ($oViewModel as $oChild) {
         if ($oChild->terminate()) {
             throw new \DomainException('Inconsistent state; child view model is marked as terminal');
         }
         $oChild->setOption('has_parent', true);
         $sResult = $this->renderChildren($oChild)->render($oChild);
         $oChild->setOption('has_parent', null);
         $sCapture = $oChild->captureTo();
         if (!empty($sCapture)) {
             $oViewModel->setVariable($sCapture, $oChild->isAppend() ? $oViewModel->{$sCapture} . $sResult : $sResult);
         }
     }
     return $this;
 }
Esempio n. 13
0
 /**
  * Recursively processes all ViewModels and returns output.
  *
  * @param string|ModelInterface $model A ViewModel instance.
  * @param null|array|\Traversable $values Values to use when rendering. If
  *     none provided, uses those in the composed variables container.
  * @return string Console output.
  */
 public function render($model, $values = null)
 {
     $result = '';
     if (!$model instanceof ModelInterface) {
         // View model is required by this renderer
         return $result;
     }
     // If option keys match setters, pass values to those methods.
     foreach ($model->getOptions() as $setting => $value) {
         $method = 'set' . $setting;
         if (method_exists($this, $method)) {
             $this->{$method}($value);
         }
     }
     // Render children first
     if ($model->hasChildren()) {
         // recursively render all children
         foreach ($model->getChildren() as $child) {
             $result .= $this->render($child, $values);
         }
     }
     // Render the result, if present.
     $values = $model->getVariables();
     if (isset($values['result']) && !isset($this->filterChain)) {
         // append the result verbatim
         $result .= $values['result'];
     }
     if (isset($values['result']) && isset($this->filterChain)) {
         // filter and append the result
         $result .= $this->getFilterChain()->filter($values['result']);
     }
     return $result;
 }
Esempio n. 14
0
 /**
  * Renders values as a PDF
  *
  * @param string|ModelInterface|PdfModel $nameOrModel
  * @param  null|array|\ArrayAccess Values to use during rendering
  * @return string The script output.
  */
 public function render($nameOrModel, $values = null)
 {
     $pdfOptions = $nameOrModel->getPdfOptions();
     $paperSize = explode(',', $pdfOptions->getPaperSize());
     $paperOrientation = $pdfOptions->getPaperOrientation();
     $basePath = $pdfOptions->getBasePath();
     $paperSize = count($paperSize) === 1 ? $paperSize[0] : $paperSize;
     $pdf = $this->getEngine();
     $pdf->setPaper($paperSize, $paperOrientation);
     $pdf->setBasePath($basePath);
     $html = $this->getHtmlRenderer()->render($nameOrModel, $values);
     $pdf->loadHtml($html);
     $pdf->render();
     $pdf = $this->processHeader($pdf, $pdfOptions);
     $pdf = $this->processFooter($pdf, $pdfOptions);
     return $pdf->output();
 }
Esempio n. 15
0
 /**
  * Determine the response content-type to return based on the view model.
  *
  * @param ApiProblemModel|HalJsonModel|\Zend\View\Model\ModelInterface $model
  * @return string The content-type to use.
  */
 private function getContentTypeFromModel($model)
 {
     if ($model instanceof ApiProblemModel) {
         return 'application/problem+json';
     }
     if ($model instanceof HalJsonModel && ($model->isCollection() || $model->isEntity())) {
         return 'application/hal+json';
     }
     return $this->contentType;
 }
Esempio n. 16
0
 /**
  * Processes a view script and returns the output.
  *
  * @param  string|ModelInterface $nameOrModel The script/resource process, or a view model
  * @param  null|array|\ArrayAccess $values Values to use during rendering
  * @return string The script output.
  */
 public function render($nameOrModel, $values = null)
 {
     $string = "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//hacksw/handcal//NONSGML v1.0//EN\n";
     foreach ($nameOrModel->getVariable('events') as $event) {
         $string .= "BEGIN:VEVENT\n";
         $string .= "UID:{$event->id}@stjornvisi.is\n";
         $string .= "DTSTART:{$event->event_time->format('Ymd\\THis')}\n";
         $string .= "DTEND:{$event->event_end->format('Ymd\\THis')}\n";
         if ($event->lat && $event->lng) {
             $string .= "GEO:{$event->lat};{$event->lng}\n";
         }
         $string .= "LOCATION:{$event->location}\n";
         $string .= "ORGANIZER;CN=\"" . ($event->groups ? implode(', ', array_map(function ($g) {
             return $g->name;
         }, $event->groups)) : 'Stjónvísisviðburður') . "\":no-reply@stjornvisi.is\n";
         $string .= "LOCATION:{$event->location}\n";
         $string .= "URL:http://{$_SERVER['SERVER_NAME']}/vidburdir/{$event->id}\n";
         $string .= "SUMMARY:{$event->subject}\n";
         $string .= "END:VEVENT\n";
     }
     $string .= "END:VCALENDAR";
     return $string;
 }
Esempio n. 17
0
 /**
  * @inheritDoc
  */
 public function configure(ModelInterface $block, array $specs)
 {
     $specs = $this->prepareOptions($specs);
     foreach ($this->getOption('options', $specs) as $name => $option) {
         $block->setOption($name, $option);
     }
     foreach ($this->getOption('variables', $specs) as $name => $variable) {
         $block->setVariable($name, $variable);
     }
     foreach ($this->getOption('actions', $specs) as $params) {
         if (isset($params['method'])) {
             $method = (string) $params['method'];
             if (method_exists($block, $method)) {
                 $this->invokeArgs($block, $method, $params);
             } else {
                 throw new BadMethodCallException(sprintf('Call to undefined block method %s::%s()', get_class($block), $method));
             }
         }
     }
     if (!$block->getTemplate() && ($template = $this->getOption('template', $specs))) {
         $block->setTemplate($template);
     }
     $block->setCaptureTo($this->getOption('capture_to', $specs));
     $block->setAppend($this->getOption('append', $specs));
     $block->setVariable('block', $block);
     if ($block instanceof BlockInterface) {
         $block->setView($this->container->get('ViewRenderer'));
         $block->setRequest($this->container->get('Request'));
     }
     $results = $this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, ['block' => $block, 'specs' => $specs], function ($result) {
         return $result instanceof ModelInterface;
     });
     if ($results->stopped()) {
         $block = $results->last();
     }
     return $block;
 }
Esempio n. 18
0
 /**
  * @param MvcEvent $e
  * @return mixed|\Zend\Http\Response|ViewModelInterface
  */
 public function onDispatch(MvcEvent $e)
 {
     if (!empty($this->options['allowedMethods']) && !in_array($this->sebaksRequest->getMethod(), $this->options['allowedMethods'])) {
         return $this->error->methodNotAllowed();
     }
     $e->setParam('sebaksRequest', $this->sebaksRequest);
     $e->setParam('sebaksResponse', $this->sebaksResponse);
     $routeName = $e->getRouteMatch()->getMatchedRouteName();
     $this->getEventManager()->trigger("dispatch.{$routeName}.pre", $e);
     $this->controller->dispatch($this->sebaksRequest, $this->sebaksResponse);
     $this->getEventManager()->trigger("dispatch.{$routeName}.post", $e);
     $criteriaErrors = $this->sebaksResponse->getCriteriaErrors();
     if (!empty($criteriaErrors)) {
         return $this->error->notFoundByRequestedCriteria($criteriaErrors);
     }
     $changesErrors = $this->sebaksResponse->getChangesErrors();
     $redirectTo = $this->sebaksResponse->getRedirectTo();
     if (empty($changesErrors) && !empty($redirectTo)) {
         if (is_array($redirectTo)) {
             if (!isset($redirectTo['route'])) {
                 throw new \RuntimeException('Missing required parameter route');
             }
             $routeParams = isset($redirectTo['params']) ? $redirectTo['params'] : [];
             $routeOptions = isset($redirectTo['options']) ? $redirectTo['options'] : [];
             return $this->redirect()->toRoute($redirectTo['route'], $routeParams, $routeOptions);
         } else {
             return $this->redirect()->toRoute($redirectTo);
         }
     }
     if (!empty($changesErrors)) {
         $result = $this->error->changesErrors($changesErrors);
         if ($result instanceof Response) {
             return $result;
         }
     }
     $this->viewModel->setVariables($this->sebaksResponse->toArray());
     $e->setResult($this->viewModel);
     return $this->viewModel;
 }
Esempio n. 19
0
 /**
  * @param ModelInterface $block
  * @return mixed|string
  */
 private function determineAnonymousBlockId(ModelInterface $block)
 {
     $blockId = $block->getOption('block_id');
     if (!$blockId) {
         $blockId = sprintf(self::ANONYMOUS_ID_PATTERN, $block->captureTo(), self::$anonymousSuffix++);
         $block->setOption('block_id', $blockId);
     }
     return $blockId;
 }
 /**
  * Recursively search a view model and it's children for the given templateName
  *
  * @param  \Zend\View\Model\ModelInterface $viewModel
  * @param  string    $templateName
  * @return boolean
  */
 protected function searchTemplates($viewModel, $templateName)
 {
     if ($viewModel->getTemplate($templateName) == $templateName) {
         return true;
     }
     foreach ($viewModel->getChildren() as $child) {
         return $this->searchTemplates($child, $templateName);
     }
     return false;
 }
Esempio n. 21
0
 /**
  * retrieve parent and capture_to as array, e.g.: [ 'layout', 'content' ]
  * so we are able to list() block_id and capture_to values
  *
  * @param   ModelInterface  $block
  * @return  array
  */
 protected function getCaptureTo(ModelInterface $block)
 {
     $captureTo = $block->captureTo();
     if ($parent = $block->getOption('parent')) {
         $captureTo = explode(self::CAPTURE_TO_DELIMITER, $captureTo);
         return [$parent, end($captureTo)];
     }
     if (false !== strpos($captureTo, self::CAPTURE_TO_DELIMITER)) {
         return explode(self::CAPTURE_TO_DELIMITER, $captureTo);
     }
     return [self::BLOCK_ID_ROOT, $captureTo];
 }
 /**
  * Inject discovered child model values into parent model
  *
  * @todo   detect collisions and decide whether to append and/or aggregate?
  * @param  Model $model
  * @param  array $children
  */
 protected function injectChildren(Model $model, array $children)
 {
     foreach ($children as $child => $value) {
         // TODO detect collisions and decide whether to append and/or aggregate?
         $model->setVariable($child, $value);
     }
 }
Esempio n. 23
0
 /**
  * Add a child model
  *
  * @param  ModelInterface $child
  * @param  null|string $captureTo Optional; if specified, the "capture to" value to set on the child
  * @param  null|bool $append Optional; if specified, append to child  with the same capture
  * @return ViewModel
  */
 public function addChild(ModelInterface $child, $captureTo = null, $append = null)
 {
     $this->children[] = $child;
     if (null !== $captureTo) {
         $child->setCaptureTo($captureTo);
     }
     if (null !== $append) {
         $child->setAppend($append);
     }
     return $this;
 }
Esempio n. 24
0
 /**
  * Recursively processes all ViewModels and returns output.
  *
  * @param  string|ModelInterface   $model        A ViewModel instance.
  * @param  null|array|\Traversable $values       Values to use when rendering. If none
  *                                               provided, uses those in the composed
  *                                               variables container.
  * @return string Console output.
  */
 public function render($model, $values = null)
 {
     if (!$model instanceof ModelInterface) {
         return '';
     }
     $result = '';
     $options = $model->getOptions();
     foreach ($options as $setting => $value) {
         $method = 'set' . $setting;
         if (method_exists($this, $method)) {
             $this->{$method}($value);
         }
         unset($method, $setting, $value);
     }
     unset($options);
     $values = $model->getVariables();
     if (isset($values['result'])) {
         // filter and append the result
         $result .= $this->getFilterChain()->filter($values['result']);
     }
     if ($model->hasChildren()) {
         // recursively render all children
         foreach ($model->getChildren() as $child) {
             $result .= $this->render($child, $values);
         }
     }
     return $result;
 }
Esempio n. 25
0
 /**
  *
  * @param ViewModel $block
  * @return string
  */
 protected function determineAnonymousBlockId(ModelInterface $block)
 {
     $blockId = $block->getVariable(self::BLOCK_ID_VAR);
     if (!$blockId) {
         $blockId = sprintf(self::ANONYMOUS_ID_PATTERN, $block->captureTo(), self::$anonymousSuffix++);
         $block->setVariable(self::BLOCK_ID_VAR, $blockId);
     }
     return $blockId;
 }
Esempio n. 26
0
 /**
  * Retrieve values from a model and recurse its children to build a data structure
  *
  * @param  Model $model
  * @return array
  */
 protected function recurseModel(Model $model)
 {
     $values = $model->getVariables();
     if ($values instanceof Traversable) {
         $values = ArrayUtils::iteratorToArray($values);
     }
     if (!$model->hasChildren()) {
         return $values;
     }
     $mergeChildren = $this->mergeUnnamedChildren();
     foreach ($model as $child) {
         $captureTo = $child->captureTo();
         if (!$captureTo && !$mergeChildren) {
             // We don't want to do anything with this child
             continue;
         }
         $childValues = $this->recurseModel($child);
         if ($captureTo) {
             // Capturing to a specific key
             //TODO please complete if append is true. must change old value to array and append to array?
             $values[$captureTo] = $childValues;
         } elseif ($mergeChildren) {
             // Merging values with parent
             $values = array_replace_recursive($values, $childValues);
         }
     }
     return $values;
 }
Esempio n. 27
0
 /**
  * Populate the view model returned by the AcceptableViewModelSelector from the result
  *
  * If the result is a ViewModel, we "re-cast" it by copying over all
  * values/settings/etc from the original.
  *
  * If the result is an array, we pass those values as the view model variables.
  *
  * @param  array|ViewModel $result
  * @param  ViewModelInterface $viewModel
  * @param  MvcEvent $e
  */
 protected function populateViewModel($result, ViewModelInterface $viewModel, MvcEvent $e)
 {
     if ($result instanceof ViewModel) {
         // "Re-cast" content-negotiation view models to the view model type
         // selected by the AcceptableViewModelSelector
         $viewModel->setVariables($result->getVariables());
         $viewModel->setTemplate($result->getTemplate());
         $viewModel->setOptions($result->getOptions());
         $viewModel->setCaptureTo($result->captureTo());
         $viewModel->setTerminal($result->terminate());
         $viewModel->setAppend($result->isAppend());
         if ($result->hasChildren()) {
             foreach ($result->getChildren() as $child) {
                 $viewModel->addChild($child);
             }
         }
         $e->setResult($viewModel);
         return;
     }
     // At this point, the result is an array; use it to populate the view
     // model variables
     $viewModel->setVariables($result);
     $e->setResult($viewModel);
 }
Esempio n. 28
0
 /**
  * assign wrapper template to block
  *
  * @param ModelInterface $block
  * @param array|string $options
  */
 protected function wrapBlock(ModelInterface $block, $options)
 {
     $attributes = $options;
     if (is_string($options)) {
         $wrapperTemplate = $options;
         $attributes = [];
     } elseif (is_array($options) && !isset($options['template'])) {
         $wrapperTemplate = self::WRAPPER_DEFAULT;
     } else {
         $wrapperTemplate = $options['template'];
         unset($attributes['template']);
     }
     if (isset($options['tag'])) {
         $block->setVariable('wrapperTag', $options['tag']);
         unset($attributes['tag']);
     }
     $originalTemplate = $block->getTemplate();
     $block->setOption('is_wrapped', true);
     $block->setTemplate($wrapperTemplate);
     $block->setVariable('wrapperAttributes', $attributes);
     $block->setVariable('originalTemplate', $originalTemplate);
 }
Esempio n. 29
0
 /**
  * Loop through children, rendering each
  *
  * @param  Model $model
  * @throws Exception\DomainException
  * @return void
  */
 protected function renderChildren(Model $model)
 {
     foreach ($model as $child) {
         if ($child->terminate()) {
             throw new Exception\DomainException('Inconsistent state; child view model is marked as terminal');
         }
         $child->setOption('has_parent', true);
         $result = $this->render($child);
         $child->setOption('has_parent', null);
         $capture = $child->captureTo();
         if (!empty($capture)) {
             if ($child->isAppend()) {
                 $oldResult = $model->{$capture};
                 $model->setVariable($capture, $oldResult . $result);
             } else {
                 $model->setVariable($capture, $result);
             }
         }
     }
 }
 /**
  * Do a recursive, depth-first rendering of a view model.
  *
  * @param ModelInterface $model
  * @param RendererInterface $renderer
  * @return string
  * @throws Exception\RenderingException if it encounters a terminal child.
  */
 private function renderModel(ModelInterface $model, RendererInterface $renderer)
 {
     foreach ($model as $child) {
         if ($child->terminate()) {
             throw new Exception\RenderingException('Cannot render; encountered a child marked terminal');
         }
         $capture = $child->captureTo();
         if (empty($capture)) {
             continue;
         }
         $result = $this->renderModel($child, $renderer);
         if ($child->isAppend()) {
             $oldResult = $model->{$capture};
             $model->setVariable($capture, $oldResult . $result);
             continue;
         }
         $model->setVariable($capture, $result);
     }
     return $renderer->render($model);
 }