4746a48bff824d2dd5e83d0c72f244318145cff0
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Classes / ContentObject / FluidTemplateContentObject.php
1 <?php
2 namespace TYPO3\CMS\Frontend\ContentObject;
3
4 /**
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 /**
18 * Contains TEMPLATE class object.
19 *
20 * @author Xavier Perseguers <typo3@perseguers.ch>
21 * @author Steffen Kamper <steffen@typo3.org>
22 * @author Bastian Waidelich <bastian@typo3.org>
23 * @author Steffen Ritter <info@steffen-ritter.net>
24 * @author Benjamin Mack <benni@typo3.org>
25 */
26 class FluidTemplateContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractContentObject {
27
28 /**
29 * @var \TYPO3\CMS\Fluid\View\StandaloneView
30 */
31 protected $view = NULL;
32
33 /**
34 * Rendering the cObject, FLUIDTEMPLATE
35 *
36 * Configuration properties:
37 * - file string+stdWrap The FLUID template file
38 * - layoutRootPaths array of filepath+stdWrap Root paths to layouts (fallback)
39 * - partialRootPaths filepath+stdWrap Root paths to partials (fallback)
40 * - variable array of cObjects, the keys are the variable names in fluid
41 * - extbase.pluginName
42 * - extbase.controllerExtensionName
43 * - extbase.controllerName
44 * - extbase.controllerActionName
45 *
46 * Example:
47 * 10 = FLUIDTEMPLATE
48 * 10.template = FILE
49 * 10.template.file = fileadmin/templates/mytemplate.html
50 * 10.partialRootPaths.10 = fileadmin/templates/partial/
51 * 10.variables {
52 * mylabel = TEXT
53 * mylabel.value = Label from TypoScript coming
54 * }
55 *
56 * @param array $conf Array of TypoScript properties
57 * @return string The HTML output
58 */
59 public function render($conf = array()) {
60 $parentView = $this->view;
61 $this->initializeStandaloneViewInstance();
62
63 if (!is_array($conf)) {
64 $conf = array();
65 }
66
67 $this->setTemplate($conf);
68 $this->setLayoutRootPath($conf);
69 $this->setPartialRootPath($conf);
70 $this->setFormat($conf);
71 $this->setExtbaseVariables($conf);
72 $this->assignSettings($conf);
73 $this->assignContentObjectVariables($conf);
74 $this->assignContentObjectDataAndCurrent($conf);
75
76 $content = $this->renderFluidView();
77 $content = $this->applyStandardWrapToRenderedContent($content, $conf);
78
79 $this->view = $parentView;
80 return $content;
81 }
82
83 /**
84 * Creating standalone view instance must not be done in construct() as
85 * it can lead to a nasty cache issue since content object instances
86 * are not always re-created by the content object rendered for every
87 * usage, but can be re-used. Thus, we need a fresh instance of
88 * StandaloneView every time render() is called.
89 *
90 * @return void
91 */
92 protected function initializeStandaloneViewInstance() {
93 $this->view = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Fluid\\View\\StandaloneView');
94 }
95
96 /**
97 * Set template
98 *
99 * @param array $conf With possibly set file resource
100 * @return void
101 * @throws \InvalidArgumentException
102 */
103 protected function setTemplate(array $conf) {
104 // Fetch the Fluid template
105 if (!empty($conf['template']) && !empty($conf['template.'])) {
106 $templateSource = $this->cObj->cObjGetSingle($conf['template'], $conf['template.']);
107 $this->view->setTemplateSource($templateSource);
108 } else {
109 $file = isset($conf['file.']) ? $this->cObj->stdWrap($conf['file'], $conf['file.']) : $conf['file'];
110 /** @var $templateService \TYPO3\CMS\Core\TypoScript\TemplateService */
111 $templateService = $GLOBALS['TSFE']->tmpl;
112 $templatePathAndFilename = $templateService->getFileName($file);
113 $this->view->setTemplatePathAndFilename(PATH_site . $templatePathAndFilename);
114 }
115 }
116
117 /**
118 * Set layout root path if given in configuration
119 *
120 * @param array $conf Configuration array
121 * @return void
122 */
123 protected function setLayoutRootPath(array $conf) {
124 // Override the default layout path via typoscript
125 $layoutPaths = array();
126 if (isset($conf['layoutRootPath']) || isset($conf['layoutRootPath.'])) {
127 $layoutRootPath = isset($conf['layoutRootPath.'])
128 ? $this->cObj->stdWrap($conf['layoutRootPath'], $conf['layoutRootPath.'])
129 : $conf['layoutRootPath'];
130 $layoutPaths[] = \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName($layoutRootPath);
131 }
132 if (isset($conf['layoutRootPaths.'])) {
133 foreach ($conf['layoutRootPaths.'] as $key => $path) {
134 $layoutPaths[$key] = \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName($path);
135 }
136 }
137 if (!empty($layoutPaths)) {
138 $this->view->setLayoutRootPaths($layoutPaths);
139 }
140 }
141
142 /**
143 * Set partial root path if given in configuration
144 *
145 * @param array $conf Configuration array
146 * @return void
147 */
148 protected function setPartialRootPath(array $conf) {
149 $partialPaths = array();
150 if (isset($conf['partialRootPath']) || isset($conf['partialRootPath.'])) {
151 $partialRootPath = isset($conf['partialRootPath.'])
152 ? $this->cObj->stdWrap($conf['partialRootPath'], $conf['partialRootPath.'])
153 : $conf['partialRootPath'];
154 $partialPaths[] = \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName($partialRootPath);
155 }
156 if (isset($conf['partialRootPaths.'])) {
157 foreach ($conf['partialRootPaths.'] as $key => $path) {
158 $partialPaths[$key] = \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName($path);
159 }
160 }
161 if (!empty($partialPaths)) {
162 $this->view->setPartialRootPaths($partialPaths);
163 }
164 }
165
166 /**
167 * Set different format if given in configuration
168 *
169 * @param array $conf Configuration array
170 * @return void
171 */
172 protected function setFormat(array $conf) {
173 $format = isset($conf['format.']) ? $this->cObj->stdWrap($conf['format'], $conf['format.']) : $conf['format'];
174 if ($format) {
175 $this->view->setFormat($format);
176 }
177 }
178
179 /**
180 * Set some extbase variables if given
181 *
182 * @param array $conf Configuration array
183 * @return void
184 */
185 protected function setExtbaseVariables(array $conf) {
186 /** @var $request \TYPO3\CMS\Extbase\Mvc\Request */
187 $requestPluginName = isset($conf['extbase.']['pluginName.']) ? $this->cObj->stdWrap($conf['extbase.']['pluginName'], $conf['extbase.']['pluginName.']) : $conf['extbase.']['pluginName'];
188 if ($requestPluginName) {
189 $this->view->getRequest()->setPluginName($requestPluginName);
190 }
191 $requestControllerExtensionName = isset($conf['extbase.']['controllerExtensionName.']) ? $this->cObj->stdWrap($conf['extbase.']['controllerExtensionName'], $conf['extbase.']['controllerExtensionName.']) : $conf['extbase.']['controllerExtensionName'];
192 if ($requestControllerExtensionName) {
193 $this->view->getRequest()->setControllerExtensionName($requestControllerExtensionName);
194 }
195 $requestControllerName = isset($conf['extbase.']['controllerName.']) ? $this->cObj->stdWrap($conf['extbase.']['controllerName'], $conf['extbase.']['controllerName.']) : $conf['extbase.']['controllerName'];
196 if ($requestControllerName) {
197 $this->view->getRequest()->setControllerName($requestControllerName);
198 }
199 $requestControllerActionName = isset($conf['extbase.']['controllerActionName.']) ? $this->cObj->stdWrap($conf['extbase.']['controllerActionName'], $conf['extbase.']['controllerActionName.']) : $conf['extbase.']['controllerActionName'];
200 if ($requestControllerActionName) {
201 $this->view->getRequest()->setControllerActionName($requestControllerActionName);
202 }
203 }
204
205 /**
206 * Assign rendered content objects in variables array to view
207 *
208 * @param array $conf Configuration array
209 * @return void
210 * @throws \InvalidArgumentException
211 */
212 protected function assignContentObjectVariables(array $conf) {
213 $reservedVariables = array('data', 'current');
214 // Accumulate the variables to be replaced and loop them through cObjGetSingle
215 $variables = (array)$conf['variables.'];
216 foreach ($variables as $variableName => $cObjType) {
217 if (is_array($cObjType)) {
218 continue;
219 }
220 if (!in_array($variableName, $reservedVariables)) {
221 $this->view->assign(
222 $variableName,
223 $this->cObj->cObjGetSingle($cObjType, $variables[$variableName . '.'])
224 );
225 } else {
226 throw new \InvalidArgumentException(
227 'Cannot use reserved name "' . $variableName . '" as variable name in FLUIDTEMPLATE.',
228 1288095720
229 );
230 }
231 }
232 }
233
234 /**
235 * Set any TypoScript settings to the view. This is similar to a
236 * default MVC action controller in extbase.
237 *
238 * @param array $conf Configuration
239 * @return void
240 */
241 protected function assignSettings(array $conf) {
242 if (isset($conf['settings.'])) {
243 /** @var $typoScriptService \TYPO3\CMS\Extbase\Service\TypoScriptService */
244 $typoScriptService = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Service\\TypoScriptService');
245 $settings = $typoScriptService->convertTypoScriptArrayToPlainArray($conf['settings.']);
246 $this->view->assign('settings', $settings);
247 }
248 }
249
250 /**
251 * Assign content object renderer data and current to view
252 *
253 * @param array $conf Configuration
254 * @return void
255 */
256 protected function assignContentObjectDataAndCurrent(array $conf) {
257 $this->view->assign('data', $this->cObj->data);
258 $this->view->assign('current', $this->cObj->data[$this->cObj->currentValKey]);
259 }
260
261 /**
262 * Render fluid standalone view
263 *
264 * @return string
265 */
266 protected function renderFluidView() {
267 return $this->view->render();
268 }
269
270 /**
271 * Apply standard wrap to content
272 *
273 * @param string $content Rendered HTML content
274 * @param array $conf Configuration array
275 * @return string Standard wrapped content
276 */
277 protected function applyStandardWrapToRenderedContent($content, array $conf) {
278 if (isset($conf['stdWrap.'])) {
279 $content = $this->cObj->stdWrap($content, $conf['stdWrap.']);
280 }
281 return $content;
282 }
283
284 }