‪TYPO3CMS  10.4
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 
28 use TYPO3\CMS\Core\Package\PackageManager;
36 
42 {
43  // Constants for the part to be rendered
44  const ‪PART_COMPLETE = 0;
45  const ‪PART_HEADER = 1;
46  const ‪PART_FOOTER = 2;
47 
48  const ‪REQUIREJS_SCOPE_CONFIG = 'config';
49  const ‪REQUIREJS_SCOPE_RESOLVE = 'resolve';
50 
54  protected ‪$compressJavascript = false;
55 
59  protected ‪$compressCss = false;
60 
64  protected ‪$removeLineBreaksFromTemplate = false;
65 
69  protected ‪$concatenateJavascript = false;
70 
74  protected ‪$concatenateCss = false;
75 
79  protected ‪$moveJsFromHeaderToFooter = false;
80 
84  protected ‪$locales;
85 
92  protected ‪$lang;
93 
100  protected ‪$languageDependencies = [];
101 
105  protected ‪$compressor;
106 
107  // Arrays containing associative array for the included files
111  protected $jsFiles = [];
112 
116  protected $jsFooterFiles = [];
117 
121  protected $jsLibs = [];
122 
126  protected $jsFooterLibs = [];
127 
131  protected $cssFiles = [];
132 
136  protected $cssLibs = [];
137 
143  protected $title;
144 
150  protected $charSet;
151 
155  protected $favIcon;
156 
160  protected $baseUrl;
161 
165  protected $renderXhtml = true;
166 
167  // Static header blocks
171  protected $xmlPrologAndDocType = '';
172 
176  protected $metaTags = [];
177 
181  protected $inlineComments = [];
182 
186  protected $headerData = [];
187 
191  protected $footerData = [];
192 
196  protected $titleTag = '<title>|</title>';
197 
201  protected $metaCharsetTag = '<meta http-equiv="Content-Type" content="text/html; charset=|" />';
202 
206  protected $htmlTag = '<html>';
207 
211  protected $headTag = '<head>';
212 
216  protected $baseUrlTag = '<base href="|" />';
217 
221  protected $iconMimeType = '';
222 
226  protected $shortcutTag = '<link rel="shortcut icon" href="%1$s"%2$s />';
227 
228  // Static inline code blocks
232  protected $jsInline = [];
233 
237  protected $jsFooterInline = [];
238 
242  protected $cssInline = [];
243 
247  protected $bodyContent;
248 
252  protected $templateFile;
253 
254  // Paths to contributed libraries
255 
260  protected $requireJsPath = 'EXT:core/Resources/Public/JavaScript/Contrib/';
261 
262  // Internal flags for JS-libraries
267  protected $addRequireJs = false;
268 
273  protected $requireJsConfig = [];
274 
279  protected $internalRequireJsPathModuleNames = [];
280 
285  protected $publicRequireJsConfig = [];
286 
290  protected $inlineLanguageLabels = [];
291 
295  protected $inlineLanguageLabelFiles = [];
296 
300  protected $inlineSettings = [];
301 
305  protected $inlineJavascriptWrap = [
306  '<script type="text/javascript">' . LF . '/*<![CDATA[*/' . LF,
307  '/*]]>*/' . LF . '</script>' . LF
308  ];
309 
313  protected $inlineCssWrap = [
314  '<style type="text/css">' . LF . '/*<![CDATA[*/' . LF . '<!-- ' . LF,
315  '-->' . LF . '/*]]>*/' . LF . '</style>' . LF
316  ];
317 
323  protected $compressError = '';
324 
330  protected $endingSlash = '';
331 
335  protected $metaTagRegistry;
336 
340  protected static $cache = null;
341 
345  public function __construct($templateFile = '')
346  {
347  $this->‪reset();
348  $this->locales = GeneralUtility::makeInstance(Locales::class);
349  if ($templateFile !== '') {
350  $this->templateFile = $templateFile;
351  }
352 
353  $this->metaTagRegistry = GeneralUtility::makeInstance(MetaTagManagerRegistry::class);
354  $this->‪setMetaTag('name', 'generator', 'TYPO3 CMS');
355  }
356 
361  public function ‪updateState(array $newState): void
362  {
363  foreach ($newState as $var => $value) {
364  switch ($var) {
365  case 'locales':
366  break;
367  case 'metaTagRegistry':
368  $this->metaTagRegistry->updateState($value);
369  break;
370  default:
371  $this->{$var} = $value;
372  break;
373  }
374  }
375  }
376 
381  public function ‪getState(): array
382  {
383  $state = [];
384  foreach (get_object_vars($this) as $var => $value) {
385  switch ($var) {
386  case 'locales':
387  break;
388  case 'metaTagRegistry':
389  $state[$var] = $this->metaTagRegistry->getState();
390  break;
391  default:
392  $state[$var] = $value;
393  break;
394  }
395  }
396  return $state;
397  }
398 
402  public static function ‪setCache(FrontendInterface $cache)
403  {
404  static::$cache = $cache;
405  }
406 
410  protected function ‪reset()
411  {
412  $this->templateFile = 'EXT:core/Resources/Private/Templates/PageRenderer.html';
413  $this->jsFiles = [];
414  $this->jsFooterFiles = [];
415  $this->jsInline = [];
416  $this->jsFooterInline = [];
417  $this->jsLibs = [];
418  $this->cssFiles = [];
419  $this->cssInline = [];
420  $this->metaTags = [];
421  $this->inlineComments = [];
422  $this->headerData = [];
423  $this->footerData = [];
424  }
425 
426  /*****************************************************/
427  /* */
428  /* Public Setters */
429  /* */
430  /* */
431  /*****************************************************/
437  public function ‪setTitle($title)
438  {
439  $this->title = $title;
440  }
441 
447  public function ‪setRenderXhtml($enable)
448  {
449  $this->renderXhtml = $enable;
450 
451  // Whenever XHTML gets disabled, remove the "text/javascript" type from the wrap
452  // since this is not needed and may lead to validation errors in the future.
453  $this->inlineJavascriptWrap = [
454  '<script' . ($enable ? ' type="text/javascript" ' : '') . '>' . LF . '/*<![CDATA[*/' . LF,
455  '/*]]>*/' . LF . '</script>' . LF
456  ];
457  }
458 
464  public function ‪setXmlPrologAndDocType($xmlPrologAndDocType)
465  {
466  $this->xmlPrologAndDocType = $xmlPrologAndDocType;
467  }
468 
474  public function ‪setCharSet($charSet)
475  {
476  $this->charSet = $charSet;
477  }
478 
484  public function ‪setLanguage(‪$lang)
485  {
486  $this->lang = ‪$lang;
487  $this->languageDependencies = [];
488 
489  // Language is found. Configure it:
490  if (in_array($this->lang, $this->locales->getLocales())) {
491  $this->languageDependencies[] = ‪$this->lang;
492  foreach ($this->locales->getLocaleDependencies($this->lang) as $language) {
493  $this->languageDependencies[] = $language;
494  }
495  }
496  }
497 
503  public function ‪setMetaCharsetTag($metaCharsetTag)
504  {
505  $this->metaCharsetTag = $metaCharsetTag;
506  }
507 
513  public function ‪setHtmlTag($htmlTag)
514  {
515  $this->htmlTag = $htmlTag;
516  }
517 
523  public function ‪setHeadTag($headTag)
524  {
525  $this->headTag = $headTag;
526  }
527 
533  public function ‪setFavIcon($favIcon)
534  {
535  $this->favIcon = $favIcon;
536  }
537 
543  public function ‪setIconMimeType($iconMimeType)
544  {
545  $this->iconMimeType = $iconMimeType;
546  }
547 
553  public function ‪setBaseUrl($baseUrl)
554  {
555  $this->baseUrl = $baseUrl;
556  }
557 
563  public function ‪setTemplateFile($file)
564  {
565  $this->templateFile = $file;
566  }
567 
573  public function ‪setBodyContent($content)
574  {
575  $this->bodyContent = $content;
576  }
577 
583  public function ‪setRequireJsPath($path)
584  {
585  $this->requireJsPath = $path;
586  }
587 
592  public function ‪getRequireJsConfig(string $scope = null): array
593  {
594  // return basic RequireJS configuration without shim, paths and packages
595  if ($scope === static::REQUIREJS_SCOPE_CONFIG) {
596  return array_replace_recursive(
597  $this->publicRequireJsConfig,
598  $this->‪filterArrayKeys(
599  $this->requireJsConfig,
600  ['shim', 'paths', 'packages'],
601  false
602  )
603  );
604  }
605  // return RequireJS configuration for resolving only shim, paths and packages
606  if ($scope === static::REQUIREJS_SCOPE_RESOLVE) {
607  return $this->‪filterArrayKeys(
608  $this->requireJsConfig,
609  ['shim', 'paths', 'packages'],
610  true
611  );
612  }
613  return [];
614  }
615 
616  /*****************************************************/
617  /* */
618  /* Public Enablers / Disablers */
619  /* */
620  /* */
621  /*****************************************************/
625  public function ‪enableMoveJsFromHeaderToFooter()
626  {
627  $this->moveJsFromHeaderToFooter = true;
628  }
629 
633  public function ‪disableMoveJsFromHeaderToFooter()
634  {
635  $this->moveJsFromHeaderToFooter = false;
636  }
637 
641  public function ‪enableCompressJavascript()
642  {
643  $this->compressJavascript = true;
644  }
645 
649  public function ‪disableCompressJavascript()
650  {
651  $this->compressJavascript = false;
652  }
653 
657  public function ‪enableCompressCss()
658  {
659  $this->compressCss = true;
660  }
661 
665  public function ‪disableCompressCss()
666  {
667  $this->compressCss = false;
668  }
669 
673  public function ‪enableConcatenateJavascript()
674  {
675  $this->concatenateJavascript = true;
676  }
677 
681  public function ‪disableConcatenateJavascript()
682  {
683  $this->concatenateJavascript = false;
684  }
685 
689  public function ‪enableConcatenateCss()
690  {
691  $this->concatenateCss = true;
692  }
693 
697  public function ‪disableConcatenateCss()
698  {
699  $this->concatenateCss = false;
700  }
701 
705  public function ‪enableRemoveLineBreaksFromTemplate()
706  {
707  $this->removeLineBreaksFromTemplate = true;
708  }
709 
714  {
715  $this->removeLineBreaksFromTemplate = false;
716  }
717 
722  public function ‪enableDebugMode()
723  {
724  $this->compressJavascript = false;
725  $this->compressCss = false;
726  $this->concatenateCss = false;
727  $this->concatenateJavascript = false;
728  $this->removeLineBreaksFromTemplate = false;
729  }
730 
731  /*****************************************************/
732  /* */
733  /* Public Getters */
734  /* */
735  /* */
736  /*****************************************************/
742  public function ‪getTitle()
743  {
744  return $this->title;
745  }
746 
752  public function ‪getCharSet()
753  {
754  return $this->charSet;
755  }
756 
762  public function ‪getLanguage()
763  {
764  return ‪$this->lang;
765  }
766 
772  public function ‪getRenderXhtml()
773  {
774  return $this->renderXhtml;
775  }
776 
782  public function ‪getHtmlTag()
783  {
784  return $this->htmlTag;
785  }
786 
792  public function ‪getMetaCharsetTag()
793  {
794  return $this->metaCharsetTag;
795  }
796 
802  public function ‪getHeadTag()
803  {
804  return $this->headTag;
805  }
806 
812  public function ‪getFavIcon()
813  {
814  return $this->favIcon;
815  }
816 
822  public function ‪getIconMimeType()
823  {
824  return $this->iconMimeType;
825  }
826 
832  public function ‪getBaseUrl()
833  {
834  return $this->baseUrl;
835  }
836 
842  public function ‪getTemplateFile()
843  {
844  return $this->templateFile;
845  }
846 
852  public function ‪getMoveJsFromHeaderToFooter()
853  {
855  }
856 
862  public function ‪getCompressJavascript()
863  {
865  }
866 
872  public function ‪getCompressCss()
873  {
874  return ‪$this->compressCss;
875  }
876 
882  public function ‪getConcatenateJavascript()
883  {
885  }
886 
892  public function ‪getConcatenateCss()
893  {
895  }
896 
903  {
905  }
906 
912  public function ‪getBodyContent()
913  {
914  return $this->bodyContent;
915  }
916 
922  public function ‪getInlineLanguageLabels()
923  {
924  return $this->inlineLanguageLabels;
925  }
926 
932  public function ‪getInlineLanguageLabelFiles()
933  {
934  return $this->inlineLanguageLabelFiles;
935  }
936 
937  /*****************************************************/
938  /* */
939  /* Public Functions to add Data */
940  /* */
941  /* */
942  /*****************************************************/
943 
954  public function ‪setMetaTag(string $type, string $name, string $content, array $subProperties = [], $replace = true)
955  {
956  // Lowercase all the things
957  $type = strtolower($type);
958  $name = strtolower($name);
959  if (!in_array($type, ['property', 'name', 'http-equiv'], true)) {
960  throw new \InvalidArgumentException(
961  'When setting a meta tag the only types allowed are property, name or http-equiv. "' . $type . '" given.',
962  1496402460
963  );
964  }
965  $manager = $this->metaTagRegistry->getManagerForProperty($name);
966  $manager->addProperty($name, $content, $subProperties, $replace, $type);
967  }
968 
977  public function ‪getMetaTag(string $type, string $name): array
978  {
979  // Lowercase all the things
980  $type = strtolower($type);
981  $name = strtolower($name);
982 
983  $manager = $this->metaTagRegistry->getManagerForProperty($name);
984  $propertyContent = $manager->getProperty($name, $type);
985 
986  if (!empty($propertyContent[0])) {
987  return [
988  'type' => $type,
989  'name' => $name,
990  'content' => $propertyContent[0]['content']
991  ];
992  }
993  return [];
994  }
995 
1002  public function ‪removeMetaTag(string $type, string $name)
1003  {
1004  // Lowercase all the things
1005  $type = strtolower($type);
1006  $name = strtolower($name);
1007 
1008  $manager = $this->metaTagRegistry->getManagerForProperty($name);
1009  $manager->removeProperty($name, $type);
1010  }
1011 
1017  public function ‪addInlineComment($comment)
1018  {
1019  if (!in_array($comment, $this->inlineComments)) {
1020  $this->inlineComments[] = $comment;
1021  }
1022  }
1023 
1029  public function ‪addHeaderData($data)
1030  {
1031  if (!in_array($data, $this->headerData)) {
1032  $this->headerData[] = $data;
1033  }
1034  }
1035 
1041  public function ‪addFooterData($data)
1042  {
1043  if (!in_array($data, $this->footerData)) {
1044  $this->footerData[] = $data;
1045  }
1046  }
1047 
1065  public function ‪addJsLibrary($name, $file, $type = 'text/javascript', $compress = false, $forceOnTop = false, $allWrap = '', $excludeFromConcatenation = false, $splitChar = '|', $async = false, $integrity = '', $defer = false, $crossorigin = '', $nomodule = false)
1066  {
1067  if (!in_array(strtolower($name), $this->jsLibs)) {
1068  $this->jsLibs[strtolower($name)] = [
1069  'file' => $file,
1070  'type' => $type,
1071  'section' => ‪self::PART_HEADER,
1072  'compress' => $compress,
1073  'forceOnTop' => $forceOnTop,
1074  'allWrap' => $allWrap,
1075  'excludeFromConcatenation' => $excludeFromConcatenation,
1076  'splitChar' => $splitChar,
1077  'async' => $async,
1078  'integrity' => $integrity,
1079  'defer' => $defer,
1080  'crossorigin' => $crossorigin,
1081  'nomodule' => $nomodule,
1082  ];
1083  }
1084  }
1085 
1103  public function ‪addJsFooterLibrary($name, $file, $type = 'text/javascript', $compress = false, $forceOnTop = false, $allWrap = '', $excludeFromConcatenation = false, $splitChar = '|', $async = false, $integrity = '', $defer = false, $crossorigin = '', $nomodule = false)
1104  {
1105  $name .= '_jsFooterLibrary';
1106  if (!in_array(strtolower($name), $this->jsLibs)) {
1107  $this->jsLibs[strtolower($name)] = [
1108  'file' => $file,
1109  'type' => $type,
1110  'section' => ‪self::PART_FOOTER,
1111  'compress' => $compress,
1112  'forceOnTop' => $forceOnTop,
1113  'allWrap' => $allWrap,
1114  'excludeFromConcatenation' => $excludeFromConcatenation,
1115  'splitChar' => $splitChar,
1116  'async' => $async,
1117  'integrity' => $integrity,
1118  'defer' => $defer,
1119  'crossorigin' => $crossorigin,
1120  'nomodule' => $nomodule,
1121  ];
1122  }
1123  }
1124 
1141  public function ‪addJsFile($file, $type = 'text/javascript', $compress = true, $forceOnTop = false, $allWrap = '', $excludeFromConcatenation = false, $splitChar = '|', $async = false, $integrity = '', $defer = false, $crossorigin = '', $nomodule = false)
1142  {
1143  if (!isset($this->jsFiles[$file])) {
1144  $this->jsFiles[$file] = [
1145  'file' => $file,
1146  'type' => $type,
1147  'section' => ‪self::PART_HEADER,
1148  'compress' => $compress,
1149  'forceOnTop' => $forceOnTop,
1150  'allWrap' => $allWrap,
1151  'excludeFromConcatenation' => $excludeFromConcatenation,
1152  'splitChar' => $splitChar,
1153  'async' => $async,
1154  'integrity' => $integrity,
1155  'defer' => $defer,
1156  'crossorigin' => $crossorigin,
1157  'nomodule' => $nomodule,
1158  ];
1159  }
1160  }
1161 
1178  public function ‪addJsFooterFile($file, $type = 'text/javascript', $compress = true, $forceOnTop = false, $allWrap = '', $excludeFromConcatenation = false, $splitChar = '|', $async = false, $integrity = '', $defer = false, $crossorigin = '', $nomodule = false)
1179  {
1180  if (!isset($this->jsFiles[$file])) {
1181  $this->jsFiles[$file] = [
1182  'file' => $file,
1183  'type' => $type,
1184  'section' => ‪self::PART_FOOTER,
1185  'compress' => $compress,
1186  'forceOnTop' => $forceOnTop,
1187  'allWrap' => $allWrap,
1188  'excludeFromConcatenation' => $excludeFromConcatenation,
1189  'splitChar' => $splitChar,
1190  'async' => $async,
1191  'integrity' => $integrity,
1192  'defer' => $defer,
1193  'crossorigin' => $crossorigin,
1194  'nomodule' => $nomodule,
1195  ];
1196  }
1197  }
1198 
1207  public function ‪addJsInlineCode($name, $block, $compress = true, $forceOnTop = false)
1208  {
1209  if (!isset($this->jsInline[$name]) && !empty($block)) {
1210  $this->jsInline[$name] = [
1211  'code' => $block . LF,
1212  'section' => ‪self::PART_HEADER,
1213  'compress' => $compress,
1214  'forceOnTop' => $forceOnTop
1215  ];
1216  }
1217  }
1218 
1227  public function ‪addJsFooterInlineCode($name, $block, $compress = true, $forceOnTop = false)
1228  {
1229  if (!isset($this->jsInline[$name]) && !empty($block)) {
1230  $this->jsInline[$name] = [
1231  'code' => $block . LF,
1232  'section' => ‪self::PART_FOOTER,
1233  'compress' => $compress,
1234  'forceOnTop' => $forceOnTop
1235  ];
1236  }
1237  }
1238 
1253  public function ‪addCssFile($file, $rel = 'stylesheet', $media = 'all', $title = '', $compress = true, $forceOnTop = false, $allWrap = '', $excludeFromConcatenation = false, $splitChar = '|', $inline = false)
1254  {
1255  if (!isset($this->cssFiles[$file])) {
1256  $this->cssFiles[$file] = [
1257  'file' => $file,
1258  'rel' => $rel,
1259  'media' => $media,
1260  'title' => $title,
1261  'compress' => $compress,
1262  'forceOnTop' => $forceOnTop,
1263  'allWrap' => $allWrap,
1264  'excludeFromConcatenation' => $excludeFromConcatenation,
1265  'splitChar' => $splitChar,
1266  'inline' => $inline
1267  ];
1268  }
1269  }
1270 
1285  public function ‪addCssLibrary($file, $rel = 'stylesheet', $media = 'all', $title = '', $compress = true, $forceOnTop = false, $allWrap = '', $excludeFromConcatenation = false, $splitChar = '|', $inline = false)
1286  {
1287  if (!isset($this->cssLibs[$file])) {
1288  $this->cssLibs[$file] = [
1289  'file' => $file,
1290  'rel' => $rel,
1291  'media' => $media,
1292  'title' => $title,
1293  'compress' => $compress,
1294  'forceOnTop' => $forceOnTop,
1295  'allWrap' => $allWrap,
1296  'excludeFromConcatenation' => $excludeFromConcatenation,
1297  'splitChar' => $splitChar,
1298  'inline' => $inline
1299  ];
1300  }
1301  }
1302 
1311  public function ‪addCssInlineBlock($name, $block, $compress = false, $forceOnTop = false)
1312  {
1313  if (!isset($this->cssInline[$name]) && !empty($block)) {
1314  $this->cssInline[$name] = [
1315  'code' => $block,
1316  'compress' => $compress,
1317  'forceOnTop' => $forceOnTop
1318  ];
1319  }
1320  }
1321 
1328  public function ‪loadRequireJs()
1329  {
1330  $this->addRequireJs = true;
1331  if (!empty($this->requireJsConfig) && !empty($this->publicRequireJsConfig)) {
1332  return;
1333  }
1334 
1335  $packages = GeneralUtility::makeInstance(PackageManager::class)->getActivePackages();
1336  $isDevelopment = ‪Environment::getContext()->‪isDevelopment();
1337  $cacheIdentifier = 'requireJS_' . sha1((string)(new Typo3Version()) . ‪Environment::getProjectPath() . implode(',', array_keys($packages)) . ($isDevelopment ? ':dev' : '') . GeneralUtility::getIndpEnv('TYPO3_REQUEST_SCRIPT'));
1339  $cache = static::$cache ?? GeneralUtility::makeInstance(CacheManager::class)->getCache('assets');
1340  $requireJsConfig = $cache->‪get($cacheIdentifier);
1341 
1342  // if we did not get a configuration from the cache, compute and store it in the cache
1343  if (!isset($requireJsConfig['internal']) || !isset($requireJsConfig['public'])) {
1344  $requireJsConfig = $this->‪computeRequireJsConfig($isDevelopment, $packages);
1345  $cache->‪set($cacheIdentifier, $requireJsConfig);
1346  }
1347 
1348  $this->requireJsConfig = $requireJsConfig['internal'];
1349  $this->publicRequireJsConfig = $requireJsConfig['public'];
1350  $this->internalRequireJsPathModuleNames = $requireJsConfig['internalNames'];
1351  }
1352 
1361  protected function ‪computeRequireJsConfig($isDevelopment, array $packages)
1362  {
1363  // load all paths to map to package names / namespaces
1364  $requireJsConfig = [
1365  'public' => [],
1366  'internal' => [],
1367  'internalNames' => [],
1368  ];
1369 
1370  $corePath = $packages['core']->getPackagePath() . 'Resources/Public/JavaScript/Contrib/';
1371  $corePath = ‪PathUtility::getAbsoluteWebPath($corePath);
1372  // first, load all paths for the namespaces, and configure contrib libs.
1373  $requireJsConfig['public']['paths'] = [
1374  'jquery' => $corePath . 'jquery/jquery',
1375  'jquery-ui' => $corePath . 'jquery-ui',
1376  'nprogress' => $corePath . 'nprogress',
1377  'moment' => $corePath . 'moment',
1378  'cropper' => $corePath . 'cropper.min',
1379  'imagesloaded' => $corePath . 'imagesloaded.pkgd.min',
1380  'bootstrap' => $corePath . 'bootstrap/bootstrap',
1381  'twbs/bootstrap-datetimepicker' => $corePath . 'bootstrap-datetimepicker',
1382  'autosize' => $corePath . 'autosize',
1383  'taboverride' => $corePath . 'taboverride.min',
1384  'jquery/autocomplete' => $corePath . 'jquery.autocomplete',
1385  'jquery/minicolors' => $corePath . 'jquery.minicolors',
1386  'd3' => $corePath . 'd3/d3',
1387  'Sortable' => $corePath . 'Sortable.min',
1388  'sortablejs' => $corePath . 'Sortable.min',
1389  'tablesort' => $corePath . 'tablesort',
1390  'tablesort.dotsep' => $corePath . 'tablesort.dotsep',
1391  'broadcastchannel' => $corePath . 'broadcastchannel-polyfill',
1392  ];
1393  $requireJsConfig['public']['shim'] = [
1394  'tablesort.dotsep' => ['deps' => ['tablesort']],
1395  ];
1396  $requireJsConfig['public']['waitSeconds'] = 30;
1397  $requireJsConfig['public']['typo3BaseUrl'] = false;
1398  $publicPackageNames = ['core', 'frontend', 'backend'];
1399  $requireJsExtensionVersions = [];
1400  foreach ($packages as $packageName => $package) {
1401  $absoluteJsPath = $package->getPackagePath() . 'Resources/Public/JavaScript/';
1402  $fullJsPath = ‪PathUtility::getAbsoluteWebPath($absoluteJsPath);
1403  $fullJsPath = rtrim($fullJsPath, '/');
1404  if (!empty($fullJsPath) && file_exists($absoluteJsPath)) {
1405  $type = in_array($packageName, $publicPackageNames, true) ? 'public' : 'internal';
1406  $requireJsConfig[$type]['paths']['TYPO3/CMS/' . ‪GeneralUtility::underscoredToUpperCamelCase($packageName)] = $fullJsPath;
1407  $requireJsExtensionVersions[] = $package->getPackageKey() . ':' . $package->getPackageMetadata()->getVersion();
1408  }
1409  }
1410  // sanitize module names in internal 'paths'
1411  $internalPathModuleNames = array_keys($requireJsConfig['internal']['paths'] ?? []);
1412  $sanitizedInternalPathModuleNames = array_map(
1413  function ($moduleName) {
1414  // trim spaces and slashes & add ending slash
1415  return trim($moduleName, ' /') . '/';
1416  },
1417  $internalPathModuleNames
1418  );
1419  $requireJsConfig['internalNames'] = array_combine(
1420  $sanitizedInternalPathModuleNames,
1421  $internalPathModuleNames
1422  );
1423 
1424  // Add a GET parameter to the files loaded via requireJS in order to avoid browser caching of JS files
1425  if ($isDevelopment) {
1426  $requireJsConfig['public']['urlArgs'] = 'bust=' . ‪$GLOBALS['EXEC_TIME'];
1427  } else {
1428  $requireJsConfig['public']['urlArgs'] = 'bust=' . GeneralUtility::hmac(
1429  ‪Environment::getProjectPath() . implode('|', $requireJsExtensionVersions)
1430  );
1431  }
1432 
1433  // check if additional AMD modules need to be loaded if a single AMD module is initialized
1434  if (is_array(‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['RequireJS']['postInitializationModules'] ?? false)) {
1435  $this->‪addInlineSettingArray(
1436  'RequireJS.PostInitializationModules',
1437  ‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['RequireJS']['postInitializationModules']
1438  );
1439  }
1440 
1441  return $requireJsConfig;
1442  }
1443 
1456  public function ‪addRequireJsConfiguration(array $configuration)
1457  {
1458  if (TYPO3_MODE === 'BE') {
1459  // Load RequireJS in backend context at first. Doing this in FE could break the output
1460  $this->‪loadRequireJs();
1461  }
1462  $this->requireJsConfig = array_merge_recursive($this->requireJsConfig, $configuration);
1463  }
1464 
1471  protected function ‪getRequireJsLoader(): string
1472  {
1473  $html = '';
1474  $backendRequest = TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_BE;
1475  $backendUserLoggedIn = !empty(‪$GLOBALS['BE_USER']->user['uid']);
1476 
1477  // no backend request - basically frontend
1478  if (!$backendRequest) {
1479  $requireJsConfig = $this->‪getRequireJsConfig(static::REQUIREJS_SCOPE_CONFIG);
1480  $requireJsConfig['typo3BaseUrl'] = GeneralUtility::getIndpEnv('TYPO3_SITE_PATH') . '?eID=requirejs';
1481  // backend request, but no backend user logged in
1482  } elseif (!$backendUserLoggedIn) {
1483  $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
1484  $requireJsConfig = $this->‪getRequireJsConfig(static::REQUIREJS_SCOPE_CONFIG);
1485  $requireJsConfig['typo3BaseUrl'] = (string)$uriBuilder->buildUriFromRoute('ajax_core_requirejs');
1486  // backend request, having backend user logged in
1487  } else {
1488  $requireJsConfig = array_replace_recursive(
1489  $this->publicRequireJsConfig,
1490  $this->requireJsConfig
1491  );
1492  }
1494  // add (probably filtered) RequireJS configuration
1495  $html .= GeneralUtility::wrapJS('var require = ' . json_encode($requireJsConfig)) . LF;
1496  // directly after that, include the require.js file
1497  $html .= '<script src="'
1498  . $this->‪processJsFile($this->requireJsPath . 'require.js')
1499  . '"></script>' . LF;
1500 
1501  if (!empty($requireJsConfig['typo3BaseUrl'])) {
1502  $html .= '<script src="'
1503  . $this->‪processJsFile(
1504  'EXT:core/Resources/Public/JavaScript/requirejs-loader.js'
1505  )
1506  . '"></script>' . LF;
1507  }
1508 
1509  return $html;
1510  }
1511 
1518  protected function ‪filterArrayKeys(array $array, array $keys, bool $keep = true): array
1519  {
1520  return array_filter(
1521  $array,
1522  function (string $key) use ($keys, $keep) {
1523  return in_array($key, $keys, true) === $keep;
1524  },
1525  ARRAY_FILTER_USE_KEY
1526  );
1527  }
1528 
1545  public function ‪loadRequireJsModule($mainModuleName, $callBackFunction = null)
1546  {
1547  $inlineCodeKey = $mainModuleName;
1548  // make sure requireJS is initialized
1549  $this->‪loadRequireJs();
1550  // move internal module path definition to public module definition
1551  // (since loading a module ends up disclosing the existence anyway)
1552  $baseModuleName = $this->‪findRequireJsBaseModuleName($mainModuleName);
1553  if ($baseModuleName !== null && isset($this->requireJsConfig['paths'][$baseModuleName])) {
1554  $this->publicRequireJsConfig['paths'][$baseModuleName] = $this->requireJsConfig['paths'][$baseModuleName];
1555  unset($this->requireJsConfig['paths'][$baseModuleName]);
1556  }
1557  // execute the main module, and load a possible callback function
1558  $javaScriptCode = 'require([' . GeneralUtility::quoteJSvalue($mainModuleName) . ']';
1559  if ($callBackFunction !== null) {
1560  $inlineCodeKey .= sha1($callBackFunction);
1561  $javaScriptCode .= ', ' . $callBackFunction;
1562  }
1563  $javaScriptCode .= ');';
1564  $this->‪addJsInlineCode('RequireJS-Module-' . $inlineCodeKey, $javaScriptCode);
1565  }
1566 
1573  protected function ‪findRequireJsBaseModuleName(string $moduleName)
1574  {
1575  // trim spaces and slashes & add ending slash
1576  $sanitizedModuleName = trim($moduleName, ' /') . '/';
1577  foreach ($this->internalRequireJsPathModuleNames as $sanitizedBaseModuleName => $baseModuleName) {
1578  if (strpos($sanitizedModuleName, $sanitizedBaseModuleName) === 0) {
1579  return $baseModuleName;
1580  }
1581  }
1582  return null;
1583  }
1592  public function ‪addInlineLanguageLabel($key, $value)
1593  {
1594  $this->inlineLanguageLabels[$key] = $value;
1595  }
1596 
1604  public function ‪addInlineLanguageLabelArray(array $array)
1605  {
1606  $this->inlineLanguageLabels = array_merge($this->inlineLanguageLabels, $array);
1607  }
1608 
1616  public function ‪addInlineLanguageLabelFile($fileRef, $selectionPrefix = '', $stripFromSelectionName = '')
1617  {
1618  $index = md5($fileRef . $selectionPrefix . $stripFromSelectionName);
1619  if ($fileRef && !isset($this->inlineLanguageLabelFiles[$index])) {
1620  $this->inlineLanguageLabelFiles[$index] = [
1621  'fileRef' => $fileRef,
1622  'selectionPrefix' => $selectionPrefix,
1623  'stripFromSelectionName' => $stripFromSelectionName
1624  ];
1625  }
1626  }
1627 
1636  public function ‪addInlineSetting($namespace, $key, $value)
1637  {
1638  if ($namespace) {
1639  if (strpos($namespace, '.')) {
1640  $parts = explode('.', $namespace);
1641  $a = &$this->inlineSettings;
1642  foreach ($parts as $part) {
1643  $a = &$a[$part];
1644  }
1645  $a[$key] = $value;
1646  } else {
1647  $this->inlineSettings[$namespace][$key] = $value;
1648  }
1649  } else {
1650  $this->inlineSettings[$key] = $value;
1651  }
1652  }
1653 
1662  public function ‪addInlineSettingArray($namespace, array $array)
1663  {
1664  if ($namespace) {
1665  if (strpos($namespace, '.')) {
1666  $parts = explode('.', $namespace);
1667  $a = &$this->inlineSettings;
1668  foreach ($parts as $part) {
1669  $a = &$a[$part];
1670  }
1671  $a = array_merge((array)$a, $array);
1672  } else {
1673  $this->inlineSettings[$namespace] = array_merge((array)$this->inlineSettings[$namespace], $array);
1674  }
1675  } else {
1676  $this->inlineSettings = array_merge($this->inlineSettings, $array);
1677  }
1678  }
1679 
1685  public function ‪addBodyContent($content)
1686  {
1687  $this->bodyContent .= $content;
1688  }
1689 
1690  /*****************************************************/
1691  /* */
1692  /* Render Functions */
1693  /* */
1694  /*****************************************************/
1701  public function ‪render($part = self::PART_COMPLETE)
1702  {
1703  $this->‪prepareRendering();
1704  [$jsLibs, $jsFiles, $jsFooterFiles, $cssLibs, $cssFiles, $jsInline, $cssInline, $jsFooterInline, $jsFooterLibs] = $this->‪renderJavaScriptAndCss();
1705  $metaTags = implode(LF, array_merge($this->metaTags, $this->‪renderMetaTagsFromAPI()));
1706  $markerArray = $this->‪getPreparedMarkerArray($jsLibs, $jsFiles, $jsFooterFiles, $cssLibs, $cssFiles, $jsInline, $cssInline, $jsFooterInline, $jsFooterLibs, $metaTags);
1707  $template = $this->‪getTemplateForPart($part);
1708 
1709  // The page renderer needs a full reset, even when only rendering one part of the page
1710  // This means that you can only register footer files *after* the header has been already rendered.
1711  // In case you render the footer part first, header files can only be added *after* the footer has been rendered
1712  $this->‪reset();
1713  $templateService = GeneralUtility::makeInstance(MarkerBasedTemplateService::class);
1714  return trim($templateService->substituteMarkerArray($template, $markerArray, '###|###'));
1715  }
1716 
1722  protected function ‪renderMetaTagsFromAPI()
1723  {
1724  $metaTags = [];
1725  $metaTagManagers = $this->metaTagRegistry->getAllManagers();
1726 
1727  foreach ($metaTagManagers as $manager => $managerObject) {
1728  $properties = $managerObject->renderAllProperties();
1729  if (!empty($properties)) {
1730  $metaTags[] = $properties;
1731  }
1732  }
1733  return $metaTags;
1734  }
1735 
1743  public function ‪renderPageWithUncachedObjects($substituteHash)
1744  {
1745  $this->‪prepareRendering();
1746  $markerArray = $this->‪getPreparedMarkerArrayForPageWithUncachedObjects($substituteHash);
1747  $template = $this->‪getTemplateForPart(self::PART_COMPLETE);
1748  $templateService = GeneralUtility::makeInstance(MarkerBasedTemplateService::class);
1749  return trim($templateService->substituteMarkerArray($template, $markerArray, '###|###'));
1750  }
1751 
1761  public function ‪renderJavaScriptAndCssForProcessingOfUncachedContentObjects($cachedPageContent, $substituteHash)
1762  {
1763  $this->‪prepareRendering();
1764  [$jsLibs, $jsFiles, $jsFooterFiles, $cssLibs, $cssFiles, $jsInline, $cssInline, $jsFooterInline, $jsFooterLibs] = $this->‪renderJavaScriptAndCss();
1765  $title = $this->title ? str_replace('|', htmlspecialchars($this->title), $this->titleTag) : '';
1766  $markerArray = [
1767  '<!-- ###TITLE' . $substituteHash . '### -->' => $title,
1768  '<!-- ###CSS_LIBS' . $substituteHash . '### -->' => $cssLibs,
1769  '<!-- ###CSS_INCLUDE' . $substituteHash . '### -->' => $cssFiles,
1770  '<!-- ###CSS_INLINE' . $substituteHash . '### -->' => $cssInline,
1771  '<!-- ###JS_INLINE' . $substituteHash . '### -->' => $jsInline,
1772  '<!-- ###JS_INCLUDE' . $substituteHash . '### -->' => $jsFiles,
1773  '<!-- ###JS_LIBS' . $substituteHash . '### -->' => $jsLibs,
1774  '<!-- ###META' . $substituteHash . '### -->' => implode(LF, array_merge($this->metaTags, $this->‪renderMetaTagsFromAPI())),
1775  '<!-- ###HEADERDATA' . $substituteHash . '### -->' => implode(LF, $this->headerData),
1776  '<!-- ###FOOTERDATA' . $substituteHash . '### -->' => implode(LF, $this->footerData),
1777  '<!-- ###JS_LIBS_FOOTER' . $substituteHash . '### -->' => $jsFooterLibs,
1778  '<!-- ###JS_INCLUDE_FOOTER' . $substituteHash . '### -->' => $jsFooterFiles,
1779  '<!-- ###JS_INLINE_FOOTER' . $substituteHash . '### -->' => $jsFooterInline
1780  ];
1781  foreach ($markerArray as $placeHolder => $content) {
1782  $cachedPageContent = str_replace($placeHolder, $content, $cachedPageContent);
1783  }
1784  $this->‪reset();
1785  return $cachedPageContent;
1786  }
1787 
1793  protected function ‪prepareRendering()
1794  {
1795  if ($this->‪getRenderXhtml()) {
1796  $this->endingSlash = ' /';
1797  } else {
1798  $this->metaCharsetTag = str_replace(' />', '>', $this->metaCharsetTag);
1799  $this->baseUrlTag = str_replace(' />', '>', $this->baseUrlTag);
1800  $this->shortcutTag = str_replace(' />', '>', $this->shortcutTag);
1801  $this->endingSlash = '';
1802  }
1803  }
1804 
1810  protected function ‪renderJavaScriptAndCss()
1811  {
1812  $this->‪executePreRenderHook();
1813  $mainJsLibs = $this->‪renderMainJavaScriptLibraries();
1814  if ($this->concatenateJavascript || $this->concatenateCss) {
1815  // Do the file concatenation
1816  $this->‪doConcatenate();
1817  }
1818  if ($this->compressCss || $this->compressJavascript) {
1819  // Do the file compression
1820  $this->‪doCompress();
1821  }
1823  $cssLibs = $this->‪renderCssLibraries();
1824  $cssFiles = $this->‪renderCssFiles();
1825  $cssInline = $this->‪renderCssInline();
1826  [$jsLibs, $jsFooterLibs] = $this->‪renderAdditionalJavaScriptLibraries();
1827  [$jsFiles, $jsFooterFiles] = $this->‪renderJavaScriptFiles();
1828  [$jsInline, $jsFooterInline] = $this->‪renderInlineJavaScript();
1829  $jsLibs = $mainJsLibs . $jsLibs;
1830  if ($this->moveJsFromHeaderToFooter) {
1831  $jsFooterLibs = $jsLibs . LF . $jsFooterLibs;
1832  $jsLibs = '';
1833  $jsFooterFiles = $jsFiles . LF . $jsFooterFiles;
1834  $jsFiles = '';
1835  $jsFooterInline = $jsInline . LF . $jsFooterInline;
1836  $jsInline = '';
1837  }
1838  // Use AssetRenderer to inject all JavaScripts and CSS files
1839  $assetRenderer = GeneralUtility::makeInstance(AssetRenderer::class);
1840  $jsInline .= $assetRenderer->renderInlineJavaScript(true);
1841  $jsFooterInline .= $assetRenderer->renderInlineJavaScript();
1842  $jsFiles .= $assetRenderer->renderJavaScript(true);
1843  $jsFooterFiles .= $assetRenderer->renderJavaScript();
1844  $cssInline .= $assetRenderer->renderInlineStyleSheets(true);
1845  // append inline CSS to footer (as there is no cssFooterInline)
1846  $jsFooterFiles .= $assetRenderer->renderInlineStyleSheets();
1847  $cssLibs .= $assetRenderer->renderStyleSheets(true, $this->endingSlash);
1848  $cssFiles .= $assetRenderer->renderStyleSheets(false, $this->endingSlash);
1849 
1850  $this->‪executePostRenderHook($jsLibs, $jsFiles, $jsFooterFiles, $cssLibs, $cssFiles, $jsInline, $cssInline, $jsFooterInline, $jsFooterLibs);
1851  return [$jsLibs, $jsFiles, $jsFooterFiles, $cssLibs, $cssFiles, $jsInline, $cssInline, $jsFooterInline, $jsFooterLibs];
1852  }
1853 
1869  protected function ‪getPreparedMarkerArray($jsLibs, $jsFiles, $jsFooterFiles, $cssLibs, $cssFiles, $jsInline, $cssInline, $jsFooterInline, $jsFooterLibs, $metaTags)
1870  {
1871  $markerArray = [
1872  'XMLPROLOG_DOCTYPE' => $this->xmlPrologAndDocType,
1873  'HTMLTAG' => $this->htmlTag,
1874  'HEADTAG' => $this->headTag,
1875  'METACHARSET' => $this->charSet ? str_replace('|', htmlspecialchars($this->charSet), $this->metaCharsetTag) : '',
1876  'INLINECOMMENT' => $this->inlineComments ? LF . LF . '<!-- ' . LF . implode(LF, $this->inlineComments) . '-->' . LF . LF : '',
1877  'BASEURL' => $this->baseUrl ? str_replace('|', $this->baseUrl, $this->baseUrlTag) : '',
1878  'SHORTCUT' => $this->favIcon ? sprintf($this->shortcutTag, htmlspecialchars($this->favIcon), $this->iconMimeType) : '',
1879  'CSS_LIBS' => $cssLibs,
1880  'CSS_INCLUDE' => $cssFiles,
1881  'CSS_INLINE' => $cssInline,
1882  'JS_INLINE' => $jsInline,
1883  'JS_INCLUDE' => $jsFiles,
1884  'JS_LIBS' => $jsLibs,
1885  'TITLE' => $this->title ? str_replace('|', htmlspecialchars($this->title), $this->titleTag) : '',
1886  'META' => $metaTags,
1887  'HEADERDATA' => $this->headerData ? implode(LF, $this->headerData) : '',
1888  'FOOTERDATA' => $this->footerData ? implode(LF, $this->footerData) : '',
1889  'JS_LIBS_FOOTER' => $jsFooterLibs,
1890  'JS_INCLUDE_FOOTER' => $jsFooterFiles,
1891  'JS_INLINE_FOOTER' => $jsFooterInline,
1892  'BODY' => $this->bodyContent
1893  ];
1894  $markerArray = array_map('trim', $markerArray);
1895  return $markerArray;
1896  }
1897 
1904  protected function ‪getPreparedMarkerArrayForPageWithUncachedObjects($substituteHash)
1905  {
1906  $markerArray = [
1907  'XMLPROLOG_DOCTYPE' => $this->xmlPrologAndDocType,
1908  'HTMLTAG' => $this->htmlTag,
1909  'HEADTAG' => $this->headTag,
1910  'METACHARSET' => $this->charSet ? str_replace('|', htmlspecialchars($this->charSet), $this->metaCharsetTag) : '',
1911  'INLINECOMMENT' => $this->inlineComments ? LF . LF . '<!-- ' . LF . implode(LF, $this->inlineComments) . '-->' . LF . LF : '',
1912  'BASEURL' => $this->baseUrl ? str_replace('|', $this->baseUrl, $this->baseUrlTag) : '',
1913  'SHORTCUT' => $this->favIcon ? sprintf($this->shortcutTag, htmlspecialchars($this->favIcon), $this->iconMimeType) : '',
1914  'META' => '<!-- ###META' . $substituteHash . '### -->',
1915  'BODY' => $this->bodyContent,
1916  'TITLE' => '<!-- ###TITLE' . $substituteHash . '### -->',
1917  'CSS_LIBS' => '<!-- ###CSS_LIBS' . $substituteHash . '### -->',
1918  'CSS_INCLUDE' => '<!-- ###CSS_INCLUDE' . $substituteHash . '### -->',
1919  'CSS_INLINE' => '<!-- ###CSS_INLINE' . $substituteHash . '### -->',
1920  'JS_INLINE' => '<!-- ###JS_INLINE' . $substituteHash . '### -->',
1921  'JS_INCLUDE' => '<!-- ###JS_INCLUDE' . $substituteHash . '### -->',
1922  'JS_LIBS' => '<!-- ###JS_LIBS' . $substituteHash . '### -->',
1923  'HEADERDATA' => '<!-- ###HEADERDATA' . $substituteHash . '### -->',
1924  'FOOTERDATA' => '<!-- ###FOOTERDATA' . $substituteHash . '### -->',
1925  'JS_LIBS_FOOTER' => '<!-- ###JS_LIBS_FOOTER' . $substituteHash . '### -->',
1926  'JS_INCLUDE_FOOTER' => '<!-- ###JS_INCLUDE_FOOTER' . $substituteHash . '### -->',
1927  'JS_INLINE_FOOTER' => '<!-- ###JS_INLINE_FOOTER' . $substituteHash . '### -->'
1928  ];
1929  $markerArray = array_map('trim', $markerArray);
1930  return $markerArray;
1931  }
1932 
1939  protected function ‪getTemplateForPart($part)
1940  {
1941  $templateFile = GeneralUtility::getFileAbsFileName($this->templateFile);
1942  if (is_file($templateFile)) {
1943  $template = (string)file_get_contents($templateFile);
1944  if ($this->removeLineBreaksFromTemplate) {
1945  $template = strtr($template, [LF => '', CR => '']);
1946  }
1947  if ($part !== self::PART_COMPLETE) {
1948  $templatePart = explode('###BODY###', $template);
1949  $template = $templatePart[$part - 1];
1950  }
1951  } else {
1952  $template = '';
1953  }
1954  return $template;
1955  }
1956 
1963  protected function ‪renderMainJavaScriptLibraries()
1964  {
1965  $out = '';
1966 
1967  // Include RequireJS
1968  if ($this->addRequireJs) {
1969  $out .= $this->‪getRequireJsLoader();
1970  }
1971 
1973  if (TYPO3_MODE === 'BE') {
1974  $noBackendUserLoggedIn = empty(‪$GLOBALS['BE_USER']->user['uid']);
1975  $this->‪addAjaxUrlsToInlineSettings($noBackendUserLoggedIn);
1976  }
1977  $inlineSettings = '';
1978  $languageLabels = $this->‪parseLanguageLabelsForJavaScript();
1979  if (!empty($languageLabels)) {
1980  $inlineSettings .= 'TYPO3.lang = ' . json_encode($languageLabels) . ';';
1981  }
1982  $inlineSettings .= $this->inlineSettings ? 'TYPO3.settings = ' . json_encode($this->inlineSettings) . ';' : '';
1983 
1984  if ($inlineSettings !== '') {
1985  // make sure the global TYPO3 is available
1986  $inlineSettings = 'var TYPO3 = TYPO3 || {};' . CRLF . $inlineSettings;
1987  $out .= $this->inlineJavascriptWrap[0] . $inlineSettings . $this->inlineJavascriptWrap[1];
1988  }
1989 
1990  return $out;
1991  }
1992 
1998  protected function ‪parseLanguageLabelsForJavaScript(): array
1999  {
2000  if (empty($this->inlineLanguageLabels)) {
2001  return [];
2002  }
2003 
2004  $labels = [];
2005  foreach ($this->inlineLanguageLabels as $key => $translationUnit) {
2006  if (is_array($translationUnit)) {
2007  $translationUnit = current($translationUnit);
2008  $labels[$key] = $translationUnit['target'] ?? $translationUnit['source'];
2009  } else {
2010  $labels[$key] = $translationUnit;
2011  }
2012  }
2013 
2014  return $labels;
2015  }
2016 
2020  protected function ‪loadJavaScriptLanguageStrings()
2021  {
2022  if (!empty($this->inlineLanguageLabelFiles)) {
2023  foreach ($this->inlineLanguageLabelFiles as $languageLabelFile) {
2024  $this->‪includeLanguageFileForInline($languageLabelFile['fileRef'], $languageLabelFile['selectionPrefix'], $languageLabelFile['stripFromSelectionName']);
2025  }
2026  }
2027  $this->inlineLanguageLabelFiles = [];
2028  // Convert settings back to UTF-8 since json_encode() only works with UTF-8:
2029  if ($this->‪getCharSet() && $this->‪getCharSet() !== 'utf-8' && is_array($this->inlineSettings)) {
2030  $this->‪convertCharsetRecursivelyToUtf8($this->inlineSettings, $this->‪getCharSet());
2031  }
2032  }
2040  protected function ‪convertCharsetRecursivelyToUtf8(&$data, string $fromCharset)
2041  {
2042  foreach ($data as $key => $value) {
2043  if (is_array($data[$key])) {
2044  $this->‪convertCharsetRecursivelyToUtf8($data[$key], $fromCharset);
2045  } elseif (is_string($data[$key])) {
2046  $data[$key] = mb_convert_encoding($data[$key], 'utf-8', $fromCharset);
2047  }
2048  }
2049  }
2050 
2056  protected function ‪addAjaxUrlsToInlineSettings(bool $publicRoutesOnly = false)
2057  {
2058  $ajaxUrls = [];
2059  // Add the ajax-based routes
2061  $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
2063  $router = GeneralUtility::makeInstance(Router::class);
2064  $routes = $router->getRoutes();
2065  foreach ($routes as $routeIdentifier => $route) {
2066  if ($publicRoutesOnly && $route->getOption('access') !== 'public') {
2067  continue;
2068  }
2069  if ($route->getOption('ajax')) {
2070  $uri = (string)$uriBuilder->buildUriFromRoute($routeIdentifier);
2071  // use the shortened value in order to use this in JavaScript
2072  $routeIdentifier = str_replace('ajax_', '', $routeIdentifier);
2073  $ajaxUrls[$routeIdentifier] = $uri;
2074  }
2075  }
2076 
2077  $this->inlineSettings['ajaxUrls'] = $ajaxUrls;
2078  }
2079 
2085  protected function ‪renderCssLibraries()
2086  {
2087  $cssFiles = '';
2088  if (!empty($this->cssLibs)) {
2089  foreach ($this->cssLibs as $file => $properties) {
2090  $tag = $this->‪createCssTag($properties, $file);
2091  if ($properties['forceOnTop']) {
2092  $cssFiles = $tag . $cssFiles;
2093  } else {
2094  $cssFiles .= $tag;
2095  }
2096  }
2097  }
2098  return $cssFiles;
2099  }
2100 
2106  protected function ‪renderCssFiles()
2107  {
2108  $cssFiles = '';
2109  if (!empty($this->cssFiles)) {
2110  foreach ($this->cssFiles as $file => $properties) {
2111  $tag = $this->‪createCssTag($properties, $file);
2112  if ($properties['forceOnTop']) {
2113  $cssFiles = $tag . $cssFiles;
2114  } else {
2115  $cssFiles .= $tag;
2116  }
2117  }
2118  }
2119  return $cssFiles;
2120  }
2121 
2129  private function ‪createCssTag(array $properties, string $file): string
2130  {
2131  if (($properties['inline'] ?? false) && @is_file($file)) {
2132  $tag = $this->‪createInlineCssTagFromFile($file, $properties);
2133  } else {
2134  $href = $this->‪getStreamlinedFileName($file);
2135  $tag = '<link rel="' . htmlspecialchars($properties['rel'])
2136  . '" type="text/css" href="' . htmlspecialchars($href)
2137  . '" media="' . htmlspecialchars($properties['media']) . '"'
2138  . (($properties['title'] ?? false) ? ' title="' . htmlspecialchars($properties['title']) . '"' : '')
2139  . $this->endingSlash . '>';
2140  }
2141  if ($properties['allWrap']) {
2142  $wrapArr = explode($properties['splitChar'] ?: '|', $properties['allWrap'], 2);
2143  $tag = $wrapArr[0] . $tag . $wrapArr[1];
2144  }
2145  $tag .= LF;
2146 
2147  return $tag;
2148  }
2149 
2155  protected function ‪renderCssInline()
2156  {
2157  $cssInline = '';
2158  if (!empty($this->cssInline)) {
2159  foreach ($this->cssInline as $name => $properties) {
2160  $cssCode = '/*' . htmlspecialchars($name) . '*/' . LF . $properties['code'] . LF;
2161  if ($properties['forceOnTop']) {
2162  $cssInline = $cssCode . $cssInline;
2163  } else {
2164  $cssInline .= $cssCode;
2165  }
2166  }
2167  $cssInline = $this->inlineCssWrap[0] . $cssInline . $this->inlineCssWrap[1];
2168  }
2169  return $cssInline;
2170  }
2177  protected function ‪renderAdditionalJavaScriptLibraries()
2178  {
2179  $jsLibs = '';
2180  $jsFooterLibs = '';
2181  if (!empty($this->jsLibs)) {
2182  foreach ($this->jsLibs as $properties) {
2183  $properties['file'] = $this->‪getStreamlinedFileName($properties['file']);
2184  $type = $properties['type'] ? ' type="' . htmlspecialchars($properties['type']) . '"' : '';
2185  $async = $properties['async'] ? ' async="async"' : '';
2186  $defer = $properties['defer'] ? ' defer="defer"' : '';
2187  $nomodule = $properties['nomodule'] ? ' nomodule="nomodule"' : '';
2188  $integrity = $properties['integrity'] ? ' integrity="' . htmlspecialchars($properties['integrity']) . '"' : '';
2189  $crossorigin = $properties['crossorigin'] ? ' crossorigin="' . htmlspecialchars($properties['crossorigin']) . '"' : '';
2190  $tag = '<script src="' . htmlspecialchars($properties['file']) . '"' . $type . $async . $defer . $integrity . $crossorigin . $nomodule . '></script>';
2191  if ($properties['allWrap']) {
2192  $wrapArr = explode($properties['splitChar'] ?: '|', $properties['allWrap'], 2);
2193  $tag = $wrapArr[0] . $tag . $wrapArr[1];
2194  }
2195  $tag .= LF;
2196  if ($properties['forceOnTop']) {
2197  if ($properties['section'] === self::PART_HEADER) {
2198  $jsLibs = $tag . $jsLibs;
2199  } else {
2200  $jsFooterLibs = $tag . $jsFooterLibs;
2201  }
2202  } else {
2203  if ($properties['section'] === self::PART_HEADER) {
2204  $jsLibs .= $tag;
2205  } else {
2206  $jsFooterLibs .= $tag;
2207  }
2208  }
2209  }
2210  }
2211  if ($this->moveJsFromHeaderToFooter) {
2212  $jsFooterLibs = $jsLibs . LF . $jsFooterLibs;
2213  $jsLibs = '';
2214  }
2215  return [$jsLibs, $jsFooterLibs];
2216  }
2223  protected function ‪renderJavaScriptFiles()
2224  {
2225  $jsFiles = '';
2226  $jsFooterFiles = '';
2227  if (!empty($this->jsFiles)) {
2228  foreach ($this->jsFiles as $file => $properties) {
2229  $file = $this->‪getStreamlinedFileName($file);
2230  $type = $properties['type'] ? ' type="' . htmlspecialchars($properties['type']) . '"' : '';
2231  $async = $properties['async'] ? ' async="async"' : '';
2232  $defer = ($properties['defer'] ?? false) ? ' defer="defer"' : '';
2233  $nomodule = ($properties['nomodule'] ?? false) ? ' nomodule="nomodule"' : '';
2234  $integrity = ($properties['integrity'] ?? false) ? ' integrity="' . htmlspecialchars($properties['integrity']) . '"' : '';
2235  $crossorigin = ($properties['crossorigin'] ?? false) ? ' crossorigin="' . htmlspecialchars($properties['crossorigin']) . '"' : '';
2236  $tag = '<script src="' . htmlspecialchars($file) . '"' . $type . $async . $defer . $integrity . $crossorigin . $nomodule . '></script>';
2237  if ($properties['allWrap']) {
2238  $wrapArr = explode($properties['splitChar'] ?: '|', $properties['allWrap'], 2);
2239  $tag = $wrapArr[0] . $tag . $wrapArr[1];
2240  }
2241  $tag .= LF;
2242  if ($properties['forceOnTop']) {
2243  if ($properties['section'] === self::PART_HEADER) {
2244  $jsFiles = $tag . $jsFiles;
2245  } else {
2246  $jsFooterFiles = $tag . $jsFooterFiles;
2247  }
2248  } else {
2249  if ($properties['section'] === self::PART_HEADER) {
2250  $jsFiles .= $tag;
2251  } else {
2252  $jsFooterFiles .= $tag;
2253  }
2254  }
2255  }
2256  }
2257  if ($this->moveJsFromHeaderToFooter) {
2258  $jsFooterFiles = $jsFiles . $jsFooterFiles;
2259  $jsFiles = '';
2260  }
2261  return [$jsFiles, $jsFooterFiles];
2262  }
2263 
2269  protected function ‪renderInlineJavaScript()
2270  {
2271  $jsInline = '';
2272  $jsFooterInline = '';
2273  if (!empty($this->jsInline)) {
2274  foreach ($this->jsInline as $name => $properties) {
2275  $jsCode = '/*' . htmlspecialchars($name) . '*/' . LF . $properties['code'] . LF;
2276  if ($properties['forceOnTop']) {
2277  if ($properties['section'] === self::PART_HEADER) {
2278  $jsInline = $jsCode . $jsInline;
2279  } else {
2280  $jsFooterInline = $jsCode . $jsFooterInline;
2281  }
2282  } else {
2283  if ($properties['section'] === self::PART_HEADER) {
2284  $jsInline .= $jsCode;
2285  } else {
2286  $jsFooterInline .= $jsCode;
2287  }
2288  }
2289  }
2290  }
2291  if ($jsInline) {
2292  $jsInline = $this->inlineJavascriptWrap[0] . $jsInline . $this->inlineJavascriptWrap[1];
2293  }
2294  if ($jsFooterInline) {
2295  $jsFooterInline = $this->inlineJavascriptWrap[0] . $jsFooterInline . $this->inlineJavascriptWrap[1];
2296  }
2297  if ($this->moveJsFromHeaderToFooter) {
2298  $jsFooterInline = $jsInline . $jsFooterInline;
2299  $jsInline = '';
2300  }
2301  return [$jsInline, $jsFooterInline];
2302  }
2303 
2312  protected function ‪includeLanguageFileForInline($fileRef, $selectionPrefix = '', $stripFromSelectionName = '')
2313  {
2314  if (!isset($this->lang) || !isset($this->charSet)) {
2315  throw new \RuntimeException('Language and character encoding are not set.', 1284906026);
2316  }
2317  $labelsFromFile = [];
2318  $allLabels = $this->‪readLLfile($fileRef);
2319  if ($allLabels !== false) {
2320  // Merge language specific translations:
2321  if ($this->lang !== 'default' && isset($allLabels[$this->lang])) {
2322  $labels = array_merge($allLabels['default'], $allLabels[$this->lang]);
2323  } else {
2324  $labels = $allLabels['default'];
2325  }
2326  // Iterate through all locallang labels:
2327  foreach ($labels as $label => $value) {
2328  // If $selectionPrefix is set, only respect labels that start with $selectionPrefix
2329  if ($selectionPrefix === '' || strpos($label, $selectionPrefix) === 0) {
2330  // Remove substring $stripFromSelectionName from label
2331  $label = str_replace($stripFromSelectionName, '', $label);
2332  $labelsFromFile[$label] = $value;
2333  }
2334  }
2335  $this->inlineLanguageLabels = array_merge($this->inlineLanguageLabels, $labelsFromFile);
2336  }
2337  }
2338 
2345  protected function ‪readLLfile($fileRef)
2346  {
2348  $languageFactory = GeneralUtility::makeInstance(LocalizationFactory::class);
2349 
2350  if ($this->lang !== 'default') {
2351  $languages = array_reverse($this->languageDependencies);
2352  // At least we need to have English
2353  if (empty($languages)) {
2354  $languages[] = 'default';
2355  }
2356  } else {
2357  $languages = ['default'];
2358  }
2359 
2360  $localLanguage = [];
2361  foreach ($languages as $language) {
2362  $tempLL = $languageFactory->getParsedData($fileRef, $language);
2363 
2364  $localLanguage['default'] = $tempLL['default'];
2365  if (!isset($localLanguage[$this->lang])) {
2366  $localLanguage[‪$this->lang] = $localLanguage['default'];
2367  }
2368  if ($this->lang !== 'default' && isset($tempLL[$language])) {
2369  // Merge current language labels onto labels from previous language
2370  // This way we have a labels with fall back applied
2371  ‪ArrayUtility::mergeRecursiveWithOverrule($localLanguage[$this->lang], $tempLL[$language], true, false);
2372  }
2373  }
2374 
2375  return $localLanguage;
2376  }
2377 
2378  /*****************************************************/
2379  /* */
2380  /* Tools */
2381  /* */
2382  /*****************************************************/
2387  protected function ‪doConcatenate()
2388  {
2389  $this->‪doConcatenateCss();
2391  }
2392 
2396  protected function ‪doConcatenateJavaScript()
2397  {
2398  if ($this->concatenateJavascript) {
2399  if (!empty(‪$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['jsConcatenateHandler'])) {
2400  // use external concatenation routine
2401  $params = [
2402  'jsLibs' => &$this->jsLibs,
2403  'jsFiles' => &$this->jsFiles,
2404  'jsFooterFiles' => &$this->jsFooterFiles,
2405  'headerData' => &$this->headerData,
2406  'footerData' => &$this->footerData
2407  ];
2408  GeneralUtility::callUserFunction(‪$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['jsConcatenateHandler'], $params, $this);
2409  } else {
2410  $this->jsLibs = $this->‪getCompressor()->‪concatenateJsFiles($this->jsLibs);
2411  $this->jsFiles = $this->‪getCompressor()->‪concatenateJsFiles($this->jsFiles);
2412  $this->jsFooterFiles = $this->‪getCompressor()->‪concatenateJsFiles($this->jsFooterFiles);
2413  }
2414  }
2415  }
2416 
2420  protected function ‪doConcatenateCss()
2421  {
2422  if ($this->concatenateCss) {
2423  if (!empty(‪$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['cssConcatenateHandler'])) {
2424  // use external concatenation routine
2425  $params = [
2426  'cssFiles' => &$this->cssFiles,
2427  'cssLibs' => &$this->cssLibs,
2428  'headerData' => &$this->headerData,
2429  'footerData' => &$this->footerData
2430  ];
2431  GeneralUtility::callUserFunction(‪$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['cssConcatenateHandler'], $params, $this);
2432  } else {
2433  $this->cssLibs = $this->‪getCompressor()->‪concatenateCssFiles($this->cssLibs);
2434  $this->cssFiles = $this->‪getCompressor()->‪concatenateCssFiles($this->cssFiles);
2435  }
2436  }
2437  }
2438 
2442  protected function ‪doCompress()
2443  {
2444  $this->‪doCompressJavaScript();
2445  $this->‪doCompressCss();
2446  }
2447 
2451  protected function ‪doCompressCss()
2452  {
2453  if ($this->compressCss) {
2454  if (!empty(‪$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['cssCompressHandler'])) {
2455  // Use external compression routine
2456  $params = [
2457  'cssInline' => &$this->cssInline,
2458  'cssFiles' => &$this->cssFiles,
2459  'cssLibs' => &$this->cssLibs,
2460  'headerData' => &$this->headerData,
2461  'footerData' => &$this->footerData
2462  ];
2463  GeneralUtility::callUserFunction(‪$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['cssCompressHandler'], $params, $this);
2464  } else {
2465  $this->cssLibs = $this->‪getCompressor()->‪compressCssFiles($this->cssLibs);
2466  $this->cssFiles = $this->‪getCompressor()->‪compressCssFiles($this->cssFiles);
2467  }
2468  }
2469  }
2470 
2474  protected function ‪doCompressJavaScript()
2475  {
2476  if ($this->compressJavascript) {
2477  if (!empty(‪$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['jsCompressHandler'])) {
2478  // Use external compression routine
2479  $params = [
2480  'jsInline' => &$this->jsInline,
2481  'jsFooterInline' => &$this->jsFooterInline,
2482  'jsLibs' => &$this->jsLibs,
2483  'jsFiles' => &$this->jsFiles,
2484  'jsFooterFiles' => &$this->jsFooterFiles,
2485  'headerData' => &$this->headerData,
2486  'footerData' => &$this->footerData
2487  ];
2488  GeneralUtility::callUserFunction(‪$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['jsCompressHandler'], $params, $this);
2489  } else {
2490  // Traverse the arrays, compress files
2491  if (!empty($this->jsInline)) {
2492  foreach ($this->jsInline as $name => $properties) {
2493  if ($properties['compress']) {
2494  $error = '';
2495  $this->jsInline[$name]['code'] = ‪GeneralUtility::minifyJavaScript($properties['code'], $error);
2496  if ($error) {
2497  $this->compressError .= 'Error with minify JS Inline Block "' . $name . '": ' . $error . LF;
2498  }
2499  }
2500  }
2501  }
2502  $this->jsLibs = $this->‪getCompressor()->‪compressJsFiles($this->jsLibs);
2503  $this->jsFiles = $this->‪getCompressor()->‪compressJsFiles($this->jsFiles);
2504  $this->jsFooterFiles = $this->‪getCompressor()->‪compressJsFiles($this->jsFooterFiles);
2505  }
2506  }
2507  }
2508 
2514  protected function ‪getCompressor()
2515  {
2516  if ($this->compressor === null) {
2517  $this->compressor = GeneralUtility::makeInstance(ResourceCompressor::class);
2518  }
2519  return ‪$this->compressor;
2520  }
2521 
2530  protected function ‪processJsFile($filename)
2531  {
2532  $filename = $this->‪getStreamlinedFileName($filename, false);
2533  if ($this->compressJavascript) {
2534  $filename = $this->‪getCompressor()->‪compressJsFile($filename);
2535  } elseif (TYPO3_MODE === 'FE') {
2536  $filename = GeneralUtility::createVersionNumberedFilename($filename);
2537  }
2538  return $this->‪getAbsoluteWebPath($filename);
2539  }
2540 
2553  protected function ‪getStreamlinedFileName($file, $prepareForOutput = true)
2554  {
2555  if (strpos($file, 'EXT:') === 0) {
2556  $file = GeneralUtility::getFileAbsFileName($file);
2557  // as the path is now absolute, make it "relative" to the current script to stay compatible
2558  $file = ‪PathUtility::getRelativePathTo($file) ?? '';
2559  $file = rtrim($file, '/');
2560  } else {
2561  $file = GeneralUtility::resolveBackPath($file);
2562  }
2563  if ($prepareForOutput) {
2564  $file = GeneralUtility::createVersionNumberedFilename($file);
2565  $file = $this->‪getAbsoluteWebPath($file);
2566  }
2567  return $file;
2568  }
2569 
2579  protected function ‪getAbsoluteWebPath(string $file): string
2580  {
2581  if (TYPO3_MODE === 'FE') {
2582  return $file;
2583  }
2584  return ‪PathUtility::getAbsoluteWebPath($file);
2585  }
2586 
2587  /*****************************************************/
2588  /* */
2589  /* Hooks */
2590  /* */
2591  /*****************************************************/
2595  protected function ‪executePreRenderHook()
2596  {
2597  $hooks = ‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-preProcess'] ?? false;
2598  if (!$hooks) {
2599  return;
2600  }
2601  $params = [
2602  'jsLibs' => &$this->jsLibs,
2603  'jsFooterLibs' => &$this->jsFooterLibs,
2604  'jsFiles' => &$this->jsFiles,
2605  'jsFooterFiles' => &$this->jsFooterFiles,
2606  'cssLibs' => &$this->cssLibs,
2607  'cssFiles' => &$this->cssFiles,
2608  'headerData' => &$this->headerData,
2609  'footerData' => &$this->footerData,
2610  'jsInline' => &$this->jsInline,
2611  'jsFooterInline' => &$this->jsFooterInline,
2612  'cssInline' => &$this->cssInline
2613  ];
2614  foreach ($hooks as $hook) {
2615  GeneralUtility::callUserFunction($hook, $params, $this);
2616  }
2617  }
2618 
2622  protected function ‪executeRenderPostTransformHook()
2623  {
2624  $hooks = ‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-postTransform'] ?? false;
2625  if (!$hooks) {
2626  return;
2627  }
2628  $params = [
2629  'jsLibs' => &$this->jsLibs,
2630  'jsFooterLibs' => &$this->jsFooterLibs,
2631  'jsFiles' => &$this->jsFiles,
2632  'jsFooterFiles' => &$this->jsFooterFiles,
2633  'cssLibs' => &$this->cssLibs,
2634  'cssFiles' => &$this->cssFiles,
2635  'headerData' => &$this->headerData,
2636  'footerData' => &$this->footerData,
2637  'jsInline' => &$this->jsInline,
2638  'jsFooterInline' => &$this->jsFooterInline,
2639  'cssInline' => &$this->cssInline
2640  ];
2641  foreach ($hooks as $hook) {
2642  GeneralUtility::callUserFunction($hook, $params, $this);
2643  }
2644  }
2645 
2659  protected function ‪executePostRenderHook(&$jsLibs, &$jsFiles, &$jsFooterFiles, &$cssLibs, &$cssFiles, &$jsInline, &$cssInline, &$jsFooterInline, &$jsFooterLibs)
2660  {
2661  $hooks = ‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-postProcess'] ?? false;
2662  if (!$hooks) {
2663  return;
2664  }
2665  $params = [
2666  'jsLibs' => &$jsLibs,
2667  'jsFiles' => &$jsFiles,
2668  'jsFooterFiles' => &$jsFooterFiles,
2669  'cssLibs' => &$cssLibs,
2670  'cssFiles' => &$cssFiles,
2671  'headerData' => &$this->headerData,
2672  'footerData' => &$this->footerData,
2673  'jsInline' => &$jsInline,
2674  'cssInline' => &$cssInline,
2675  'xmlPrologAndDocType' => &$this->xmlPrologAndDocType,
2676  'htmlTag' => &$this->htmlTag,
2677  'headTag' => &$this->headTag,
2678  'charSet' => &$this->charSet,
2679  'metaCharsetTag' => &$this->metaCharsetTag,
2680  'shortcutTag' => &$this->shortcutTag,
2681  'inlineComments' => &$this->inlineComments,
2682  'baseUrl' => &$this->baseUrl,
2683  'baseUrlTag' => &$this->baseUrlTag,
2684  'favIcon' => &$this->favIcon,
2685  'iconMimeType' => &$this->iconMimeType,
2686  'titleTag' => &$this->titleTag,
2687  'title' => &$this->title,
2688  'metaTags' => &$this->metaTags,
2689  'jsFooterInline' => &$jsFooterInline,
2690  'jsFooterLibs' => &$jsFooterLibs,
2691  'bodyContent' => &$this->bodyContent
2692  ];
2693  foreach ($hooks as $hook) {
2694  GeneralUtility::callUserFunction($hook, $params, $this);
2695  }
2696  }
2697 
2705  protected function ‪createInlineCssTagFromFile(string $file, array $properties): string
2706  {
2707  $cssInline = file_get_contents($file);
2708  if ($cssInline === false) {
2709  return '';
2710  }
2711  $cssInlineFix = $this->‪getPathFixer()->fixRelativeUrlPaths($cssInline, '/' . ‪PathUtility::dirname($file) . '/');
2712  return '<style type="text/css"'
2713  . ' media="' . htmlspecialchars($properties['media']) . '"'
2714  . ($properties['title'] ? ' title="' . htmlspecialchars($properties['title']) . '"' : '')
2715  . '>' . LF
2716  . '/*<![CDATA[*/' . LF . '<!-- ' . LF
2717  . $cssInlineFix
2718  . '-->' . LF . '/*]]>*/' . LF . '</style>' . LF;
2719  }
2720 
2721  protected function ‪getPathFixer(): RelativeCssPathFixer
2722  {
2723  return GeneralUtility::makeInstance(RelativeCssPathFixer::class);
2724  }
2725 }
‪TYPO3\CMS\Core\Page\PageRenderer\getPathFixer
‪getPathFixer()
Definition: PageRenderer.php:2669
‪TYPO3\CMS\Core\Page\PageRenderer\disableCompressJavascript
‪disableCompressJavascript()
Definition: PageRenderer.php:597
‪TYPO3\CMS\Core\Page\PageRenderer\getRequireJsLoader
‪string getRequireJsLoader()
Definition: PageRenderer.php:1419
‪TYPO3\CMS\Core\Page\PageRenderer\addInlineLanguageLabelFile
‪addInlineLanguageLabelFile($fileRef, $selectionPrefix='', $stripFromSelectionName='')
Definition: PageRenderer.php:1564
‪TYPO3\CMS\Core\Page\PageRenderer\renderCssInline
‪string renderCssInline()
Definition: PageRenderer.php:2103
‪TYPO3\CMS\Core\Page\PageRenderer\enableConcatenateJavascript
‪enableConcatenateJavascript()
Definition: PageRenderer.php:621
‪TYPO3\CMS\Core\Page\PageRenderer\renderJavaScriptAndCssForProcessingOfUncachedContentObjects
‪string renderJavaScriptAndCssForProcessingOfUncachedContentObjects($cachedPageContent, $substituteHash)
Definition: PageRenderer.php:1709
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:24
‪TYPO3\CMS\Core\Page\PageRenderer\setFavIcon
‪setFavIcon($favIcon)
Definition: PageRenderer.php:481
‪TYPO3\CMS\Core\Page\PageRenderer\loadJavaScriptLanguageStrings
‪loadJavaScriptLanguageStrings()
Definition: PageRenderer.php:1968
‪TYPO3\CMS\Core\Page\PageRenderer\renderJavaScriptFiles
‪array string[] renderJavaScriptFiles()
Definition: PageRenderer.php:2171
‪TYPO3\CMS\Core\Page\PageRenderer\filterArrayKeys
‪array filterArrayKeys(array $array, array $keys, bool $keep=true)
Definition: PageRenderer.php:1466
‪TYPO3\CMS\Core\Page\PageRenderer\renderAdditionalJavaScriptLibraries
‪array string[] renderAdditionalJavaScriptLibraries()
Definition: PageRenderer.php:2125
‪TYPO3\CMS\Core\Page\PageRenderer\addRequireJsConfiguration
‪addRequireJsConfiguration(array $configuration)
Definition: PageRenderer.php:1404
‪TYPO3\CMS\Core\Page\PageRenderer\addJsLibrary
‪addJsLibrary($name, $file, $type='text/javascript', $compress=false, $forceOnTop=false, $allWrap='', $excludeFromConcatenation=false, $splitChar='|', $async=false, $integrity='', $defer=false, $crossorigin='', $nomodule=false)
Definition: PageRenderer.php:1013
‪TYPO3\CMS\Core\Utility\GeneralUtility\minifyJavaScript
‪static string minifyJavaScript($script, &$error='')
Definition: GeneralUtility.php:1713
‪TYPO3\CMS\Core\Page\PageRenderer\enableCompressJavascript
‪enableCompressJavascript()
Definition: PageRenderer.php:589
‪TYPO3\CMS\Core\Page\PageRenderer\doCompressCss
‪doCompressCss()
Definition: PageRenderer.php:2399
‪TYPO3\CMS\Core\Page\PageRenderer\getConcatenateCss
‪bool getConcatenateCss()
Definition: PageRenderer.php:840
‪TYPO3\CMS\Core\Page\PageRenderer\getIconMimeType
‪string getIconMimeType()
Definition: PageRenderer.php:770
‪TYPO3\CMS\Core\Utility\PathUtility\dirname
‪static string dirname($path)
Definition: PathUtility.php:186
‪TYPO3\CMS\Core\Information\Typo3Version
Definition: Typo3Version.php:21
‪TYPO3\CMS\Core\Page\PageRenderer\renderMainJavaScriptLibraries
‪string renderMainJavaScriptLibraries()
Definition: PageRenderer.php:1911
‪TYPO3\CMS\Core\Page\PageRenderer\addJsFooterFile
‪addJsFooterFile($file, $type='text/javascript', $compress=true, $forceOnTop=false, $allWrap='', $excludeFromConcatenation=false, $splitChar='|', $async=false, $integrity='', $defer=false, $crossorigin='', $nomodule=false)
Definition: PageRenderer.php:1126
‪TYPO3\CMS\Core\Localization\LocalizationFactory
Definition: LocalizationFactory.php:28
‪TYPO3\CMS\Core\Page\PageRenderer\$removeLineBreaksFromTemplate
‪bool $removeLineBreaksFromTemplate
Definition: PageRenderer.php:61
‪TYPO3\CMS\Core\Page\PageRenderer\getTemplateFile
‪string getTemplateFile()
Definition: PageRenderer.php:790
‪TYPO3\CMS\Core\Page\PageRenderer\loadRequireJs
‪loadRequireJs()
Definition: PageRenderer.php:1276
‪TYPO3\CMS\Core\Page\PageRenderer\renderCssFiles
‪string renderCssFiles()
Definition: PageRenderer.php:2054
‪TYPO3\CMS\Core\Page\PageRenderer\renderJavaScriptAndCss
‪array string[] renderJavaScriptAndCss()
Definition: PageRenderer.php:1758
‪TYPO3\CMS\Core\Page\PageRenderer\enableConcatenateCss
‪enableConcatenateCss()
Definition: PageRenderer.php:637
‪TYPO3\CMS\Core\Page\PageRenderer\$concatenateCss
‪bool $concatenateCss
Definition: PageRenderer.php:69
‪TYPO3\CMS\Core\Page\PageRenderer\addJsFooterLibrary
‪addJsFooterLibrary($name, $file, $type='text/javascript', $compress=false, $forceOnTop=false, $allWrap='', $excludeFromConcatenation=false, $splitChar='|', $async=false, $integrity='', $defer=false, $crossorigin='', $nomodule=false)
Definition: PageRenderer.php:1051
‪TYPO3\CMS\Core\Page\PageRenderer\getFavIcon
‪string getFavIcon()
Definition: PageRenderer.php:760
‪TYPO3\CMS\Core\Page\PageRenderer\addCssInlineBlock
‪addCssInlineBlock($name, $block, $compress=false, $forceOnTop=false)
Definition: PageRenderer.php:1259
‪TYPO3\CMS\Core\Page\PageRenderer\$compressor
‪ResourceCompressor $compressor
Definition: PageRenderer.php:95
‪TYPO3\CMS\Core\Page\PageRenderer\PART_COMPLETE
‪const PART_COMPLETE
Definition: PageRenderer.php:44
‪TYPO3\CMS\Core\MetaTag\MetaTagManagerRegistry
Definition: MetaTagManagerRegistry.php:28
‪TYPO3\CMS\Core\Resource\ResourceCompressor
Definition: ResourceCompressor.php:29
‪TYPO3\CMS\Core\Page\PageRenderer\setHeadTag
‪setHeadTag($headTag)
Definition: PageRenderer.php:471
‪TYPO3\CMS\Core\Page
Definition: AssetCollector.php:18
‪TYPO3\CMS\Core\Page\PageRenderer\doConcatenate
‪doConcatenate()
Definition: PageRenderer.php:2335
‪TYPO3\CMS\Core\Page\PageRenderer\getInlineLanguageLabelFiles
‪array getInlineLanguageLabelFiles()
Definition: PageRenderer.php:880
‪TYPO3\CMS\Core\Localization\Locales
Definition: Locales.php:30
‪TYPO3\CMS\Core\Utility\ArrayUtility\mergeRecursiveWithOverrule
‪static mergeRecursiveWithOverrule(array &$original, array $overrule, $addKeys=true, $includeEmptyValues=true, $enableUnsetFeature=true)
Definition: ArrayUtility.php:654
‪TYPO3\CMS\Core\Page\PageRenderer\getMetaTag
‪array getMetaTag(string $type, string $name)
Definition: PageRenderer.php:925
‪TYPO3\CMS\Core\Page\PageRenderer\getBodyContent
‪string getBodyContent()
Definition: PageRenderer.php:860
‪TYPO3\CMS\Core\Page\PageRenderer\disableConcatenateJavascript
‪disableConcatenateJavascript()
Definition: PageRenderer.php:629
‪TYPO3\CMS\Core\Page\PageRenderer\getState
‪array getState()
Definition: PageRenderer.php:329
‪TYPO3\CMS\Core\Page\PageRenderer\doCompress
‪doCompress()
Definition: PageRenderer.php:2390
‪TYPO3\CMS\Core\Page\PageRenderer\getHtmlTag
‪string getHtmlTag()
Definition: PageRenderer.php:730
‪TYPO3\CMS\Core\Page\PageRenderer\$compressJavascript
‪bool $compressJavascript
Definition: PageRenderer.php:53
‪TYPO3\CMS\Core\Page\PageRenderer\loadRequireJsModule
‪loadRequireJsModule($mainModuleName, $callBackFunction=null)
Definition: PageRenderer.php:1493
‪TYPO3\CMS\Core\Page\PageRenderer\getPreparedMarkerArrayForPageWithUncachedObjects
‪array getPreparedMarkerArrayForPageWithUncachedObjects($substituteHash)
Definition: PageRenderer.php:1852
‪TYPO3\CMS\Core\Page\PageRenderer\getMetaCharsetTag
‪string getMetaCharsetTag()
Definition: PageRenderer.php:740
‪TYPO3\CMS\Core\Package\PackageInterface
Definition: PackageInterface.php:22
‪TYPO3\CMS\Core\Page\PageRenderer\renderPageWithUncachedObjects
‪string renderPageWithUncachedObjects($substituteHash)
Definition: PageRenderer.php:1691
‪TYPO3\CMS\Core\Core\Environment\getContext
‪static ApplicationContext getContext()
Definition: Environment.php:133
‪TYPO3\CMS\Core\Page\PageRenderer\setXmlPrologAndDocType
‪setXmlPrologAndDocType($xmlPrologAndDocType)
Definition: PageRenderer.php:412
‪TYPO3\CMS\Core\Page\PageRenderer\setMetaTag
‪array< string, $jsFiles=array();protected array $jsFooterFiles=array();protected array $jsLibs=array();protected array $jsFooterLibs=array();protected array< string, $cssFiles=array();protected array< string, $cssLibs=array();protected string $title;protected string $charSet;protected string $favIcon;protected string $baseUrl;protected bool $renderXhtml=true;protected string $xmlPrologAndDocType='';protected array $metaTags=array();protected array $inlineComments=array();protected array $headerData=array();protected array $footerData=array();protected string $titleTag='< title >|</title >';protected string $metaCharsetTag='< meta http-equiv="Content-Type" content="text/html; charset=|"/>';protected string $htmlTag='< html >';protected string $headTag='< head >';protected string $baseUrlTag='< base href="|"/>';protected string $iconMimeType='';protected string $shortcutTag='< link rel="shortcut icon" href="%1$s"%2 $s/>';protected array< string, $jsInline=array();protected array $jsFooterInline=array();protected array< string, $cssInline=array();protected string $bodyContent;protected string $templateFile;protected string $requireJsPath='EXT:core/Resources/Public/JavaScript/Contrib/';protected bool $addRequireJs=false;protected array $requireJsConfig=array();protected array $internalRequireJsPathModuleNames=array();protected array $publicRequireJsConfig=array();protected array $inlineLanguageLabels=array();protected array $inlineLanguageLabelFiles=array();protected array $inlineSettings=array();protected array $inlineJavascriptWrap=array('< script type="text/javascript">' . LF . '' . LF, '' . LF . '</script >' . LF);protected array $inlineCssWrap=array('< style type="text/css">' . LF . '' . LF . '<!-- ' . LF, '-->' . LF . '' . LF . '</style >' . LF);protected string $compressError='';protected string $endingSlash='';protected MetaTagManagerRegistry $metaTagRegistry;protected static FrontendInterface $cache=null;public __construct( $templateFile='') { $this->reset();$this->locales=GeneralUtility::makeInstance(Locales::class);if( $templateFile !=='') { $this->templateFile=$templateFile;} $this->metaTagRegistry=GeneralUtility::makeInstance(MetaTagManagerRegistry::class);$this-> setMetaTag('name', 'generator', 'TYPO3 CMS')
‪TYPO3\CMS\Core\Page\PageRenderer\disableMoveJsFromHeaderToFooter
‪disableMoveJsFromHeaderToFooter()
Definition: PageRenderer.php:581
‪TYPO3\CMS\Core\Page\PageRenderer\addInlineSettingArray
‪addInlineSettingArray($namespace, array $array)
Definition: PageRenderer.php:1610
‪TYPO3\CMS\Core\Utility\PathUtility\getRelativePathTo
‪static string null getRelativePathTo($targetPath)
Definition: PathUtility.php:32
‪TYPO3\CMS\Core\Resource\ResourceCompressor\compressCssFiles
‪array compressCssFiles(array $cssFiles)
Definition: ResourceCompressor.php:305
‪TYPO3\CMS\Core\Page\PageRenderer\renderCssLibraries
‪string renderCssLibraries()
Definition: PageRenderer.php:2033
‪TYPO3\CMS\Core\Page\PageRenderer\addInlineLanguageLabel
‪addInlineLanguageLabel($key, $value)
Definition: PageRenderer.php:1540
‪TYPO3\CMS\Core\Page\PageRenderer\setHtmlTag
‪setHtmlTag($htmlTag)
Definition: PageRenderer.php:461
‪TYPO3\CMS\Core\Page\PageRenderer\getCompressor
‪ResourceCompressor getCompressor()
Definition: PageRenderer.php:2462
‪TYPO3\CMS\Core\Page\PageRenderer\executePreRenderHook
‪executePreRenderHook()
Definition: PageRenderer.php:2543
‪TYPO3\CMS\Core\Page\PageRenderer\getRenderXhtml
‪bool getRenderXhtml()
Definition: PageRenderer.php:720
‪TYPO3\CMS\Core\Page\PageRenderer\setBodyContent
‪setBodyContent($content)
Definition: PageRenderer.php:521
‪TYPO3\CMS\Core\Page\PageRenderer
Definition: PageRenderer.php:42
‪TYPO3\CMS\Core\Page\PageRenderer\addCssFile
‪addCssFile($file, $rel='stylesheet', $media='all', $title='', $compress=true, $forceOnTop=false, $allWrap='', $excludeFromConcatenation=false, $splitChar='|', $inline=false)
Definition: PageRenderer.php:1201
‪TYPO3\CMS\Core\Page\PageRenderer\REQUIREJS_SCOPE_RESOLVE
‪const REQUIREJS_SCOPE_RESOLVE
Definition: PageRenderer.php:49
‪TYPO3\CMS\Core\Page\PageRenderer\getCompressCss
‪bool getCompressCss()
Definition: PageRenderer.php:820
‪TYPO3\CMS\Core\Page\PageRenderer\doCompressJavaScript
‪doCompressJavaScript()
Definition: PageRenderer.php:2422
‪TYPO3\CMS\Core\Core\Environment\getProjectPath
‪static string getProjectPath()
Definition: Environment.php:169
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface\get
‪mixed get($entryIdentifier)
‪TYPO3\CMS\Core\Page\PageRenderer\setMetaCharsetTag
‪setMetaCharsetTag($metaCharsetTag)
Definition: PageRenderer.php:451
‪TYPO3\CMS\Core\Resource\ResourceCompressor\compressJsFile
‪string compressJsFile($filename)
Definition: ResourceCompressor.php:389
‪TYPO3\CMS\Core\Page\PageRenderer\$concatenateJavascript
‪bool $concatenateJavascript
Definition: PageRenderer.php:65
‪TYPO3\CMS\Core\Page\PageRenderer\getTitle
‪string getTitle()
Definition: PageRenderer.php:690
‪TYPO3\CMS\Core\Page\PageRenderer\setBaseUrl
‪setBaseUrl($baseUrl)
Definition: PageRenderer.php:501
‪TYPO3\CMS\Core\Page\PageRenderer\addCssLibrary
‪addCssLibrary($file, $rel='stylesheet', $media='all', $title='', $compress=true, $forceOnTop=false, $allWrap='', $excludeFromConcatenation=false, $splitChar='|', $inline=false)
Definition: PageRenderer.php:1233
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:38
‪TYPO3\CMS\Core\Page\PageRenderer\REQUIREJS_SCOPE_CONFIG
‪const REQUIREJS_SCOPE_CONFIG
Definition: PageRenderer.php:48
‪TYPO3\CMS\Core\Page\PageRenderer\PART_FOOTER
‪const PART_FOOTER
Definition: PageRenderer.php:46
‪TYPO3\CMS\Core\Page\PageRenderer\getCharSet
‪string getCharSet()
Definition: PageRenderer.php:700
‪TYPO3\CMS\Core\Page\PageRenderer\addInlineLanguageLabelArray
‪addInlineLanguageLabelArray(array $array)
Definition: PageRenderer.php:1552
‪TYPO3\CMS\Core\Page\PageRenderer\render
‪string render($part=self::PART_COMPLETE)
Definition: PageRenderer.php:1649
‪TYPO3\CMS\Core\Page\PageRenderer\setTitle
‪setTitle($title)
Definition: PageRenderer.php:385
‪TYPO3\CMS\Core\Page\PageRenderer\getInlineLanguageLabels
‪array getInlineLanguageLabels()
Definition: PageRenderer.php:870
‪TYPO3\CMS\Core\Page\PageRenderer\$compressCss
‪bool $compressCss
Definition: PageRenderer.php:57
‪TYPO3\CMS\Core\Page\PageRenderer\setCache
‪static setCache(FrontendInterface $cache)
Definition: PageRenderer.php:350
‪TYPO3\CMS\Core\Page\PageRenderer\getStreamlinedFileName
‪string getStreamlinedFileName($file, $prepareForOutput=true)
Definition: PageRenderer.php:2501
‪TYPO3\CMS\Core\Cache\CacheManager
Definition: CacheManager.php:35
‪TYPO3\CMS\Core\Page\PageRenderer\setLanguage
‪setLanguage($lang)
Definition: PageRenderer.php:432
‪TYPO3\CMS\Core\Page\PageRenderer\addInlineComment
‪addInlineComment($comment)
Definition: PageRenderer.php:965
‪TYPO3\CMS\Core\Page\PageRenderer\setRequireJsPath
‪setRequireJsPath($path)
Definition: PageRenderer.php:531
‪TYPO3\CMS\Core\Page\PageRenderer\doConcatenateJavaScript
‪doConcatenateJavaScript()
Definition: PageRenderer.php:2344
‪TYPO3\CMS\Core\Page\PageRenderer\executePostRenderHook
‪executePostRenderHook(&$jsLibs, &$jsFiles, &$jsFooterFiles, &$cssLibs, &$cssFiles, &$jsInline, &$cssInline, &$jsFooterInline, &$jsFooterLibs)
Definition: PageRenderer.php:2607
‪TYPO3\CMS\Core\Page\PageRenderer\addJsFooterInlineCode
‪addJsFooterInlineCode($name, $block, $compress=true, $forceOnTop=false)
Definition: PageRenderer.php:1175
‪TYPO3\CMS\Core\Page\PageRenderer\enableMoveJsFromHeaderToFooter
‪enableMoveJsFromHeaderToFooter()
Definition: PageRenderer.php:573
‪TYPO3\CMS\Core\Resource\ResourceCompressor\concatenateCssFiles
‪array concatenateCssFiles(array $cssFiles)
Definition: ResourceCompressor.php:106
‪TYPO3\CMS\Core\Core\ApplicationContext\isDevelopment
‪bool isDevelopment()
Definition: ApplicationContext.php:96
‪TYPO3\CMS\Core\Page\PageRenderer\processJsFile
‪string processJsFile($filename)
Definition: PageRenderer.php:2478
‪TYPO3\CMS\Core\Page\PageRenderer\getPreparedMarkerArray
‪array getPreparedMarkerArray($jsLibs, $jsFiles, $jsFooterFiles, $cssLibs, $cssFiles, $jsInline, $cssInline, $jsFooterInline, $jsFooterLibs, $metaTags)
Definition: PageRenderer.php:1817
‪TYPO3\CMS\Core\Page\PageRenderer\setIconMimeType
‪setIconMimeType($iconMimeType)
Definition: PageRenderer.php:491
‪TYPO3\CMS\Core\Page\PageRenderer\getLanguage
‪string getLanguage()
Definition: PageRenderer.php:710
‪TYPO3\CMS\Core\Page\PageRenderer\addHeaderData
‪addHeaderData($data)
Definition: PageRenderer.php:977
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
Definition: FrontendInterface.php:22
‪TYPO3\CMS\Core\Page\PageRenderer\updateState
‪updateState(array $newState)
Definition: PageRenderer.php:309
‪TYPO3\CMS\Core\Page\PageRenderer\renderMetaTagsFromAPI
‪array renderMetaTagsFromAPI()
Definition: PageRenderer.php:1670
‪TYPO3\CMS\Core\Page\PageRenderer\includeLanguageFileForInline
‪includeLanguageFileForInline($fileRef, $selectionPrefix='', $stripFromSelectionName='')
Definition: PageRenderer.php:2260
‪TYPO3\CMS\Core\Utility\ArrayUtility
Definition: ArrayUtility.php:24
‪TYPO3\CMS\Core\Page\PageRenderer\getRemoveLineBreaksFromTemplate
‪bool getRemoveLineBreaksFromTemplate()
Definition: PageRenderer.php:850
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:23
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Page\PageRenderer\convertCharsetRecursivelyToUtf8
‪convertCharsetRecursivelyToUtf8(&$data, string $fromCharset)
Definition: PageRenderer.php:1988
‪TYPO3\CMS\Core\Page\PageRenderer\getHeadTag
‪string getHeadTag()
Definition: PageRenderer.php:750
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:40
‪TYPO3\CMS\Core\Page\PageRenderer\$lang
‪string $lang
Definition: PageRenderer.php:84
‪TYPO3\CMS\Core\Page\PageRenderer\setCharSet
‪setCharSet($charSet)
Definition: PageRenderer.php:422
‪TYPO3\CMS\Core\Page\PageRenderer\enableCompressCss
‪enableCompressCss()
Definition: PageRenderer.php:605
‪TYPO3\CMS\Core\Page\PageRenderer\doConcatenateCss
‪doConcatenateCss()
Definition: PageRenderer.php:2368
‪TYPO3\CMS\Core\Page\PageRenderer\disableRemoveLineBreaksFromTemplate
‪disableRemoveLineBreaksFromTemplate()
Definition: PageRenderer.php:661
‪TYPO3\CMS\Core\Page\PageRenderer\$languageDependencies
‪array $languageDependencies
Definition: PageRenderer.php:91
‪TYPO3\CMS\Core\Page\PageRenderer\addJsFile
‪addJsFile($file, $type='text/javascript', $compress=true, $forceOnTop=false, $allWrap='', $excludeFromConcatenation=false, $splitChar='|', $async=false, $integrity='', $defer=false, $crossorigin='', $nomodule=false)
Definition: PageRenderer.php:1089
‪TYPO3\CMS\Core\Page\PageRenderer\addFooterData
‪addFooterData($data)
Definition: PageRenderer.php:989
‪TYPO3\CMS\Core\Page\PageRenderer\addInlineSetting
‪addInlineSetting($namespace, $key, $value)
Definition: PageRenderer.php:1584
‪TYPO3\CMS\Core\Page\PageRenderer\removeMetaTag
‪removeMetaTag(string $type, string $name)
Definition: PageRenderer.php:950
‪TYPO3\CMS\Core\Page\PageRenderer\executeRenderPostTransformHook
‪executeRenderPostTransformHook()
Definition: PageRenderer.php:2570
‪TYPO3\CMS\Core\Page\PageRenderer\getBaseUrl
‪string getBaseUrl()
Definition: PageRenderer.php:780
‪TYPO3\CMS\Core\Page\PageRenderer\parseLanguageLabelsForJavaScript
‪array parseLanguageLabelsForJavaScript()
Definition: PageRenderer.php:1946
‪TYPO3\CMS\Core\Page\PageRenderer\prepareRendering
‪prepareRendering()
Definition: PageRenderer.php:1741
‪TYPO3\CMS\Core\Page\PageRenderer\$locales
‪Locales $locales
Definition: PageRenderer.php:77
‪TYPO3\CMS\Core\Page\PageRenderer\getRequireJsConfig
‪array getRequireJsConfig(string $scope=null)
Definition: PageRenderer.php:540
‪TYPO3\CMS\Core\Page\PageRenderer\readLLfile
‪array readLLfile($fileRef)
Definition: PageRenderer.php:2293
‪TYPO3\CMS\Core\Page\PageRenderer\disableCompressCss
‪disableCompressCss()
Definition: PageRenderer.php:613
‪TYPO3\CMS\Core\Page\PageRenderer\setRenderXhtml
‪setRenderXhtml($enable)
Definition: PageRenderer.php:395
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface\set
‪set($entryIdentifier, $data, array $tags=[], $lifetime=null)
‪TYPO3\CMS\Core\Page\PageRenderer\setTemplateFile
‪setTemplateFile($file)
Definition: PageRenderer.php:511
‪TYPO3\CMS\Core\Page\PageRenderer\enableRemoveLineBreaksFromTemplate
‪enableRemoveLineBreaksFromTemplate()
Definition: PageRenderer.php:653
‪TYPO3\CMS\Core\Page\PageRenderer\addBodyContent
‪addBodyContent($content)
Definition: PageRenderer.php:1633
‪TYPO3\CMS\Core\Service\MarkerBasedTemplateService
Definition: MarkerBasedTemplateService.php:27
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Core\Page\PageRenderer\findRequireJsBaseModuleName
‪string null findRequireJsBaseModuleName(string $moduleName)
Definition: PageRenderer.php:1521
‪TYPO3\CMS\Core\Resource\ResourceCompressor\compressJsFiles
‪array compressJsFiles(array $jsFiles)
Definition: ResourceCompressor.php:366
‪TYPO3\CMS\Core\Utility\PathUtility\getAbsoluteWebPath
‪static string getAbsoluteWebPath($targetPath)
Definition: PathUtility.php:43
‪TYPO3\CMS\Core\Page\PageRenderer\getCompressJavascript
‪bool getCompressJavascript()
Definition: PageRenderer.php:810
‪TYPO3\CMS\Core\Page\PageRenderer\setMetaTag
‪setMetaTag(string $type, string $name, string $content, array $subProperties=[], $replace=true)
Definition: PageRenderer.php:902
‪TYPO3\CMS\Core\Page\PageRenderer\disableConcatenateCss
‪disableConcatenateCss()
Definition: PageRenderer.php:645
‪TYPO3\CMS\Core\Page\PageRenderer\enableDebugMode
‪enableDebugMode()
Definition: PageRenderer.php:670
‪TYPO3\CMS\Backend\Routing\Router
Definition: Router.php:34
‪TYPO3\CMS\Core\Page\PageRenderer\addAjaxUrlsToInlineSettings
‪addAjaxUrlsToInlineSettings(bool $publicRoutesOnly=false)
Definition: PageRenderer.php:2004
‪TYPO3\CMS\Core\Page\PageRenderer\renderInlineJavaScript
‪array string[] renderInlineJavaScript()
Definition: PageRenderer.php:2217
‪TYPO3\CMS\Core\Page\PageRenderer\PART_HEADER
‪const PART_HEADER
Definition: PageRenderer.php:45
‪TYPO3\CMS\Core\Page\PageRenderer\reset
‪reset()
Definition: PageRenderer.php:358
‪TYPO3\CMS\Core\Page\PageRenderer\addJsInlineCode
‪addJsInlineCode($name, $block, $compress=true, $forceOnTop=false)
Definition: PageRenderer.php:1155
‪TYPO3\CMS\Core\Utility\GeneralUtility\underscoredToUpperCamelCase
‪static string underscoredToUpperCamelCase($string)
Definition: GeneralUtility.php:890
‪TYPO3\CMS\Core\Page\PageRenderer\computeRequireJsConfig
‪array computeRequireJsConfig($isDevelopment, array $packages)
Definition: PageRenderer.php:1309
‪TYPO3\CMS\Core\Page\PageRenderer\getMoveJsFromHeaderToFooter
‪bool getMoveJsFromHeaderToFooter()
Definition: PageRenderer.php:800
‪TYPO3\CMS\Core\Resource\ResourceCompressor\concatenateJsFiles
‪array concatenateJsFiles(array $jsFiles)
Definition: ResourceCompressor.php:153
‪TYPO3\CMS\Core\Page\PageRenderer\getAbsoluteWebPath
‪string getAbsoluteWebPath(string $file)
Definition: PageRenderer.php:2527
‪TYPO3\CMS\Core\Page\PageRenderer\getConcatenateJavascript
‪bool getConcatenateJavascript()
Definition: PageRenderer.php:830
‪TYPO3\CMS\Core\Page\PageRenderer\createInlineCssTagFromFile
‪string createInlineCssTagFromFile(string $file, array $properties)
Definition: PageRenderer.php:2653
‪TYPO3\CMS\Core\Resource\RelativeCssPathFixer
Definition: RelativeCssPathFixer.php:29
‪TYPO3\CMS\Core\Page\PageRenderer\getTemplateForPart
‪string getTemplateForPart($part)
Definition: PageRenderer.php:1887
‪TYPO3\CMS\Core\Page\PageRenderer\createCssTag
‪string createCssTag(array $properties, string $file)
Definition: PageRenderer.php:2077
‪TYPO3\CMS\Core\Page\PageRenderer\$moveJsFromHeaderToFooter
‪bool $moveJsFromHeaderToFooter
Definition: PageRenderer.php:73