@@ -109,7 +109,7 @@ public function __construct(RendererInterface $renderer = null, $layout = null)
109
109
*
110
110
* If a layout was specified during construction, it will be used;
111
111
* alternately, you can specify a layout to use via the "layout"
112
- * parameter, using either:
112
+ * parameter/variable , using either:
113
113
*
114
114
* - a string layout template name
115
115
* - a Zend\View\Model\ModelInterface instance
@@ -118,16 +118,18 @@ public function __construct(RendererInterface $renderer = null, $layout = null)
118
118
* the constructor.
119
119
*
120
120
* @param string $name
121
- * @param array|object $params
121
+ * @param array|ModelInterface| object $params
122
122
* @return string
123
123
*/
124
124
public function render ($ name , $ params = [])
125
125
{
126
- $ params = $ this ->mergeParams ($ name , $ this ->normalizeParams ($ params ));
127
- return $ this ->renderModel (
128
- $ this ->createModel ($ name , $ params ),
129
- $ this ->renderer
130
- );
126
+ $ viewModel = ($ params instanceof ModelInterface)
127
+ ? $ this ->mergeViewModel ($ name , $ params )
128
+ : $ this ->createModel ($ name , $ params );
129
+
130
+ $ viewModel = $ this ->prepareLayout ($ viewModel );
131
+
132
+ return $ this ->renderModel ($ viewModel , $ this ->renderer );
131
133
}
132
134
133
135
/**
@@ -169,43 +171,15 @@ public function getPaths()
169
171
/**
170
172
* Create a view model from the template and parameters.
171
173
*
172
- * Injects the created model in the layout view model, if present.
173
- *
174
- * If the $params contains a non-empty 'layout' key, that value will
175
- * be used to seed a layout view model, if:
176
- *
177
- * - it is a string layout template name
178
- * - it is a ModelInterface instance
179
- *
180
- * If a layout is discovered in this way, it will override the one set in
181
- * the constructor, if any.
182
- *
183
174
* @param string $name
184
- * @param array $params
175
+ * @param mixed $params
185
176
* @return ModelInterface
186
177
*/
187
- private function createModel ($ name , array $ params )
178
+ private function createModel ($ name , $ params )
188
179
{
189
- $ layout = $ this ->layout ? clone $ this ->layout : null ;
190
- if (array_key_exists ('layout ' , $ params ) && $ params ['layout ' ]) {
191
- if (is_string ($ params ['layout ' ])) {
192
- $ layout = new ViewModel ();
193
- $ layout ->setTemplate ($ params ['layout ' ]);
194
- unset($ params ['layout ' ]);
195
- } elseif ($ params ['layout ' ] instanceof ModelInterface) {
196
- $ layout = $ params ['layout ' ];
197
- unset($ params ['layout ' ]);
198
- }
199
- }
200
-
201
- $ model = new ViewModel ($ params );
180
+ $ params = $ this ->mergeParams ($ name , $ this ->normalizeParams ($ params ));
181
+ $ model = new ViewModel ($ params );
202
182
$ model ->setTemplate ($ name );
203
-
204
- if ($ layout ) {
205
- $ layout ->addChild ($ model );
206
- $ model = $ layout ;
207
- }
208
-
209
183
return $ model ;
210
184
}
211
185
@@ -306,4 +280,62 @@ private function getNamespacedResolver(AggregateResolver $aggregate)
306
280
}
307
281
}
308
282
}
283
+
284
+ /**
285
+ * Merge global/template parameters with provided view model.
286
+ *
287
+ * @param string $name Template name.
288
+ * @param ModelInterface $model
289
+ * @return ModelInterface
290
+ */
291
+ private function mergeViewModel ($ name , ModelInterface $ model )
292
+ {
293
+ $ params = $ this ->mergeParams ($ name , $ model ->getVariables ());
294
+ $ model ->setVariables ($ params );
295
+ $ model ->setTemplate ($ name );
296
+ return $ model ;
297
+ }
298
+
299
+ /**
300
+ * Prepare the layout, if any.
301
+ *
302
+ * Injects the view model in the layout view model, if present.
303
+ *
304
+ * If the view model contains a non-empty 'layout' variable, that value
305
+ * will be used to seed a layout view model, if:
306
+ *
307
+ * - it is a string layout template name
308
+ * - it is a ModelInterface instance
309
+ *
310
+ * If a layout is discovered in this way, it will override the one set in
311
+ * the constructor, if any.
312
+ *
313
+ * Returns the provided $viewModel unchanged if no layout is discovered;
314
+ * otherwise, a view model representing the layout, with the provided
315
+ * view model as a child, is returned.
316
+ *
317
+ * @param ModelInterface $viewModel
318
+ * @return ModelInterface
319
+ */
320
+ private function prepareLayout (ModelInterface $ viewModel )
321
+ {
322
+ $ layout = $ this ->layout ? clone $ this ->layout : null ;
323
+
324
+ $ providedLayout = $ viewModel ->getVariable ('layout ' , false );
325
+ if (is_string ($ providedLayout ) && ! empty ($ providedLayout )) {
326
+ $ layout = new ViewModel ();
327
+ $ layout ->setTemplate ($ providedLayout );
328
+ $ viewModel ->setVariable ('layout ' , null );
329
+ } elseif ($ providedLayout instanceof ModelInterface) {
330
+ $ layout = $ providedLayout ;
331
+ $ viewModel ->setVariable ('layout ' , null );
332
+ }
333
+
334
+ if ($ layout ) {
335
+ $ layout ->addChild ($ viewModel );
336
+ $ viewModel = $ layout ;
337
+ }
338
+
339
+ return $ viewModel ;
340
+ }
309
341
}
0 commit comments