‪TYPO3CMS  ‪main
PageRenderer.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
16 namespace ‪TYPO3\CMS\Core\Page;
17 
18 use Psr\Http\Message\ResponseFactoryInterface;
19 use Psr\Http\Message\ResponseInterface;
20 use Psr\Http\Message\ServerRequestInterface;
21 use Psr\Http\Message\StreamFactoryInterface;
38 
44 {
45  // Constants for the part to be rendered
46  protected const ‪PART_COMPLETE = 0;
47  protected const ‪PART_HEADER = 1;
48  protected const ‪PART_FOOTER = 2;
49 
50  protected bool ‪$compressJavascript = false;
51  protected bool ‪$compressCss = false;
52  protected bool ‪$concatenateJavascript = false;
53  protected bool ‪$concatenateCss = false;
54  protected bool ‪$moveJsFromHeaderToFooter = false;
55 
59  protected ‪Locale ‪$locale;
60 
61  // Arrays containing associative array for the included files
65  protected array ‪$jsFiles = [];
66  protected array ‪$jsFooterFiles = [];
67  protected array ‪$jsLibs = [];
68  protected array ‪$jsFooterLibs = [];
69 
73  protected array ‪$cssFiles = [];
74 
78  protected array ‪$cssLibs = [];
79 
83  protected string ‪$title = '';
84  protected string ‪$favIcon = '';
85 
86  // Static header blocks
87  protected string ‪$xmlPrologAndDocType = '';
88  protected array ‪$inlineComments = [];
89  protected array ‪$headerData = [];
90  protected array ‪$footerData = [];
91  protected string ‪$titleTag = '<title>|</title>';
92  protected string ‪$htmlTag = '<html>';
93  protected string ‪$headTag = '<head>';
94  protected string ‪$iconMimeType = '';
95  protected string ‪$shortcutTag = '<link rel="icon" href="%1$s"%2$s />';
96 
97  // Static inline code blocks
101  protected array ‪$jsInline = [];
102  protected array ‪$jsFooterInline = [];
103 
107  protected array ‪$cssInline = [];
108  protected string ‪$bodyContent = '';
109  protected string ‪$templateFile = '';
110  protected array ‪$inlineLanguageLabels = [];
111  protected array ‪$inlineLanguageLabelFiles = [];
112  protected array ‪$inlineSettings = [];
113 
117  protected string ‪$endingSlash = '';
118 
119  protected JavaScriptRenderer ‪$javaScriptRenderer;
120  protected ?‪ConsumableNonce ‪$nonce = null;
121  protected ‪DocType ‪$docType = DocType::html5;
122  protected bool ‪$applyNonceHint = false;
123 
124  public function ‪__construct(
125  protected readonly ‪FrontendInterface $assetsCache,
126  protected readonly ‪MarkerBasedTemplateService $templateService,
127  protected readonly ‪MetaTagManagerRegistry $metaTagRegistry,
128  protected readonly ‪AssetRenderer $assetRenderer,
129  protected readonly ‪ResourceCompressor $resourceCompressor,
130  protected readonly ‪RelativeCssPathFixer $relativeCssPathFixer,
131  protected readonly ‪LanguageServiceFactory $languageServiceFactory,
132  protected readonly ResponseFactoryInterface $responseFactory,
133  protected readonly StreamFactoryInterface $streamFactory,
134  ) {
135  $this->‪reset();
136 
137  $this->‪setMetaTag('name', 'generator', 'TYPO3 CMS');
138  }
139 
143  public function ‪updateState(array $state): void
144  {
145  foreach ($state as $var => $value) {
146  switch ($var) {
147  case 'assetsCache':
148  case 'assetRenderer':
149  case 'templateService':
150  case 'resourceCompressor':
151  case 'relativeCssPathFixer':
152  case 'languageServiceFactory':
153  case 'responseFactory':
154  case 'streamFactory':
155  break;
156  case 'nonce':
157  $this->‪setNonce(new ‪ConsumableNonce($value));
158  break;
159  case 'metaTagRegistry':
160  $this->metaTagRegistry->updateState($value);
161  break;
162  case 'javaScriptRenderer':
163  $this->javaScriptRenderer->updateState($value);
164  break;
165  default:
166  $this->{$var} = $value;
167  break;
168  }
169  }
170  }
171 
175  public function ‪getState(): array
176  {
177  $state = [];
178  foreach (get_object_vars($this) as $var => $value) {
179  switch ($var) {
180  case 'assetsCache':
181  case 'assetRenderer':
182  case 'templateService':
183  case 'resourceCompressor':
184  case 'relativeCssPathFixer':
185  case 'languageServiceFactory':
186  case 'responseFactory':
187  case 'streamFactory':
188  break;
189  case 'nonce':
190  if ($value instanceof ‪ConsumableNonce) {
191  $state[$var] = $value->value;
192  }
193  break;
194  case 'metaTagRegistry':
195  $state[$var] = $this->metaTagRegistry->getState();
196  break;
197  case 'javaScriptRenderer':
198  $state[$var] = $this->javaScriptRenderer->getState();
199  break;
200  default:
201  $state[$var] = $value;
202  break;
203  }
204  }
205  return $state;
206  }
207 
208  public function ‪getJavaScriptRenderer(): JavaScriptRenderer
209  {
211  }
212 
216  protected function ‪reset(): void
217  {
218  $this->locale = new ‪Locale();
219  $this->‪setDocType(DocType::html5);
220  $this->templateFile = 'EXT:core/Resources/Private/Templates/PageRenderer.html';
221  $this->bodyContent = '';
222  $this->jsFiles = [];
223  $this->jsFooterFiles = [];
224  $this->jsInline = [];
225  $this->jsFooterInline = [];
226  $this->jsLibs = [];
227  $this->cssFiles = [];
228  $this->cssInline = [];
229  $this->inlineComments = [];
230  $this->headerData = [];
231  $this->footerData = [];
232  $this->javaScriptRenderer = JavaScriptRenderer::create(
233  $this->‪getStreamlinedFileName('EXT:core/Resources/Public/JavaScript/java-script-item-handler.js', true)
234  );
235  }
236 
237  /*****************************************************/
238  /* */
239  /* Public Setters */
240  /* */
241  /* */
242  /*****************************************************/
248  public function ‪setTitle($title)
249  {
250  $this->title = ‪$title;
251  }
252 
259  {
260  $this->xmlPrologAndDocType = ‪$xmlPrologAndDocType;
261  }
262 
266  public function ‪setLanguage(‪Locale ‪$locale): void
267  {
268  $this->locale = ‪$locale;
269  $this->‪setDefaultHtmlTag();
270  }
271 
276  protected function ‪setDefaultHtmlTag(): void
277  {
278  if ($this->docType === DocType::html5) {
279  $attributes = [
280  'lang' => $this->locale->getName(),
281  ];
282  if ($this->locale->isRightToLeftLanguageDirection()) {
283  $attributes['dir'] = 'rtl';
284  }
285  $this->‪setHtmlTag('<html ' . GeneralUtility::implodeAttributes($attributes, true) . '>');
286  }
287  }
288 
294  public function ‪setHtmlTag(‪$htmlTag)
295  {
296  $this->htmlTag = ‪$htmlTag;
297  }
298 
304  public function ‪setHeadTag(‪$headTag)
305  {
306  $this->headTag = ‪$headTag;
307  }
308 
314  public function ‪setFavIcon(‪$favIcon)
315  {
316  $this->favIcon = ‪$favIcon;
317  }
318 
325  {
326  $this->iconMimeType = ‪$iconMimeType;
327  }
328 
334  public function ‪setTemplateFile($file)
335  {
336  $this->templateFile = $file;
337  }
338 
344  public function ‪setBodyContent($content)
345  {
346  $this->bodyContent = $content;
347  }
348 
349  public function ‪setApplyNonceHint(bool ‪$applyNonceHint): void
350  {
351  $this->applyNonceHint = ‪$applyNonceHint;
352  }
353 
354  /*****************************************************/
355  /* */
356  /* Public Enablers / Disablers */
357  /* */
358  /* */
359  /*****************************************************/
364  {
365  $this->moveJsFromHeaderToFooter = true;
366  }
367 
372  {
373  $this->moveJsFromHeaderToFooter = false;
374  }
375 
379  public function ‪enableCompressJavascript()
380  {
381  $this->compressJavascript = true;
382  }
383 
388  {
389  $this->compressJavascript = false;
390  }
391 
395  public function ‪enableCompressCss()
396  {
397  $this->compressCss = true;
398  }
399 
403  public function ‪disableCompressCss()
404  {
405  $this->compressCss = false;
406  }
407 
412  {
413  $this->concatenateJavascript = true;
414  }
415 
420  {
421  $this->concatenateJavascript = false;
422  }
423 
427  public function ‪enableConcatenateCss()
428  {
429  $this->concatenateCss = true;
430  }
431 
435  public function ‪disableConcatenateCss()
436  {
437  $this->concatenateCss = false;
438  }
439 
440  /*****************************************************/
441  /* */
442  /* Public Getters */
443  /* */
444  /* */
445  /*****************************************************/
451  public function ‪getTitle()
452  {
453  return ‪$this->title;
454  }
455 
459  public function ‪getLanguage(): string
460  {
461  return (string)‪$this->locale;
462  }
463 
464  public function ‪setNonce(?‪ConsumableNonce ‪$nonce): void
465  {
466  $this->nonce = ‪$nonce;
467  }
468 
469  public function ‪setDocType(‪DocType ‪$docType): void
470  {
471  $this->docType = ‪$docType;
472  $this->xmlPrologAndDocType = ‪$docType->getDoctypeDeclaration();
473  $this->‪setDefaultHtmlTag();
474  }
475 
476  public function ‪getDocType(): ‪DocType
477  {
478  return ‪$this->docType;
479  }
480 
486  public function ‪getHtmlTag()
487  {
488  return ‪$this->htmlTag;
489  }
490 
496  public function ‪getHeadTag()
497  {
498  return ‪$this->headTag;
499  }
500 
506  public function ‪getFavIcon()
507  {
508  return ‪$this->favIcon;
509  }
510 
516  public function ‪getIconMimeType()
517  {
518  return ‪$this->iconMimeType;
519  }
520 
526  public function ‪getTemplateFile()
527  {
528  return ‪$this->templateFile;
529  }
530 
537  {
539  }
540 
546  public function ‪getCompressJavascript()
547  {
549  }
550 
556  public function ‪getCompressCss()
557  {
558  return ‪$this->compressCss;
559  }
560 
566  public function ‪getConcatenateJavascript()
567  {
569  }
570 
576  public function ‪getConcatenateCss()
577  {
579  }
580 
586  public function ‪getBodyContent()
587  {
588  return ‪$this->bodyContent;
589  }
590 
596  public function ‪getInlineLanguageLabels()
597  {
599  }
600 
607  {
609  }
610 
611  /*****************************************************/
612  /* */
613  /* Public Functions to add Data */
614  /* */
615  /* */
616  /*****************************************************/
617 
628  public function ‪setMetaTag(string $type, string $name, string $content, array $subProperties = [], $replace = true)
629  {
630  // Lowercase all the things
631  $type = strtolower($type);
632  $name = strtolower($name);
633  if (!in_array($type, ['property', 'name', 'http-equiv'], true)) {
634  throw new \InvalidArgumentException(
635  'When setting a meta tag the only types allowed are property, name or http-equiv. "' . $type . '" given.',
636  1496402460
637  );
638  }
639  $manager = $this->metaTagRegistry->getManagerForProperty($name);
640  $manager->addProperty($name, $content, $subProperties, $replace, $type);
641  }
642 
646  public function ‪getMetaTag(string $type, string $name): array
647  {
648  // Lowercase all the things
649  $type = strtolower($type);
650  $name = strtolower($name);
651 
652  $manager = $this->metaTagRegistry->getManagerForProperty($name);
653  $propertyContent = $manager->getProperty($name, $type);
654 
655  if (!empty($propertyContent[0])) {
656  return [
657  'type' => $type,
658  'name' => $name,
659  'content' => $propertyContent[0]['content'],
660  ];
661  }
662  return [];
663  }
664 
668  public function ‪removeMetaTag(string $type, string $name)
669  {
670  // Lowercase all the things
671  $type = strtolower($type);
672  $name = strtolower($name);
673 
674  $manager = $this->metaTagRegistry->getManagerForProperty($name);
675  $manager->removeProperty($name, $type);
676  }
677 
683  public function ‪addInlineComment($comment)
684  {
685  if (!in_array($comment, $this->inlineComments)) {
686  $this->inlineComments[] = $comment;
687  }
688  }
689 
695  public function ‪addHeaderData($data)
696  {
697  if (!in_array($data, $this->headerData)) {
698  $this->headerData[] = $data;
699  }
700  }
701 
707  public function ‪addFooterData($data)
708  {
709  if (!in_array($data, $this->footerData)) {
710  $this->footerData[] = $data;
711  }
712  }
713 
732  public function ‪addJsLibrary($name, $file, $type = '', $compress = false, $forceOnTop = false, $allWrap = '', $excludeFromConcatenation = false, $splitChar = '|', $async = false, $integrity = '', $defer = false, $crossorigin = '', $nomodule = false, array $tagAttributes = [])
733  {
734  if ($type === null) {
735  $type = $this->docType === DocType::html5 ? '' : 'text/javascript';
736  }
737  if (!isset($this->jsLibs[strtolower($name)])) {
738  $this->jsLibs[strtolower($name)] = [
739  'file' => $file,
740  'type' => $type,
741  'section' => ‪self::PART_HEADER,
742  'compress' => $compress,
743  'forceOnTop' => $forceOnTop,
744  'allWrap' => $allWrap,
745  'excludeFromConcatenation' => $excludeFromConcatenation,
746  'splitChar' => $splitChar,
747  'async' => $async,
748  'integrity' => $integrity,
749  'defer' => $defer,
750  'crossorigin' => $crossorigin,
751  'nomodule' => $nomodule,
752  'tagAttributes' => $tagAttributes,
753  ];
754  }
755  }
756 
775  public function ‪addJsFooterLibrary($name, $file, $type = '', $compress = false, $forceOnTop = false, $allWrap = '', $excludeFromConcatenation = false, $splitChar = '|', $async = false, $integrity = '', $defer = false, $crossorigin = '', $nomodule = false, array $tagAttributes = [])
776  {
777  if ($type === null) {
778  $type = $this->docType === DocType::html5 ? '' : 'text/javascript';
779  }
780  $name .= '_jsFooterLibrary';
781  if (!isset($this->jsLibs[strtolower($name)])) {
782  $this->jsLibs[strtolower($name)] = [
783  'file' => $file,
784  'type' => $type,
785  'section' => ‪self::PART_FOOTER,
786  'compress' => $compress,
787  'forceOnTop' => $forceOnTop,
788  'allWrap' => $allWrap,
789  'excludeFromConcatenation' => $excludeFromConcatenation,
790  'splitChar' => $splitChar,
791  'async' => $async,
792  'integrity' => $integrity,
793  'defer' => $defer,
794  'crossorigin' => $crossorigin,
795  'nomodule' => $nomodule,
796  'tagAttributes' => $tagAttributes,
797  ];
798  }
799  }
800 
818  public function ‪addJsFile($file, $type = '', $compress = true, $forceOnTop = false, $allWrap = '', $excludeFromConcatenation = false, $splitChar = '|', $async = false, $integrity = '', $defer = false, $crossorigin = '', $nomodule = false, array $tagAttributes = [])
819  {
820  if ($type === null) {
821  $type = $this->docType === DocType::html5 ? '' : 'text/javascript';
822  }
823  if (!isset($this->jsFiles[$file])) {
824  $this->jsFiles[$file] = [
825  'file' => $file,
826  'type' => $type,
827  'section' => ‪self::PART_HEADER,
828  'compress' => $compress,
829  'forceOnTop' => $forceOnTop,
830  'allWrap' => $allWrap,
831  'excludeFromConcatenation' => $excludeFromConcatenation,
832  'splitChar' => $splitChar,
833  'async' => $async,
834  'integrity' => $integrity,
835  'defer' => $defer,
836  'crossorigin' => $crossorigin,
837  'nomodule' => $nomodule,
838  'tagAttributes' => $tagAttributes,
839  ];
840  }
841  }
842 
860  public function ‪addJsFooterFile($file, $type = '', $compress = true, $forceOnTop = false, $allWrap = '', $excludeFromConcatenation = false, $splitChar = '|', $async = false, $integrity = '', $defer = false, $crossorigin = '', $nomodule = false, array $tagAttributes = [])
861  {
862  if ($type === null) {
863  $type = $this->docType === DocType::html5 ? '' : 'text/javascript';
864  }
865  if (!isset($this->jsFiles[$file])) {
866  $this->jsFiles[$file] = [
867  'file' => $file,
868  'type' => $type,
869  'section' => ‪self::PART_FOOTER,
870  'compress' => $compress,
871  'forceOnTop' => $forceOnTop,
872  'allWrap' => $allWrap,
873  'excludeFromConcatenation' => $excludeFromConcatenation,
874  'splitChar' => $splitChar,
875  'async' => $async,
876  'integrity' => $integrity,
877  'defer' => $defer,
878  'crossorigin' => $crossorigin,
879  'nomodule' => $nomodule,
880  'tagAttributes' => $tagAttributes,
881  ];
882  }
883  }
884 
893  public function ‪addJsInlineCode($name, $block, $compress = true, $forceOnTop = false, bool $useNonce = false)
894  {
895  if (!isset($this->jsInline[$name]) && !empty($block)) {
896  $this->jsInline[$name] = [
897  'code' => $block . LF,
898  'section' => ‪self::PART_HEADER,
899  'compress' => $compress,
900  'forceOnTop' => $forceOnTop,
901  'useNonce' => $useNonce,
902  ];
903  }
904  }
905 
914  public function ‪addJsFooterInlineCode($name, $block, $compress = true, $forceOnTop = false, bool $useNonce = false)
915  {
916  if (!isset($this->jsInline[$name]) && !empty($block)) {
917  $this->jsInline[$name] = [
918  'code' => $block . LF,
919  'section' => ‪self::PART_FOOTER,
920  'compress' => $compress,
921  'forceOnTop' => $forceOnTop,
922  'useNonce' => $useNonce,
923  ];
924  }
925  }
926 
942  public function ‪addCssFile($file, $rel = 'stylesheet', $media = 'all', ‪$title = '', $compress = true, $forceOnTop = false, $allWrap = '', $excludeFromConcatenation = false, $splitChar = '|', $inline = false, array $tagAttributes = [])
943  {
944  if (!isset($this->cssFiles[$file])) {
945  $this->cssFiles[$file] = [
946  'file' => $file,
947  'rel' => $rel,
948  'media' => $media,
949  'title' => ‪$title,
950  'compress' => $compress,
951  'forceOnTop' => $forceOnTop,
952  'allWrap' => $allWrap,
953  'excludeFromConcatenation' => $excludeFromConcatenation,
954  'splitChar' => $splitChar,
955  'inline' => $inline,
956  'tagAttributes' => $tagAttributes,
957  ];
958  }
959  }
960 
976  public function ‪addCssLibrary($file, $rel = 'stylesheet', $media = 'all', ‪$title = '', $compress = true, $forceOnTop = false, $allWrap = '', $excludeFromConcatenation = false, $splitChar = '|', $inline = false, array $tagAttributes = [])
977  {
978  if (!isset($this->cssLibs[$file])) {
979  $this->cssLibs[$file] = [
980  'file' => $file,
981  'rel' => $rel,
982  'media' => $media,
983  'title' => ‪$title,
984  'compress' => $compress,
985  'forceOnTop' => $forceOnTop,
986  'allWrap' => $allWrap,
987  'excludeFromConcatenation' => $excludeFromConcatenation,
988  'splitChar' => $splitChar,
989  'inline' => $inline,
990  'tagAttributes' => $tagAttributes,
991  ];
992  }
993  }
994 
1003  public function ‪addCssInlineBlock($name, $block, $compress = false, $forceOnTop = false, bool $useNonce = false)
1004  {
1005  if (!isset($this->cssInline[$name]) && !empty($block)) {
1006  $this->cssInline[$name] = [
1007  'code' => $block,
1008  'compress' => $compress,
1009  'forceOnTop' => $forceOnTop,
1010  'useNonce' => $useNonce,
1011  ];
1012  }
1013  }
1014 
1021  public function ‪loadJavaScriptModule(string $specifier)
1022  {
1023  $this->javaScriptRenderer->addJavaScriptModuleInstruction(
1025  );
1026  }
1027 
1035  public function ‪addInlineLanguageLabel($key, $value)
1036  {
1037  $this->inlineLanguageLabels[$key] = $value;
1038  }
1039 
1045  public function ‪addInlineLanguageLabelArray(array $array)
1046  {
1047  $this->inlineLanguageLabels = array_merge($this->inlineLanguageLabels, $array);
1048  }
1049 
1057  public function ‪addInlineLanguageLabelFile($fileRef, $selectionPrefix = '', $stripFromSelectionName = '')
1058  {
1059  $index = md5($fileRef . $selectionPrefix . $stripFromSelectionName);
1060  if ($fileRef && !isset($this->inlineLanguageLabelFiles[$index])) {
1061  $this->inlineLanguageLabelFiles[$index] = [
1062  'fileRef' => $fileRef,
1063  'selectionPrefix' => $selectionPrefix,
1064  'stripFromSelectionName' => $stripFromSelectionName,
1065  ];
1066  }
1067  }
1068 
1077  public function ‪addInlineSetting($namespace, $key, $value)
1078  {
1079  if ($namespace) {
1080  if (strpos($namespace, '.')) {
1081  $parts = explode('.', $namespace);
1083  foreach ($parts as $part) {
1084  $a = &$a[$part];
1085  }
1086  $a[$key] = $value;
1087  } else {
1088  $this->inlineSettings[$namespace][$key] = $value;
1089  }
1090  } else {
1091  $this->inlineSettings[$key] = $value;
1092  }
1093  }
1094 
1102  public function ‪addInlineSettingArray($namespace, array $array)
1103  {
1104  if ($namespace) {
1105  if (strpos($namespace, '.')) {
1106  $parts = explode('.', $namespace);
1108  foreach ($parts as $part) {
1109  $a = &$a[$part];
1110  }
1111  $a = array_merge((array)$a, $array);
1112  } else {
1113  $this->inlineSettings[$namespace] = array_merge((array)($this->inlineSettings[$namespace] ?? []), $array);
1114  }
1115  } else {
1116  $this->inlineSettings = array_merge($this->inlineSettings, $array);
1117  }
1118  }
1119 
1125  public function ‪addBodyContent($content)
1126  {
1127  $this->bodyContent .= $content;
1128  }
1129 
1130  /*****************************************************/
1131  /* */
1132  /* Render Functions */
1133  /* */
1134  /*****************************************************/
1140  public function ‪render()
1141  {
1142  $this->‪prepareRendering();
1144  $metaTags = implode(LF, $this->‪renderMetaTagsFromAPI());
1146  $template = $this->‪getTemplate();
1147 
1148  // The page renderer needs a full reset when the page was rendered
1149  $this->‪reset();
1150  return trim($this->templateService->substituteMarkerArray($template, $markerArray, '###|###'));
1151  }
1152 
1153  public function ‪renderResponse(
1154  int $code = 200,
1155  string $reasonPhrase = '',
1156  ): ResponseInterface {
1157  $stream = $this->streamFactory->createStream($this->‪render());
1158  return $this->responseFactory->createResponse($code, $reasonPhrase)
1159  ->withHeader('Content-Type', 'text/html; charset=utf-8')
1160  ->withBody($stream);
1161  }
1162 
1168  protected function ‪renderMetaTagsFromAPI()
1169  {
1170  $metaTags = [];
1171  $metaTagManagers = $this->metaTagRegistry->getAllManagers();
1172 
1173  foreach ($metaTagManagers as $manager => $managerObject) {
1174  $properties = $managerObject->renderAllProperties();
1175  if (!empty($properties)) {
1176  $metaTags[] = $properties;
1177  }
1178  }
1179  return $metaTags;
1180  }
1181 
1189  public function ‪renderPageWithUncachedObjects($substituteHash)
1190  {
1191  $this->‪prepareRendering();
1192  $markerArray = $this->‪getPreparedMarkerArrayForPageWithUncachedObjects($substituteHash);
1193  $template = $this->‪getTemplate();
1194  return trim($this->templateService->substituteMarkerArray($template, $markerArray, '###|###'));
1195  }
1196 
1206  public function ‪renderJavaScriptAndCssForProcessingOfUncachedContentObjects($cachedPageContent, $substituteHash)
1207  {
1208  $this->‪prepareRendering();
1210  $title = $this->title ? str_replace('|', htmlspecialchars($this->title), $this->titleTag) : '';
1211  $markerArray = [
1212  '<!-- ###TITLE' . $substituteHash . '### -->' => ‪$title,
1213  '<!-- ###CSS_LIBS' . $substituteHash . '### -->' => ‪$cssLibs,
1214  '<!-- ###CSS_INCLUDE' . $substituteHash . '### -->' => ‪$cssFiles,
1215  '<!-- ###CSS_INLINE' . $substituteHash . '### -->' => ‪$cssInline,
1216  '<!-- ###JS_INLINE' . $substituteHash . '### -->' => ‪$jsInline,
1217  '<!-- ###JS_INCLUDE' . $substituteHash . '### -->' => ‪$jsFiles,
1218  '<!-- ###JS_LIBS' . $substituteHash . '### -->' => ‪$jsLibs,
1219  '<!-- ###META' . $substituteHash . '### -->' => implode(LF, $this->‪renderMetaTagsFromAPI()),
1220  '<!-- ###HEADERDATA' . $substituteHash . '### -->' => implode(LF, $this->headerData),
1221  '<!-- ###FOOTERDATA' . $substituteHash . '### -->' => implode(LF, $this->footerData),
1222  '<!-- ###JS_LIBS_FOOTER' . $substituteHash . '### -->' => ‪$jsFooterLibs,
1223  '<!-- ###JS_INCLUDE_FOOTER' . $substituteHash . '### -->' => ‪$jsFooterFiles,
1224  '<!-- ###JS_INLINE_FOOTER' . $substituteHash . '### -->' => ‪$jsFooterInline,
1225  ];
1226  foreach ($markerArray as $placeHolder => $content) {
1227  $cachedPageContent = str_replace($placeHolder, $content, $cachedPageContent);
1228  }
1229  $this->‪reset();
1230  return $cachedPageContent;
1231  }
1232 
1238  protected function ‪prepareRendering()
1239  {
1240  if ($this->docType->isXmlCompliant()) {
1241  $this->endingSlash = ' /';
1242  } else {
1243  $this->shortcutTag = str_replace(' />', '>', $this->shortcutTag);
1244  $this->endingSlash = '';
1245  }
1246  }
1247 
1253  protected function ‪renderJavaScriptAndCss()
1254  {
1255  $this->‪executePreRenderHook();
1256  $mainJsLibs = $this->‪renderMainJavaScriptLibraries();
1257  if ($this->concatenateJavascript || $this->concatenateCss) {
1258  // Do the file concatenation
1259  $this->‪doConcatenate();
1260  }
1261  if ($this->compressCss || $this->compressJavascript) {
1262  // Do the file compression
1263  $this->‪doCompress();
1264  }
1266  $cssLibs = $this->‪renderCssLibraries();
1267  $cssFiles = $this->‪renderCssFiles();
1268  $cssInline = $this->‪renderCssInline();
1272  $jsLibs = $mainJsLibs . ‪$jsLibs;
1273  if ($this->moveJsFromHeaderToFooter) {
1275  ‪$jsLibs = '';
1277  ‪$jsFiles = '';
1279  ‪$jsInline = '';
1280  }
1281  // Use AssetRenderer to inject all JavaScripts and CSS files
1282  ‪$jsInline .= $this->assetRenderer->renderInlineJavaScript(true, $this->nonce);
1283  ‪$jsFooterInline .= $this->assetRenderer->renderInlineJavaScript(false, $this->nonce);
1284  ‪$jsFiles .= $this->assetRenderer->renderJavaScript(true, $this->nonce);
1285  ‪$jsFooterFiles .= $this->assetRenderer->renderJavaScript(false, $this->nonce);
1286  ‪$cssInline .= $this->assetRenderer->renderInlineStyleSheets(true, $this->nonce);
1287  // append inline CSS to footer (as there is no cssFooterInline)
1288  ‪$jsFooterFiles .= $this->assetRenderer->renderInlineStyleSheets(false, $this->nonce);
1289  ‪$cssLibs .= $this->assetRenderer->renderStyleSheets(true, $this->endingSlash, $this->nonce);
1290  ‪$cssFiles .= $this->assetRenderer->renderStyleSheets(false, $this->endingSlash, $this->nonce);
1291 
1294  }
1295 
1312  {
1313  $markerArray = [
1314  'XMLPROLOG_DOCTYPE' => ‪$this->xmlPrologAndDocType,
1315  'HTMLTAG' => ‪$this->htmlTag,
1316  'HEADTAG' => ‪$this->headTag,
1317  'INLINECOMMENT' => $this->inlineComments ? LF . LF . '<!-- ' . LF . implode(LF, $this->inlineComments) . '-->' . LF . LF : '',
1318  'SHORTCUT' => $this->favIcon ? sprintf($this->shortcutTag, htmlspecialchars($this->favIcon), $this->iconMimeType) : '',
1319  'CSS_LIBS' => ‪$cssLibs,
1320  'CSS_INCLUDE' => ‪$cssFiles,
1321  'CSS_INLINE' => ‪$cssInline,
1322  'JS_INLINE' => ‪$jsInline,
1323  'JS_INCLUDE' => ‪$jsFiles,
1324  'JS_LIBS' => ‪$jsLibs,
1325  'TITLE' => $this->title ? str_replace('|', htmlspecialchars($this->title), $this->titleTag) : '',
1326  'META' => $metaTags,
1327  'HEADERDATA' => $this->headerData ? implode(LF, $this->headerData) : '',
1328  'FOOTERDATA' => $this->footerData ? implode(LF, $this->footerData) : '',
1329  'JS_LIBS_FOOTER' => ‪$jsFooterLibs,
1330  'JS_INCLUDE_FOOTER' => ‪$jsFooterFiles,
1331  'JS_INLINE_FOOTER' => ‪$jsFooterInline,
1332  'BODY' => ‪$this->bodyContent,
1333  // @internal
1334  'TRAILING_SLASH_FOR_SELF_CLOSING_TAG' => $this->endingSlash ? ' ' . $this->endingSlash : '',
1335  ];
1336 
1337  return array_map(trim(...), $markerArray);
1338  }
1339 
1346  protected function ‪getPreparedMarkerArrayForPageWithUncachedObjects($substituteHash)
1347  {
1348  $markerArray = [
1349  'XMLPROLOG_DOCTYPE' => ‪$this->xmlPrologAndDocType,
1350  'HTMLTAG' => ‪$this->htmlTag,
1351  'HEADTAG' => ‪$this->headTag,
1352  'INLINECOMMENT' => $this->inlineComments ? LF . LF . '<!-- ' . LF . implode(LF, $this->inlineComments) . '-->' . LF . LF : '',
1353  'SHORTCUT' => $this->favIcon ? sprintf($this->shortcutTag, htmlspecialchars($this->favIcon), $this->iconMimeType) : '',
1354  'META' => '<!-- ###META' . $substituteHash . '### -->',
1355  'BODY' => ‪$this->bodyContent,
1356  'TITLE' => '<!-- ###TITLE' . $substituteHash . '### -->',
1357  'CSS_LIBS' => '<!-- ###CSS_LIBS' . $substituteHash . '### -->',
1358  'CSS_INCLUDE' => '<!-- ###CSS_INCLUDE' . $substituteHash . '### -->',
1359  'CSS_INLINE' => '<!-- ###CSS_INLINE' . $substituteHash . '### -->',
1360  'JS_INLINE' => '<!-- ###JS_INLINE' . $substituteHash . '### -->',
1361  'JS_INCLUDE' => '<!-- ###JS_INCLUDE' . $substituteHash . '### -->',
1362  'JS_LIBS' => '<!-- ###JS_LIBS' . $substituteHash . '### -->',
1363  'HEADERDATA' => '<!-- ###HEADERDATA' . $substituteHash . '### -->',
1364  'FOOTERDATA' => '<!-- ###FOOTERDATA' . $substituteHash . '### -->',
1365  'JS_LIBS_FOOTER' => '<!-- ###JS_LIBS_FOOTER' . $substituteHash . '### -->',
1366  'JS_INCLUDE_FOOTER' => '<!-- ###JS_INCLUDE_FOOTER' . $substituteHash . '### -->',
1367  'JS_INLINE_FOOTER' => '<!-- ###JS_INLINE_FOOTER' . $substituteHash . '### -->',
1368  // @internal
1369  'TRAILING_SLASH_FOR_SELF_CLOSING_TAG' => $this->endingSlash ? ' ' . $this->endingSlash : '',
1370  ];
1371  $markerArray = array_map(trim(...), $markerArray);
1372  return $markerArray;
1373  }
1374 
1378  protected function ‪getTemplate(): string
1379  {
1380  ‪$templateFile = GeneralUtility::getFileAbsFileName($this->templateFile);
1381  if (is_file(‪$templateFile)) {
1382  $template = (string)file_get_contents(‪$templateFile);
1383  } else {
1384  $template = '';
1385  }
1386  return $template;
1387  }
1388 
1395  {
1396  $out = '';
1397 
1398  // adds a nonce hint/work-around for lit-elements (which is only applied automatically in ShadowDOM)
1399  // see https://lit.dev/docs/api/ReactiveElement/#ReactiveElement.styles)
1400  if ($this->applyNonceHint && $this->nonce !== null) {
1401  $out .= GeneralUtility::wrapJS(
1402  sprintf('window.litNonce = %s;', GeneralUtility::quoteJSvalue($this->nonce->consume())),
1403  ['nonce' => $this->nonce->consume()]
1404  );
1405  }
1406 
1407  $out .= $this->javaScriptRenderer->renderImportMap(
1408  // @todo hookup with PSR-7 request/response and
1409  GeneralUtility::getIndpEnv('TYPO3_SITE_PATH'),
1410  $this->nonce
1411  );
1412 
1414  if ($this->‪getApplicationType() === 'BE') {
1415  $noBackendUserLoggedIn = empty(‪$GLOBALS['BE_USER']->user['uid']);
1416  $this->‪addAjaxUrlsToInlineSettings($noBackendUserLoggedIn);
1418  }
1419  $assignments = array_filter([
1420  'settings' => $this->inlineSettings,
1421  'lang' => $this->‪parseLanguageLabelsForJavaScript(),
1422  ]);
1423  if ($assignments !== []) {
1424  if ($this->‪getApplicationType() === 'BE') {
1425  $this->javaScriptRenderer->addGlobalAssignment(['TYPO3' => $assignments]);
1426  } else {
1427  $out .= $this->‪wrapInlineScript(
1428  sprintf(
1429  "var TYPO3 = Object.assign(TYPO3 || {}, %s);\r\n",
1430  // filter potential prototype pollution
1431  sprintf(
1432  'Object.fromEntries(Object.entries(%s).filter((entry) => '
1433  . "!['__proto__', 'prototype', 'constructor'].includes(entry[0])))",
1434  json_encode($assignments)
1435  )
1436  ),
1437  $this->nonce !== null ? ['nonce' => $this->nonce->consume()] : []
1438  );
1439  }
1440  }
1441  $out .= $this->javaScriptRenderer->render($this->nonce);
1442  return $out;
1443  }
1444 
1448  protected function ‪parseLanguageLabelsForJavaScript(): array
1449  {
1450  if (empty($this->inlineLanguageLabels)) {
1451  return [];
1452  }
1453 
1454  $labels = [];
1455  foreach ($this->inlineLanguageLabels as $key => $translationUnit) {
1456  if (is_array($translationUnit)) {
1457  $translationUnit = current($translationUnit);
1458  $labels[$key] = $translationUnit['target'] ?? $translationUnit['source'];
1459  } else {
1460  $labels[$key] = $translationUnit;
1461  }
1462  }
1463 
1464  return $labels;
1465  }
1466 
1471  {
1472  foreach ($this->inlineLanguageLabelFiles as $languageLabelFile) {
1473  $this->‪includeLanguageFileForInline($languageLabelFile['fileRef'], $languageLabelFile['selectionPrefix'], $languageLabelFile['stripFromSelectionName']);
1474  }
1475  $this->inlineLanguageLabelFiles = [];
1476  }
1477 
1481  protected function ‪addAjaxUrlsToInlineSettings(bool $publicRoutesOnly = false)
1482  {
1483  $ajaxUrls = [];
1484  // Add the ajax-based routes
1485  $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
1486  $router = GeneralUtility::makeInstance(Router::class);
1487  foreach ($router->getRoutes() as $routeIdentifier => $route) {
1488  if ($publicRoutesOnly && $route->getOption('access') !== 'public') {
1489  continue;
1490  }
1491  if ($route->getOption('ajax')) {
1492  $uri = (string)$uriBuilder->buildUriFromRoute($routeIdentifier);
1493  // use the shortened value in order to use this in JavaScript
1494  $routeIdentifier = str_replace('ajax_', '', $routeIdentifier);
1495  $ajaxUrls[$routeIdentifier] = $uri;
1496  }
1497  }
1498 
1499  $this->inlineSettings['ajaxUrls'] = $ajaxUrls;
1500  }
1501 
1503  {
1504  $this->inlineSettings['cssUrls'] = [
1505  'backend' => $this->‪getStreamlinedFileName('EXT:backend/Resources/Public/Css/backend.css'),
1506  ];
1507  }
1508 
1514  protected function ‪renderCssLibraries()
1515  {
1516  $cssFiles = '';
1517  if (!empty($this->cssLibs)) {
1518  foreach ($this->cssLibs as $file => $properties) {
1519  $tag = $this->‪createCssTag($properties, $file);
1520  if ($properties['forceOnTop'] ?? false) {
1521  ‪$cssFiles = $tag . ‪$cssFiles;
1522  } else {
1523  ‪$cssFiles .= $tag;
1524  }
1525  }
1526  }
1527  return ‪$cssFiles;
1528  }
1529 
1535  protected function ‪renderCssFiles()
1536  {
1537  ‪$cssFiles = '';
1538  if (!empty($this->cssFiles)) {
1539  foreach ($this->cssFiles as $file => $properties) {
1540  $tag = $this->‪createCssTag($properties, $file);
1541  if ($properties['forceOnTop'] ?? false) {
1542  ‪$cssFiles = $tag . ‪$cssFiles;
1543  } else {
1544  ‪$cssFiles .= $tag;
1545  }
1546  }
1547  }
1548  return ‪$cssFiles;
1549  }
1550 
1554  private function ‪createCssTag(array $properties, string $file): string
1555  {
1556  $includeInline = $properties['inline'] ?? false;
1557  $file = $this->‪getStreamlinedFileName($file, !$includeInline);
1558  if ($includeInline && @is_file($file)) {
1559  $tag = $this->‪createInlineCssTagFromFile($file, $properties);
1560  } else {
1561  $tagAttributes = [];
1562  if ($properties['rel'] ?? false) {
1563  $tagAttributes['rel'] = $properties['rel'];
1564  }
1565  $tagAttributes['href'] = $file;
1566  if ($properties['media'] ?? false) {
1567  $tagAttributes['media'] = $properties['media'];
1568  }
1569  if ($properties['title'] ?? false) {
1570  $tagAttributes['title'] = $properties['title'];
1571  }
1572  // use nonce if given
1573  if ($this->nonce !== null) {
1574  $tagAttributes['nonce'] = $this->nonce->consume();
1575  }
1576  $tagAttributes = array_merge($tagAttributes, $properties['tagAttributes'] ?? []);
1577  $tag = '<link ' . GeneralUtility::implodeAttributes($tagAttributes, true, true) . $this->endingSlash . '>';
1578  }
1579  if ($properties['allWrap'] ?? false) {
1580  $wrapArr = explode(($properties['splitChar'] ?? false) ?: '|', $properties['allWrap'], 2);
1581  $tag = $wrapArr[0] . $tag . $wrapArr[1];
1582  }
1583  $tag .= LF;
1584 
1585  return $tag;
1586  }
1587 
1593  protected function ‪renderCssInline()
1594  {
1595  if (empty($this->cssInline)) {
1596  return '';
1597  }
1598  $cssItems = [0 => [], 1 => []];
1599  foreach ($this->cssInline as $name => $properties) {
1600  $nonceKey = (int)(!empty($properties['useNonce']));
1601  $cssCode = '/*' . htmlspecialchars($name) . '*/' . LF . ($properties['code'] ?? '') . LF;
1602  if ($properties['forceOnTop'] ?? false) {
1603  array_unshift($cssItems[$nonceKey], $cssCode);
1604  } else {
1605  $cssItems[$nonceKey][] = $cssCode;
1606  }
1607  }
1608  $cssItems = array_filter($cssItems);
1609  foreach ($cssItems as $useNonce => $items) {
1610  $attributes = $useNonce && $this->nonce !== null ? ['nonce' => $this->nonce->consume()] : [];
1611  $cssItems[$useNonce] = $this->‪wrapInlineStyle(implode('', $items), $attributes);
1612  }
1613  return implode(LF, $cssItems);
1614  }
1615 
1622  {
1623  ‪$jsLibs = '';
1624  ‪$jsFooterLibs = '';
1625  if (!empty($this->jsLibs)) {
1626  foreach ($this->jsLibs as $properties) {
1627  $tagAttributes = [];
1628  $tagAttributes['src'] = $this->‪getStreamlinedFileName($properties['file'] ?? '');
1629  if ($properties['type'] ?? false) {
1630  $tagAttributes['type'] = $properties['type'];
1631  }
1632  if ($properties['async'] ?? false) {
1633  $tagAttributes['async'] = 'async';
1634  }
1635  if ($properties['defer'] ?? false) {
1636  $tagAttributes['defer'] = 'defer';
1637  }
1638  if ($properties['nomodule'] ?? false) {
1639  $tagAttributes['nomodule'] = 'nomodule';
1640  }
1641  if ($properties['integrity'] ?? false) {
1642  $tagAttributes['integrity'] = $properties['integrity'];
1643  }
1644  if ($properties['crossorigin'] ?? false) {
1645  $tagAttributes['crossorigin'] = $properties['crossorigin'];
1646  }
1647  // use nonce if given
1648  if ($this->nonce !== null) {
1649  $tagAttributes['nonce'] = $this->nonce->consume();
1650  }
1651  $tagAttributes = array_merge($tagAttributes, $properties['tagAttributes'] ?? []);
1652  $tag = '<script ' . GeneralUtility::implodeAttributes($tagAttributes, true, true) . '></script>';
1653  if ($properties['allWrap'] ?? false) {
1654  $wrapArr = explode(($properties['splitChar'] ?? false) ?: '|', $properties['allWrap'], 2);
1655  $tag = $wrapArr[0] . $tag . $wrapArr[1];
1656  }
1657  $tag .= LF;
1658  if ($properties['forceOnTop'] ?? false) {
1659  if (($properties['section'] ?? 0) === self::PART_HEADER) {
1660  ‪$jsLibs = $tag . ‪$jsLibs;
1661  } else {
1663  }
1664  } elseif (($properties['section'] ?? 0) === self::PART_HEADER) {
1665  ‪$jsLibs .= $tag;
1666  } else {
1667  ‪$jsFooterLibs .= $tag;
1668  }
1669  }
1670  }
1671  if ($this->moveJsFromHeaderToFooter) {
1673  ‪$jsLibs = '';
1674  }
1675  return [‪$jsLibs, ‪$jsFooterLibs];
1676  }
1677 
1683  protected function ‪renderJavaScriptFiles()
1684  {
1685  ‪$jsFiles = '';
1686  ‪$jsFooterFiles = '';
1687  if (!empty($this->jsFiles)) {
1688  foreach ($this->jsFiles as $file => $properties) {
1689  $tagAttributes = [];
1690  $tagAttributes['src'] = $this->‪getStreamlinedFileName($file);
1691  if ($properties['type'] ?? false) {
1692  $tagAttributes['type'] = $properties['type'];
1693  }
1694  if ($properties['async'] ?? false) {
1695  $tagAttributes['async'] = 'async';
1696  }
1697  if ($properties['defer'] ?? false) {
1698  $tagAttributes['defer'] = 'defer';
1699  }
1700  if ($properties['nomodule'] ?? false) {
1701  $tagAttributes['nomodule'] = 'nomodule';
1702  }
1703  if ($properties['integrity'] ?? false) {
1704  $tagAttributes['integrity'] = $properties['integrity'];
1705  }
1706  if ($properties['crossorigin'] ?? false) {
1707  $tagAttributes['crossorigin'] = $properties['crossorigin'];
1708  }
1709  // use nonce if given
1710  if ($this->nonce !== null) {
1711  $tagAttributes['nonce'] = $this->nonce->consume();
1712  }
1713  $tagAttributes = array_merge($tagAttributes, $properties['tagAttributes'] ?? []);
1714  $tag = '<script ' . GeneralUtility::implodeAttributes($tagAttributes, true, true) . '></script>';
1715  if ($properties['allWrap'] ?? false) {
1716  $wrapArr = explode(($properties['splitChar'] ?? false) ?: '|', $properties['allWrap'], 2);
1717  $tag = $wrapArr[0] . $tag . $wrapArr[1];
1718  }
1719  $tag .= LF;
1720  if ($properties['forceOnTop'] ?? false) {
1721  if (($properties['section'] ?? 0) === self::PART_HEADER) {
1722  ‪$jsFiles = $tag . ‪$jsFiles;
1723  } else {
1725  }
1726  } elseif (($properties['section'] ?? 0) === self::PART_HEADER) {
1727  ‪$jsFiles .= $tag;
1728  } else {
1729  ‪$jsFooterFiles .= $tag;
1730  }
1731  }
1732  }
1733  if ($this->moveJsFromHeaderToFooter) {
1735  ‪$jsFiles = '';
1736  }
1737  return [‪$jsFiles, ‪$jsFooterFiles];
1738  }
1739 
1745  protected function ‪renderInlineJavaScript()
1746  {
1747  if (empty($this->jsInline)) {
1748  return ['', ''];
1749  }
1750  $regularItems = [0 => [], 1 => []];
1751  $footerItems = [0 => [], 1 => []];
1752  foreach ($this->jsInline as $name => $properties) {
1753  $nonceKey = (int)(!empty($properties['useNonce'])); // 0 or 1
1754  $jsCode = '/*' . htmlspecialchars($name) . '*/' . LF . ($properties['code'] ?? '') . LF;
1755  if ($properties['forceOnTop'] ?? false) {
1756  if (($properties['section'] ?? 0) === ‪self::PART_HEADER) {
1757  array_unshift($regularItems[$nonceKey], $jsCode);
1758  } else {
1759  array_unshift($footerItems[$nonceKey], $jsCode);
1760  }
1761  } elseif (($properties['section'] ?? 0) === self::PART_HEADER) {
1762  $regularItems[$nonceKey][] = $jsCode;
1763  } else {
1764  $footerItems[$nonceKey][] = $jsCode;
1765  }
1766  }
1767  $regularItems = array_filter($regularItems);
1768  $footerItems = array_filter($footerItems);
1769  foreach ($regularItems as $useNonce => $items) {
1770  $attributes = $useNonce && $this->nonce !== null ? ['nonce' => $this->nonce->consume()] : [];
1771  $regularItems[$useNonce] = $this->‪wrapInlineScript(implode('', $items), $attributes);
1772  }
1773  foreach ($footerItems as $useNonce => $items) {
1774  $attributes = $useNonce && $this->nonce !== null ? ['nonce' => $this->nonce->consume()] : [];
1775  $footerItems[$useNonce] = $this->‪wrapInlineScript(implode('', $items), $attributes);
1776  }
1777  $regularCode = implode(LF, $regularItems);
1778  $footerCode = implode(LF, $footerItems);
1779  if ($this->moveJsFromHeaderToFooter) {
1780  $footerCode = $regularCode . $footerCode;
1781  $regularCode = '';
1782  }
1783  return [$regularCode, $footerCode];
1784  }
1785 
1793  protected function ‪includeLanguageFileForInline($fileRef, $selectionPrefix = '', $stripFromSelectionName = '')
1794  {
1795  $labelsFromFile = [];
1796  $allLabels = $this->‪readLLfile($fileRef);
1797 
1798  // Iterate through all labels from the language file
1799  foreach ($allLabels as $label => $value) {
1800  // If $selectionPrefix is set, only respect labels that start with $selectionPrefix
1801  if ($selectionPrefix === '' || str_starts_with($label, $selectionPrefix)) {
1802  // Remove substring $stripFromSelectionName from label
1803  $label = str_replace($stripFromSelectionName, '', $label);
1804  $labelsFromFile[$label] = $value;
1805  }
1806  }
1807  $this->inlineLanguageLabels = array_merge($this->inlineLanguageLabels, $labelsFromFile);
1808  }
1809 
1816  protected function ‪readLLfile(string $fileRef): array
1817  {
1818  $languageService = $this->languageServiceFactory->create($this->locale);
1819  return $languageService->getLabelsFromResource($fileRef);
1820  }
1821 
1822  /*****************************************************/
1823  /* */
1824  /* Tools */
1825  /* */
1826  /*****************************************************/
1831  protected function ‪doConcatenate()
1832  {
1833  $this->‪doConcatenateCss();
1834  $this->‪doConcatenateJavaScript();
1835  }
1836 
1840  protected function ‪doConcatenateJavaScript()
1841  {
1842  if ($this->‪getApplicationType() !== 'FE') {
1843  return;
1844  }
1845  if (!$this->concatenateJavascript) {
1846  return;
1847  }
1848  if (!empty(‪$GLOBALS['TYPO3_CONF_VARS']['FE']['jsConcatenateHandler'])) {
1849  // use external concatenation routine
1850  $params = [
1851  'jsLibs' => &‪$this->jsLibs,
1852  'jsFiles' => &‪$this->jsFiles,
1853  'jsFooterFiles' => &‪$this->jsFooterFiles,
1854  'headerData' => &‪$this->headerData,
1855  'footerData' => &‪$this->footerData,
1856  ];
1857  GeneralUtility::callUserFunction(‪$GLOBALS['TYPO3_CONF_VARS']['FE']['jsConcatenateHandler'], $params, $this);
1858  } else {
1859  $this->jsLibs = $this->resourceCompressor->concatenateJsFiles($this->jsLibs);
1860  $this->jsFiles = $this->resourceCompressor->concatenateJsFiles($this->jsFiles);
1861  $this->jsFooterFiles = $this->resourceCompressor->concatenateJsFiles($this->jsFooterFiles);
1862  }
1863  }
1864 
1868  protected function ‪doConcatenateCss()
1869  {
1870  if ($this->‪getApplicationType() !== 'FE') {
1871  return;
1872  }
1873  if (!$this->concatenateCss) {
1874  return;
1875  }
1876  if (!empty(‪$GLOBALS['TYPO3_CONF_VARS']['FE']['cssConcatenateHandler'])) {
1877  // use external concatenation routine
1878  $params = [
1879  'cssFiles' => &‪$this->cssFiles,
1880  'cssLibs' => &‪$this->cssLibs,
1881  'headerData' => &‪$this->headerData,
1882  'footerData' => &‪$this->footerData,
1883  ];
1884  GeneralUtility::callUserFunction(‪$GLOBALS['TYPO3_CONF_VARS']['FE']['cssConcatenateHandler'], $params, $this);
1885  } else {
1886  $this->cssLibs = $this->resourceCompressor->concatenateCssFiles($this->cssLibs);
1887  $this->cssFiles = $this->resourceCompressor->concatenateCssFiles($this->cssFiles);
1888  }
1889  }
1890 
1894  protected function ‪doCompress()
1895  {
1896  $this->‪doCompressJavaScript();
1897  $this->‪doCompressCss();
1898  }
1899 
1903  protected function ‪doCompressCss()
1904  {
1905  if ($this->‪getApplicationType() !== 'FE') {
1906  return;
1907  }
1908  if (!$this->compressCss) {
1909  return;
1910  }
1911  if (!empty(‪$GLOBALS['TYPO3_CONF_VARS']['FE']['cssCompressHandler'])) {
1912  // Use external compression routine
1913  $params = [
1914  'cssInline' => &‪$this->cssInline,
1915  'cssFiles' => &‪$this->cssFiles,
1916  'cssLibs' => &‪$this->cssLibs,
1917  'headerData' => &‪$this->headerData,
1918  'footerData' => &‪$this->footerData,
1919  ];
1920  GeneralUtility::callUserFunction(‪$GLOBALS['TYPO3_CONF_VARS']['FE']['cssCompressHandler'], $params, $this);
1921  } else {
1922  $this->cssLibs = $this->resourceCompressor->compressCssFiles($this->cssLibs);
1923  $this->cssFiles = $this->resourceCompressor->compressCssFiles($this->cssFiles);
1924  }
1925  }
1926 
1930  protected function ‪doCompressJavaScript()
1931  {
1932  if ($this->‪getApplicationType() !== 'FE') {
1933  return;
1934  }
1935  if (!$this->compressJavascript) {
1936  return;
1937  }
1938  if (!empty(‪$GLOBALS['TYPO3_CONF_VARS']['FE']['jsCompressHandler'])) {
1939  // Use external compression routine
1940  $params = [
1941  'jsInline' => &‪$this->jsInline,
1942  'jsFooterInline' => &‪$this->jsFooterInline,
1943  'jsLibs' => &‪$this->jsLibs,
1944  'jsFiles' => &‪$this->jsFiles,
1945  'jsFooterFiles' => &‪$this->jsFooterFiles,
1946  'headerData' => &‪$this->headerData,
1947  'footerData' => &‪$this->footerData,
1948  ];
1949  GeneralUtility::callUserFunction(‪$GLOBALS['TYPO3_CONF_VARS']['FE']['jsCompressHandler'], $params, $this);
1950  } else {
1951  // Traverse the arrays, compress files
1952  foreach ($this->jsInline as $name => $properties) {
1953  if ($properties['compress'] ?? false) {
1954  $this->jsInline[$name]['code'] = $this->resourceCompressor->compressJavaScriptSource($properties['code'] ?? '');
1955  }
1956  }
1957  $this->jsLibs = $this->resourceCompressor->compressJsFiles($this->jsLibs);
1958  $this->jsFiles = $this->resourceCompressor->compressJsFiles($this->jsFiles);
1959  $this->jsFooterFiles = $this->resourceCompressor->compressJsFiles($this->jsFooterFiles);
1960  }
1961  }
1962 
1971  protected function ‪processJsFile($filename)
1972  {
1973  $filename = $this->‪getStreamlinedFileName($filename, false);
1974  if ($this->‪getApplicationType() === 'FE') {
1975  if ($this->compressJavascript) {
1976  $filename = $this->resourceCompressor->compressJsFile($filename);
1977  } else {
1978  $filename = GeneralUtility::createVersionNumberedFilename($filename);
1979  }
1980  }
1981  return $this->‪getAbsoluteWebPath($filename);
1982  }
1983 
1996  protected function ‪getStreamlinedFileName($file, $prepareForOutput = true)
1997  {
1998  if (‪PathUtility::isExtensionPath($file)) {
2000  // as the path is now absolute, make it "relative" to the current script to stay compatible
2001  $file = ‪PathUtility::getRelativePathTo($file) ?? '';
2002  $file = rtrim($file, '/');
2003  } else {
2004  $file = GeneralUtility::resolveBackPath($file);
2005  }
2006  if ($prepareForOutput) {
2007  $file = GeneralUtility::createVersionNumberedFilename($file);
2008  $file = $this->‪getAbsoluteWebPath($file);
2009  }
2010  return $file;
2011  }
2012 
2020  protected function ‪getAbsoluteWebPath(string $file): string
2021  {
2022  if ($this->‪getApplicationType() === 'FE') {
2023  return $file;
2024  }
2025  return ‪PathUtility::getAbsoluteWebPath($file);
2026  }
2027 
2028  /*****************************************************/
2029  /* */
2030  /* Hooks */
2031  /* */
2032  /*****************************************************/
2036  protected function ‪executePreRenderHook()
2037  {
2038  $hooks = ‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-preProcess'] ?? false;
2039  if (!$hooks) {
2040  return;
2041  }
2042  $params = [
2043  'jsLibs' => &‪$this->jsLibs,
2044  'jsFooterLibs' => &‪$this->jsFooterLibs,
2045  'jsFiles' => &‪$this->jsFiles,
2046  'jsFooterFiles' => &‪$this->jsFooterFiles,
2047  'cssLibs' => &‪$this->cssLibs,
2048  'cssFiles' => &‪$this->cssFiles,
2049  'headerData' => &‪$this->headerData,
2050  'footerData' => &‪$this->footerData,
2051  'jsInline' => &‪$this->jsInline,
2052  'jsFooterInline' => &‪$this->jsFooterInline,
2053  'cssInline' => &‪$this->cssInline,
2054  ];
2055  foreach ($hooks as $hook) {
2056  GeneralUtility::callUserFunction($hook, $params, $this);
2057  }
2058  }
2059 
2064  {
2065  $hooks = ‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-postTransform'] ?? false;
2066  if (!$hooks) {
2067  return;
2068  }
2069  $params = [
2070  'jsLibs' => &‪$this->jsLibs,
2071  'jsFooterLibs' => &‪$this->jsFooterLibs,
2072  'jsFiles' => &‪$this->jsFiles,
2073  'jsFooterFiles' => &‪$this->jsFooterFiles,
2074  'cssLibs' => &‪$this->cssLibs,
2075  'cssFiles' => &‪$this->cssFiles,
2076  'headerData' => &‪$this->headerData,
2077  'footerData' => &‪$this->footerData,
2078  'jsInline' => &‪$this->jsInline,
2079  'jsFooterInline' => &‪$this->jsFooterInline,
2080  'cssInline' => &‪$this->cssInline,
2081  ];
2082  foreach ($hooks as $hook) {
2083  GeneralUtility::callUserFunction($hook, $params, $this);
2084  }
2085  }
2086 
2101  {
2102  $hooks = ‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-postProcess'] ?? false;
2103  if (!$hooks) {
2104  return;
2105  }
2106  $params = [
2107  'jsLibs' => &‪$jsLibs,
2108  'jsFiles' => &‪$jsFiles,
2109  'jsFooterFiles' => &‪$jsFooterFiles,
2110  'cssLibs' => &‪$cssLibs,
2111  'cssFiles' => &‪$cssFiles,
2112  'headerData' => &‪$this->headerData,
2113  'footerData' => &‪$this->footerData,
2114  'jsInline' => &‪$jsInline,
2115  'cssInline' => &‪$cssInline,
2116  'xmlPrologAndDocType' => &‪$this->xmlPrologAndDocType,
2117  'htmlTag' => &‪$this->htmlTag,
2118  'headTag' => &‪$this->headTag,
2119  'shortcutTag' => &‪$this->shortcutTag,
2120  'inlineComments' => &‪$this->inlineComments,
2121  'favIcon' => &‪$this->favIcon,
2122  'iconMimeType' => &‪$this->iconMimeType,
2123  'titleTag' => &‪$this->titleTag,
2124  'title' => &‪$this->title,
2125  'jsFooterInline' => &‪$jsFooterInline,
2126  'jsFooterLibs' => &‪$jsFooterLibs,
2127  'bodyContent' => &‪$this->bodyContent,
2128  ];
2129  foreach ($hooks as $hook) {
2130  GeneralUtility::callUserFunction($hook, $params, $this);
2131  }
2132  }
2133 
2139  protected function ‪createInlineCssTagFromFile(string $file, array $properties): string
2140  {
2141  ‪$cssInline = file_get_contents($file);
2142  if (‪$cssInline === false) {
2143  return '';
2144  }
2145  $cssInlineFix = $this->relativeCssPathFixer->fixRelativeUrlPaths(‪$cssInline, '/' . ‪PathUtility::dirname($file) . '/');
2146  $tagAttributes = [];
2147  if ($properties['media'] ?? false) {
2148  $tagAttributes['media'] = $properties['media'];
2149  }
2150  if ($properties['title'] ?? false) {
2151  $tagAttributes['title'] = $properties['title'];
2152  }
2153  // use nonce if given - special case, since content is created from a static file
2154  if ($this->nonce !== null) {
2155  $tagAttributes['nonce'] = $this->nonce->consume();
2156  }
2157  $tagAttributes = array_merge($tagAttributes, $properties['tagAttributes'] ?? []);
2158  return '<style ' . GeneralUtility::implodeAttributes($tagAttributes, true, true) . '>' . LF
2159  . '/*<![CDATA[*/' . LF . '<!-- ' . LF
2160  . $cssInlineFix
2161  . '-->' . LF . '/*]]>*/' . LF . '</style>' . LF;
2162  }
2163 
2164  protected function ‪wrapInlineStyle(string $content, array $attributes = []): string
2165  {
2166  $attributesList = GeneralUtility::implodeAttributes($attributes, true);
2167  return sprintf(
2168  "<style%s>\n/*<![CDATA[*/\n<!-- \n%s-->\n/*]]>*/\n</style>\n",
2169  $attributesList !== '' ? ' ' . $attributesList : '',
2170  $content
2171  );
2172  }
2173 
2174  protected function ‪wrapInlineScript(string $content, array $attributes = []): string
2175  {
2176  // * Whenever HTML5 is used, remove the "text/javascript" type from the wrap
2177  // since this is not needed and may lead to validation errors in the future.
2178  // * Whenever XHTML gets disabled, remove the "text/javascript" type from the wrap
2179  // since this is not needed and may lead to validation errors in the future.
2180  if ($this->docType !== DocType::html5 || $this->docType->isXmlCompliant()) {
2181  $attributes['type'] = 'text/javascript';
2182  }
2183 
2184  $attributesList = GeneralUtility::implodeAttributes($attributes, true);
2185  return sprintf(
2186  "<script%s>\n/*<![CDATA[*/\n%s/*]]>*/\n</script>\n",
2187  $attributesList !== '' ? ' ' . $attributesList : '',
2188  $content
2189  );
2190  }
2191 
2197  public function ‪getApplicationType(): string
2198  {
2199  if (
2200  (‪$GLOBALS['TYPO3_REQUEST'] ?? null) instanceof ServerRequestInterface &&
2201  ‪ApplicationType::fromRequest(‪$GLOBALS['TYPO3_REQUEST'])->isFrontend()
2202  ) {
2203  return 'FE';
2204  }
2205 
2206  return 'BE';
2207  }
2208 }
‪TYPO3\CMS\Core\Localization\LanguageServiceFactory
Definition: LanguageServiceFactory.php:25
‪TYPO3\CMS\Core\Page\PageRenderer\addJsLibrary
‪addJsLibrary($name, $file, $type='', $compress=false, $forceOnTop=false, $allWrap='', $excludeFromConcatenation=false, $splitChar='|', $async=false, $integrity='', $defer=false, $crossorigin='', $nomodule=false, array $tagAttributes=[])
Definition: PageRenderer.php:732
‪TYPO3\CMS\Core\Page\PageRenderer\disableCompressJavascript
‪disableCompressJavascript()
Definition: PageRenderer.php:387
‪TYPO3\CMS\Core\Page\PageRenderer\$inlineLanguageLabels
‪array $inlineLanguageLabels
Definition: PageRenderer.php:110
‪TYPO3\CMS\Core\Page\PageRenderer\addInlineLanguageLabelFile
‪addInlineLanguageLabelFile($fileRef, $selectionPrefix='', $stripFromSelectionName='')
Definition: PageRenderer.php:1057
‪TYPO3\CMS\Core\Page\PageRenderer\renderCssInline
‪string renderCssInline()
Definition: PageRenderer.php:1593
‪TYPO3\CMS\Core\Page\PageRenderer\readLLfile
‪array readLLfile(string $fileRef)
Definition: PageRenderer.php:1816
‪TYPO3\CMS\Core\Page\PageRenderer\$javaScriptRenderer
‪JavaScriptRenderer $javaScriptRenderer
Definition: PageRenderer.php:119
‪TYPO3\CMS\Core\Page\PageRenderer\enableConcatenateJavascript
‪enableConcatenateJavascript()
Definition: PageRenderer.php:411
‪TYPO3\CMS\Core\Page\PageRenderer\renderJavaScriptAndCssForProcessingOfUncachedContentObjects
‪string renderJavaScriptAndCssForProcessingOfUncachedContentObjects($cachedPageContent, $substituteHash)
Definition: PageRenderer.php:1206
‪TYPO3\CMS\Core\Page\PageRenderer\setDefaultHtmlTag
‪setDefaultHtmlTag()
Definition: PageRenderer.php:276
‪TYPO3\CMS\Core\Utility\PathUtility\isExtensionPath
‪static isExtensionPath(string $path)
Definition: PathUtility.php:117
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:27
‪TYPO3\CMS\Core\Page\PageRenderer\$cssFiles
‪array $cssFiles
Definition: PageRenderer.php:73
‪TYPO3\CMS\Core\Page\PageRenderer\setFavIcon
‪setFavIcon($favIcon)
Definition: PageRenderer.php:314
‪TYPO3\CMS\Core\Page\PageRenderer\loadJavaScriptLanguageStrings
‪loadJavaScriptLanguageStrings()
Definition: PageRenderer.php:1470
‪TYPO3\CMS\Core\Page\PageRenderer\renderJavaScriptFiles
‪array string[] renderJavaScriptFiles()
Definition: PageRenderer.php:1683
‪TYPO3\CMS\Core\Page\PageRenderer\addGlobalCSSUrlsToInlineSettings
‪addGlobalCSSUrlsToInlineSettings()
Definition: PageRenderer.php:1502
‪TYPO3\CMS\Core\Page\PageRenderer\addJsFooterInlineCode
‪addJsFooterInlineCode($name, $block, $compress=true, $forceOnTop=false, bool $useNonce=false)
Definition: PageRenderer.php:914
‪TYPO3\CMS\Core\Page\PageRenderer\$headTag
‪string $headTag
Definition: PageRenderer.php:93
‪TYPO3\CMS\Core\Page\PageRenderer\renderAdditionalJavaScriptLibraries
‪array string[] renderAdditionalJavaScriptLibraries()
Definition: PageRenderer.php:1621
‪TYPO3\CMS\Core\Page\PageRenderer\$jsInline
‪array $jsInline
Definition: PageRenderer.php:101
‪TYPO3\CMS\Core\Page\PageRenderer\enableCompressJavascript
‪enableCompressJavascript()
Definition: PageRenderer.php:379
‪TYPO3\CMS\Core\Page\PageRenderer\doCompressCss
‪doCompressCss()
Definition: PageRenderer.php:1903
‪TYPO3\CMS\Core\Page\PageRenderer\getConcatenateCss
‪bool getConcatenateCss()
Definition: PageRenderer.php:576
‪TYPO3\CMS\Core\Page\PageRenderer\getIconMimeType
‪string getIconMimeType()
Definition: PageRenderer.php:516
‪TYPO3\CMS\Core\Page\PageRenderer\renderMainJavaScriptLibraries
‪string renderMainJavaScriptLibraries()
Definition: PageRenderer.php:1394
‪TYPO3\CMS\Core\Page\PageRenderer\$templateFile
‪string $templateFile
Definition: PageRenderer.php:109
‪TYPO3\CMS\Core\Page\PageRenderer\$title
‪string $title
Definition: PageRenderer.php:83
‪TYPO3\CMS\Core\Page\PageRenderer\getTemplateFile
‪string getTemplateFile()
Definition: PageRenderer.php:526
‪TYPO3\CMS\Core\Page\PageRenderer\renderCssFiles
‪string renderCssFiles()
Definition: PageRenderer.php:1535
‪TYPO3\CMS\Core\Page\PageRenderer\renderJavaScriptAndCss
‪array string[] renderJavaScriptAndCss()
Definition: PageRenderer.php:1253
‪TYPO3\CMS\Core\Page\PageRenderer\enableConcatenateCss
‪enableConcatenateCss()
Definition: PageRenderer.php:427
‪TYPO3\CMS\Core\Page\PageRenderer\$concatenateCss
‪bool $concatenateCss
Definition: PageRenderer.php:53
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static getPublicPath()
Definition: Environment.php:187
‪TYPO3\CMS\Core\Page\PageRenderer\getJavaScriptRenderer
‪getJavaScriptRenderer()
Definition: PageRenderer.php:208
‪TYPO3\CMS\Core\Utility\PathUtility\getRelativePathTo
‪static getRelativePathTo(string $absolutePath)
Definition: PathUtility.php:33
‪TYPO3\CMS\Core\Page\PageRenderer\getFavIcon
‪string getFavIcon()
Definition: PageRenderer.php:506
‪TYPO3\CMS\Core\Page\JavaScriptModuleInstruction\create
‪static create(string $name, string $exportName=null)
Definition: JavaScriptModuleInstruction.php:47
‪TYPO3\CMS\Core\Page\PageRenderer\addJsInlineCode
‪addJsInlineCode($name, $block, $compress=true, $forceOnTop=false, bool $useNonce=false)
Definition: PageRenderer.php:893
‪TYPO3\CMS\Core\Page\PageRenderer\$bodyContent
‪string $bodyContent
Definition: PageRenderer.php:108
‪TYPO3\CMS\Core\Page\PageRenderer\getState
‪getState()
Definition: PageRenderer.php:175
‪TYPO3\CMS\Core\Page\PageRenderer\updateState
‪updateState(array $state)
Definition: PageRenderer.php:143
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\ConsumableNonce
Definition: ConsumableNonce.php:24
‪TYPO3\CMS\Core\Page\PageRenderer\addCssInlineBlock
‪addCssInlineBlock($name, $block, $compress=false, $forceOnTop=false, bool $useNonce=false)
Definition: PageRenderer.php:1003
‪TYPO3\CMS\Core\Page\PageRenderer\PART_COMPLETE
‪const PART_COMPLETE
Definition: PageRenderer.php:46
‪TYPO3\CMS\Core\MetaTag\MetaTagManagerRegistry
Definition: MetaTagManagerRegistry.php:28
‪TYPO3\CMS\Core\Resource\ResourceCompressor
Definition: ResourceCompressor.php:31
‪TYPO3\CMS\Core\Page\PageRenderer\setHeadTag
‪setHeadTag($headTag)
Definition: PageRenderer.php:304
‪TYPO3\CMS\Core\Page
Definition: AssetCollector.php:18
‪TYPO3\CMS\Core\Page\PageRenderer\$inlineComments
‪array $inlineComments
Definition: PageRenderer.php:88
‪TYPO3\CMS\Core\Page\PageRenderer\doConcatenate
‪doConcatenate()
Definition: PageRenderer.php:1831
‪TYPO3\CMS\Core\Page\PageRenderer\getInlineLanguageLabelFiles
‪array getInlineLanguageLabelFiles()
Definition: PageRenderer.php:606
‪TYPO3\CMS\Core\Page\PageRenderer\$favIcon
‪string $favIcon
Definition: PageRenderer.php:84
‪TYPO3\CMS\Core\Page\PageRenderer\getTemplate
‪getTemplate()
Definition: PageRenderer.php:1378
‪TYPO3\CMS\Core\Page\PageRenderer\setApplyNonceHint
‪setApplyNonceHint(bool $applyNonceHint)
Definition: PageRenderer.php:349
‪TYPO3\CMS\Core\Page\PageRenderer\$jsFooterLibs
‪array $jsFooterLibs
Definition: PageRenderer.php:68
‪TYPO3\CMS\Core\Page\PageRenderer\$jsFiles
‪array $jsFiles
Definition: PageRenderer.php:65
‪TYPO3\CMS\Core\Page\PageRenderer\getBodyContent
‪string getBodyContent()
Definition: PageRenderer.php:586
‪TYPO3\CMS\Core\Page\PageRenderer\disableConcatenateJavascript
‪disableConcatenateJavascript()
Definition: PageRenderer.php:419
‪TYPO3\CMS\Core\Page\PageRenderer\getAbsoluteWebPath
‪getAbsoluteWebPath(string $file)
Definition: PageRenderer.php:2020
‪TYPO3\CMS\Core\Page\PageRenderer\doCompress
‪doCompress()
Definition: PageRenderer.php:1894
‪TYPO3\CMS\Core\Page\PageRenderer\getHtmlTag
‪string getHtmlTag()
Definition: PageRenderer.php:486
‪TYPO3\CMS\Core\Page\PageRenderer\$compressJavascript
‪bool $compressJavascript
Definition: PageRenderer.php:50
‪TYPO3\CMS\Core\Page\PageRenderer\getPreparedMarkerArrayForPageWithUncachedObjects
‪array getPreparedMarkerArrayForPageWithUncachedObjects($substituteHash)
Definition: PageRenderer.php:1346
‪TYPO3\CMS\Core\Page\PageRenderer\renderPageWithUncachedObjects
‪string renderPageWithUncachedObjects($substituteHash)
Definition: PageRenderer.php:1189
‪TYPO3\CMS\Core\Page\PageRenderer\setXmlPrologAndDocType
‪setXmlPrologAndDocType($xmlPrologAndDocType)
Definition: PageRenderer.php:258
‪TYPO3\CMS\Core\Page\PageRenderer\disableMoveJsFromHeaderToFooter
‪disableMoveJsFromHeaderToFooter()
Definition: PageRenderer.php:371
‪TYPO3\CMS\Core\Page\PageRenderer\addInlineSettingArray
‪addInlineSettingArray($namespace, array $array)
Definition: PageRenderer.php:1102
‪TYPO3\CMS\Core\Page\PageRenderer\renderCssLibraries
‪string renderCssLibraries()
Definition: PageRenderer.php:1514
‪TYPO3\CMS\Core\Page\PageRenderer\addInlineLanguageLabel
‪addInlineLanguageLabel($key, $value)
Definition: PageRenderer.php:1035
‪TYPO3\CMS\Core\Utility\PathUtility\getAbsoluteWebPath
‪static string getAbsoluteWebPath(string $targetPath, bool $prefixWithSitePath=true)
Definition: PathUtility.php:52
‪TYPO3\CMS\Core\Page\PageRenderer\setHtmlTag
‪setHtmlTag($htmlTag)
Definition: PageRenderer.php:294
‪TYPO3\CMS\Core\Page\PageRenderer\renderResponse
‪renderResponse(int $code=200, string $reasonPhrase='',)
Definition: PageRenderer.php:1153
‪TYPO3\CMS\Core\Page\PageRenderer\__construct
‪__construct(protected readonly FrontendInterface $assetsCache, protected readonly MarkerBasedTemplateService $templateService, protected readonly MetaTagManagerRegistry $metaTagRegistry, protected readonly AssetRenderer $assetRenderer, protected readonly ResourceCompressor $resourceCompressor, protected readonly RelativeCssPathFixer $relativeCssPathFixer, protected readonly LanguageServiceFactory $languageServiceFactory, protected readonly ResponseFactoryInterface $responseFactory, protected readonly StreamFactoryInterface $streamFactory,)
Definition: PageRenderer.php:124
‪TYPO3\CMS\Core\Page\PageRenderer\executePreRenderHook
‪executePreRenderHook()
Definition: PageRenderer.php:2036
‪TYPO3\CMS\Core\Page\PageRenderer\setBodyContent
‪setBodyContent($content)
Definition: PageRenderer.php:344
‪TYPO3\CMS\Core\Page\PageRenderer
Definition: PageRenderer.php:44
‪TYPO3\CMS\Core\Utility\PathUtility\dirname
‪static dirname(string $path)
Definition: PathUtility.php:243
‪TYPO3\CMS\Core\Page\PageRenderer\$htmlTag
‪string $htmlTag
Definition: PageRenderer.php:92
‪TYPO3\CMS\Core\Page\PageRenderer\getCompressCss
‪bool getCompressCss()
Definition: PageRenderer.php:556
‪TYPO3\CMS\Core\Page\PageRenderer\getApplicationType
‪getApplicationType()
Definition: PageRenderer.php:2197
‪TYPO3\CMS\Core\Page\PageRenderer\$applyNonceHint
‪bool $applyNonceHint
Definition: PageRenderer.php:122
‪TYPO3\CMS\Core\Page\PageRenderer\doCompressJavaScript
‪doCompressJavaScript()
Definition: PageRenderer.php:1930
‪TYPO3\CMS\Core\Page\PageRenderer\$jsFooterInline
‪array $jsFooterInline
Definition: PageRenderer.php:102
‪TYPO3\CMS\Core\Page\PageRenderer\addJsFooterLibrary
‪addJsFooterLibrary($name, $file, $type='', $compress=false, $forceOnTop=false, $allWrap='', $excludeFromConcatenation=false, $splitChar='|', $async=false, $integrity='', $defer=false, $crossorigin='', $nomodule=false, array $tagAttributes=[])
Definition: PageRenderer.php:775
‪TYPO3\CMS\Core\Utility\PathUtility\getPublicResourceWebPath
‪static getPublicResourceWebPath(string $resourcePath, bool $prefixWithSitePath=true)
Definition: PathUtility.php:97
‪TYPO3\CMS\Core\Page\PageRenderer\$concatenateJavascript
‪bool $concatenateJavascript
Definition: PageRenderer.php:52
‪TYPO3\CMS\Core\Page\PageRenderer\getTitle
‪string getTitle()
Definition: PageRenderer.php:451
‪TYPO3\CMS\Core\Page\PageRenderer\$endingSlash
‪string $endingSlash
Definition: PageRenderer.php:117
‪TYPO3\CMS\Core\Page\PageRenderer\setNonce
‪setNonce(?ConsumableNonce $nonce)
Definition: PageRenderer.php:464
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:44
‪TYPO3\CMS\Core\Page\PageRenderer\setLanguage
‪setLanguage(Locale $locale)
Definition: PageRenderer.php:266
‪TYPO3\CMS\Core\Page\PageRenderer\PART_FOOTER
‪const PART_FOOTER
Definition: PageRenderer.php:48
‪TYPO3\CMS\Core\Page\PageRenderer\addInlineLanguageLabelArray
‪addInlineLanguageLabelArray(array $array)
Definition: PageRenderer.php:1045
‪TYPO3\CMS\Core\Page\PageRenderer\setTitle
‪setTitle($title)
Definition: PageRenderer.php:248
‪TYPO3\CMS\Core\Page\PageRenderer\getInlineLanguageLabels
‪array getInlineLanguageLabels()
Definition: PageRenderer.php:596
‪TYPO3\CMS\Core\Page\PageRenderer\$xmlPrologAndDocType
‪string $xmlPrologAndDocType
Definition: PageRenderer.php:87
‪TYPO3\CMS\Core\Page\PageRenderer\$compressCss
‪bool $compressCss
Definition: PageRenderer.php:51
‪TYPO3\CMS\Core\Page\PageRenderer\getStreamlinedFileName
‪string getStreamlinedFileName($file, $prepareForOutput=true)
Definition: PageRenderer.php:1996
‪TYPO3\CMS\Core\Page\PageRenderer\$jsFooterFiles
‪array $jsFooterFiles
Definition: PageRenderer.php:66
‪TYPO3\CMS\Core\Page\PageRenderer\addCssFile
‪addCssFile($file, $rel='stylesheet', $media='all', $title='', $compress=true, $forceOnTop=false, $allWrap='', $excludeFromConcatenation=false, $splitChar='|', $inline=false, array $tagAttributes=[])
Definition: PageRenderer.php:942
‪TYPO3\CMS\Core\Page\PageRenderer\createInlineCssTagFromFile
‪createInlineCssTagFromFile(string $file, array $properties)
Definition: PageRenderer.php:2139
‪TYPO3\CMS\Core\Page\PageRenderer\addInlineComment
‪addInlineComment($comment)
Definition: PageRenderer.php:683
‪TYPO3\CMS\Core\Page\PageRenderer\loadJavaScriptModule
‪loadJavaScriptModule(string $specifier)
Definition: PageRenderer.php:1021
‪TYPO3\CMS\Core\Page\PageRenderer\$nonce
‪ConsumableNonce $nonce
Definition: PageRenderer.php:120
‪TYPO3\CMS\Core\Page\PageRenderer\$titleTag
‪string $titleTag
Definition: PageRenderer.php:91
‪TYPO3\CMS\Core\Page\PageRenderer\$shortcutTag
‪string $shortcutTag
Definition: PageRenderer.php:95
‪TYPO3\CMS\Core\Page\PageRenderer\doConcatenateJavaScript
‪doConcatenateJavaScript()
Definition: PageRenderer.php:1840
‪TYPO3\CMS\Core\Page\PageRenderer\render
‪string render()
Definition: PageRenderer.php:1140
‪TYPO3\CMS\Core\Page\PageRenderer\executePostRenderHook
‪executePostRenderHook(&$jsLibs, &$jsFiles, &$jsFooterFiles, &$cssLibs, &$cssFiles, &$jsInline, &$cssInline, &$jsFooterInline, &$jsFooterLibs)
Definition: PageRenderer.php:2100
‪TYPO3\CMS\Core\Page\PageRenderer\enableMoveJsFromHeaderToFooter
‪enableMoveJsFromHeaderToFooter()
Definition: PageRenderer.php:363
‪TYPO3\CMS\Core\Page\PageRenderer\processJsFile
‪string processJsFile($filename)
Definition: PageRenderer.php:1971
‪TYPO3\CMS\Core\Page\PageRenderer\getPreparedMarkerArray
‪array getPreparedMarkerArray($jsLibs, $jsFiles, $jsFooterFiles, $cssLibs, $cssFiles, $jsInline, $cssInline, $jsFooterInline, $jsFooterLibs, $metaTags)
Definition: PageRenderer.php:1311
‪TYPO3\CMS\Core\Page\PageRenderer\setIconMimeType
‪setIconMimeType($iconMimeType)
Definition: PageRenderer.php:324
‪TYPO3\CMS\Core\Page\PageRenderer\wrapInlineStyle
‪wrapInlineStyle(string $content, array $attributes=[])
Definition: PageRenderer.php:2164
‪TYPO3\CMS\Core\Page\PageRenderer\addJsFile
‪addJsFile($file, $type='', $compress=true, $forceOnTop=false, $allWrap='', $excludeFromConcatenation=false, $splitChar='|', $async=false, $integrity='', $defer=false, $crossorigin='', $nomodule=false, array $tagAttributes=[])
Definition: PageRenderer.php:818
‪TYPO3\CMS\Core\Page\PageRenderer\addHeaderData
‪addHeaderData($data)
Definition: PageRenderer.php:695
‪TYPO3\CMS\Core\Page\PageRenderer\createCssTag
‪createCssTag(array $properties, string $file)
Definition: PageRenderer.php:1554
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
Definition: FrontendInterface.php:22
‪TYPO3\CMS\Core\Page\PageRenderer\$inlineSettings
‪array $inlineSettings
Definition: PageRenderer.php:112
‪TYPO3\CMS\Core\Page\PageRenderer\$cssInline
‪array $cssInline
Definition: PageRenderer.php:107
‪TYPO3\CMS\Core\Page\PageRenderer\renderMetaTagsFromAPI
‪array renderMetaTagsFromAPI()
Definition: PageRenderer.php:1168
‪TYPO3\CMS\Core\Page\PageRenderer\$jsLibs
‪array $jsLibs
Definition: PageRenderer.php:67
‪TYPO3\CMS\Core\Page\PageRenderer\addJsFooterFile
‪addJsFooterFile($file, $type='', $compress=true, $forceOnTop=false, $allWrap='', $excludeFromConcatenation=false, $splitChar='|', $async=false, $integrity='', $defer=false, $crossorigin='', $nomodule=false, array $tagAttributes=[])
Definition: PageRenderer.php:860
‪TYPO3\CMS\Core\Page\PageRenderer\includeLanguageFileForInline
‪includeLanguageFileForInline($fileRef, $selectionPrefix='', $stripFromSelectionName='')
Definition: PageRenderer.php:1793
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:22
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Page\PageRenderer\$cssLibs
‪array $cssLibs
Definition: PageRenderer.php:78
‪TYPO3\CMS\Core\Page\PageRenderer\getHeadTag
‪string getHeadTag()
Definition: PageRenderer.php:496
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:41
‪TYPO3\CMS\Core\Page\PageRenderer\setDocType
‪setDocType(DocType $docType)
Definition: PageRenderer.php:469
‪TYPO3\CMS\Core\Page\PageRenderer\enableCompressCss
‪enableCompressCss()
Definition: PageRenderer.php:395
‪TYPO3\CMS\Core\Page\PageRenderer\doConcatenateCss
‪doConcatenateCss()
Definition: PageRenderer.php:1868
‪TYPO3\CMS\Core\Localization\Locale
Definition: Locale.php:30
‪TYPO3\CMS\Core\Page\PageRenderer\addFooterData
‪addFooterData($data)
Definition: PageRenderer.php:707
‪TYPO3\CMS\Core\Page\PageRenderer\addInlineSetting
‪addInlineSetting($namespace, $key, $value)
Definition: PageRenderer.php:1077
‪TYPO3\CMS\Core\Page\PageRenderer\removeMetaTag
‪removeMetaTag(string $type, string $name)
Definition: PageRenderer.php:668
‪TYPO3\CMS\Core\Page\PageRenderer\executeRenderPostTransformHook
‪executeRenderPostTransformHook()
Definition: PageRenderer.php:2063
‪TYPO3\CMS\Core\Page\AssetRenderer
Definition: AssetRenderer.php:31
‪TYPO3\CMS\Core\Page\PageRenderer\prepareRendering
‪prepareRendering()
Definition: PageRenderer.php:1238
‪TYPO3\CMS\Core\Page\PageRenderer\getDocType
‪getDocType()
Definition: PageRenderer.php:476
‪TYPO3\CMS\Core\Page\PageRenderer\$iconMimeType
‪string $iconMimeType
Definition: PageRenderer.php:94
‪TYPO3\CMS\Core\Type\DocType
‪DocType
Definition: DocType.php:27
‪TYPO3\CMS\Core\Http\fromRequest
‪@ fromRequest
Definition: ApplicationType.php:66
‪TYPO3\CMS\Core\Page\PageRenderer\disableCompressCss
‪disableCompressCss()
Definition: PageRenderer.php:403
‪TYPO3\CMS\Core\Page\PageRenderer\setTemplateFile
‪setTemplateFile($file)
Definition: PageRenderer.php:334
‪TYPO3\CMS\Core\Page\PageRenderer\addBodyContent
‪addBodyContent($content)
Definition: PageRenderer.php:1125
‪TYPO3\CMS\Core\Service\MarkerBasedTemplateService
Definition: MarkerBasedTemplateService.php:27
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Page\PageRenderer\$headerData
‪array $headerData
Definition: PageRenderer.php:89
‪TYPO3\CMS\Core\Page\PageRenderer\getCompressJavascript
‪bool getCompressJavascript()
Definition: PageRenderer.php:546
‪TYPO3\CMS\Core\Page\PageRenderer\setMetaTag
‪setMetaTag(string $type, string $name, string $content, array $subProperties=[], $replace=true)
Definition: PageRenderer.php:628
‪TYPO3\CMS\Core\Page\PageRenderer\disableConcatenateCss
‪disableConcatenateCss()
Definition: PageRenderer.php:435
‪TYPO3\CMS\Backend\Routing\Router
Definition: Router.php:40
‪TYPO3\CMS\Core\Page\PageRenderer\addAjaxUrlsToInlineSettings
‪addAjaxUrlsToInlineSettings(bool $publicRoutesOnly=false)
Definition: PageRenderer.php:1481
‪TYPO3\CMS\Core\Page\PageRenderer\renderInlineJavaScript
‪array string[] renderInlineJavaScript()
Definition: PageRenderer.php:1745
‪TYPO3\CMS\Core\Page\PageRenderer\PART_HEADER
‪const PART_HEADER
Definition: PageRenderer.php:47
‪TYPO3\CMS\Core\Page\PageRenderer\getMetaTag
‪getMetaTag(string $type, string $name)
Definition: PageRenderer.php:646
‪TYPO3\CMS\Core\Page\PageRenderer\reset
‪reset()
Definition: PageRenderer.php:216
‪TYPO3\CMS\Core\Page\PageRenderer\addCssLibrary
‪addCssLibrary($file, $rel='stylesheet', $media='all', $title='', $compress=true, $forceOnTop=false, $allWrap='', $excludeFromConcatenation=false, $splitChar='|', $inline=false, array $tagAttributes=[])
Definition: PageRenderer.php:976
‪TYPO3\CMS\Core\Page\PageRenderer\parseLanguageLabelsForJavaScript
‪parseLanguageLabelsForJavaScript()
Definition: PageRenderer.php:1448
‪TYPO3\CMS\Core\Page\PageRenderer\$inlineLanguageLabelFiles
‪array $inlineLanguageLabelFiles
Definition: PageRenderer.php:111
‪TYPO3\CMS\Core\Page\PageRenderer\getMoveJsFromHeaderToFooter
‪bool getMoveJsFromHeaderToFooter()
Definition: PageRenderer.php:536
‪TYPO3\CMS\Core\Page\PageRenderer\$footerData
‪array $footerData
Definition: PageRenderer.php:90
‪TYPO3\CMS\Core\Page\PageRenderer\getConcatenateJavascript
‪bool getConcatenateJavascript()
Definition: PageRenderer.php:566
‪TYPO3\CMS\Core\Page\PageRenderer\$locale
‪Locale $locale
Definition: PageRenderer.php:59
‪TYPO3\CMS\Core\Http\ApplicationType
‪ApplicationType
Definition: ApplicationType.php:55
‪TYPO3\CMS\Core\Resource\RelativeCssPathFixer
Definition: RelativeCssPathFixer.php:29
‪TYPO3\CMS\Core\Page\PageRenderer\getLanguage
‪getLanguage()
Definition: PageRenderer.php:459
‪TYPO3\CMS\Core\Page\PageRenderer\wrapInlineScript
‪wrapInlineScript(string $content, array $attributes=[])
Definition: PageRenderer.php:2174
‪TYPO3\CMS\Core\Page\PageRenderer\$docType
‪DocType $docType
Definition: PageRenderer.php:121
‪TYPO3\CMS\Core\Page\PageRenderer\$moveJsFromHeaderToFooter
‪bool $moveJsFromHeaderToFooter
Definition: PageRenderer.php:54