From 11d7544a5e8fb0961f999d4bb19c16ad98130a0b Mon Sep 17 00:00:00 2001 From: BettyFromHH Date: Fri, 29 May 2026 16:38:46 +0200 Subject: [PATCH 01/11] Fix for class.ilTemplate.php --- .../ILIAS/UICore/classes/class.ilTemplate.php | 131 +++++++++++------- 1 file changed, 79 insertions(+), 52 deletions(-) diff --git a/components/ILIAS/UICore/classes/class.ilTemplate.php b/components/ILIAS/UICore/classes/class.ilTemplate.php index c26b2e22f472..5cc272f0ba73 100755 --- a/components/ILIAS/UICore/classes/class.ilTemplate.php +++ b/components/ILIAS/UICore/classes/class.ilTemplate.php @@ -337,76 +337,103 @@ protected function fileExistsInSkin(string $path): bool */ protected function getTemplatePath(string $a_tplname, string $a_in_module = ''): string { - $ilias_root = realpath(__DIR__ . '/../../../../') . '/'; + $ilias_root = realpath(__DIR__ . '/../../../../'); - if (str_starts_with($a_in_module, $ilias_root)) { - $a_in_module = str_replace($ilias_root, '', $a_in_module); - } + $skin = $this->getCurrentSkin(); + $style = $this->getCurrentStyle(); - if (str_ends_with($a_in_module, '/')) { - $a_in_module = rtrim($a_in_module, '/'); - } + $default_path = $ilias_root; + $skin_base_path = $ilias_root . '/public/Customizing/skin'; + $skin_path = $skin_base_path . '/' . $skin; + $style_path = $skin_base_path . '/' . $skin . '/' . $style; - $tpl_sub_path = '/templates/default/'; - if (str_starts_with($a_tplname, 'components/ILIAS/UI/')) { - $a_in_module = 'components/ILIAS/UI/src'; - $a_tplname = str_replace('components/ILIAS/UI/src/templates/default/', '', $a_tplname); - } + $is_custom_skin = !($skin === 'default' && $style === 'delos'); - if (str_starts_with($a_tplname, $ilias_root)) { - $a_tplname = str_replace($ilias_root, '', $a_tplname); - } + $template_type = 0; + $template_name = $a_tplname; + $component = $a_in_module; + $ui_component = null; - // Special Cases for plugins - if (str_starts_with($a_tplname, 'Customizing/global/plugins/')) { - $a_tplname = "public/$a_tplname"; - } - if (str_contains($a_tplname, 'public/Customizing/global/plugins')) { - $tpl_sub_path = ''; - } + ///////////////////////////////////////////////// + /// Split & sort everything + /// + if(str_starts_with($component, 'components/')) { + $template_type = 1; + } else { + if($component === '' && str_contains($template_name, '/UI/')) { + $template_type = 2; - // Proceed with skin lookup - $base_path = $ilias_root; - $default = $base_path . $a_in_module . $tpl_sub_path . $a_tplname; + $template_name = substr($a_tplname, strrpos($a_tplname, '/') + 1); + $ui_path = str_replace('/' . $template_name, '', $a_tplname); - $skin = $this->getCurrentSkin(); - if ($skin === 'default') { - return $default; + if(!str_ends_with($ui_path, '/templates/default')) { + $ui_component = substr($ui_path, strrpos($ui_path, '/') + 1); + $ui_path = str_replace('/' . $ui_component, '', $ui_path); + } + + $component = str_replace('/templates/default', '', $ui_path); + } } - $style = $this->getCurrentStyle(); - $base_skin_path = $ilias_root . 'public/Customizing/skin/' . $skin; - - $paths = [ - "$base_skin_path/$style/components/ILIAS/UI/src", - "$base_skin_path/$style/components/ILIAS/UI", - "$base_skin_path/$style/UI/src", - "$base_skin_path/$style/UI", - "$base_skin_path/components/ILIAS/UI/src", - "$base_skin_path/components/ILIAS/UI", - "$base_skin_path/UI/src", - "$base_skin_path/UI", - ]; + ///////////////////////////////////////////////// + /// Build paths + /// + switch($template_type) { + case 1: // Component Template + $default_path .= '/' . $component . '/templates/default'; + $skin_path .= '/' . $component . '/'; + $style_path .= '/' . $component . '/'; + break; + case 2: // UI-Framework Template + $default_path .= '/' . $component . '/templates/default'; + if($ui_component !== null) { + $default_path .= '/' . $ui_component; + } - foreach ($paths as $path) { - if (is_dir($path)) { - $a_in_module = str_replace($base_skin_path . '/', '', $path); break; - } + default: // Basic Template + $default_path .= '/templates/default/'; + break; } - $from_style = $base_skin_path . '/' . $style . '/' . $a_in_module . '/' . $a_tplname; - if ($this->fileexistsinskin($from_style)) { - return $from_style; + ///////////////////////////////////////////////// + /// Return default template + /// + if (!$is_custom_skin) { + return $default_path . $template_name; } - $from_skin = $base_skin_path . '/' . $a_in_module . '/' . $a_tplname; - if ($this->fileexistsinskin($from_skin)) { - return $from_skin; + ///////////////////////////////////////////////// + /// Return custom skins template or fallback + /// + $custom_skin_UI_paths = [ + "$style_path/components/ILIAS/UI/src/", + "$style_path/components/ILIAS/UI", + "$style_path/UI/src", + "$style_path/UI", + "$skin_path/components/ILIAS/UI/src", + "$skin_path/components/ILIAS/UI", + "$skin_path/UI/src", + "$skin_path/UI", + ]; + + if($template_type === 2) { + foreach ($custom_skin_UI_paths as $custom_skin_UI_path) { + if ($this->fileexistsinskin($custom_skin_UI_path . $template_name)) { + return $style_path . $template_name; + } + } + } else { + if ($this->fileexistsinskin($style_path . $template_name)) { + return $style_path . $template_name; + } + if ($this->fileexistsinskin($skin_path . $template_name)) { + return $skin_path . $template_name; + } } - return $default; + return $default_path .$template_name; } /** From 506f3c174464469470567ce399c2142e6e46f6bf Mon Sep 17 00:00:00 2001 From: BettyFromHH Date: Fri, 29 May 2026 17:17:29 +0200 Subject: [PATCH 02/11] Fix for class.ilTemplate.php --- .../ILIAS/UICore/classes/class.ilTemplate.php | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/components/ILIAS/UICore/classes/class.ilTemplate.php b/components/ILIAS/UICore/classes/class.ilTemplate.php index 5cc272f0ba73..6df072acc170 100755 --- a/components/ILIAS/UICore/classes/class.ilTemplate.php +++ b/components/ILIAS/UICore/classes/class.ilTemplate.php @@ -338,6 +338,7 @@ protected function fileExistsInSkin(string $path): bool protected function getTemplatePath(string $a_tplname, string $a_in_module = ''): string { $ilias_root = realpath(__DIR__ . '/../../../../'); + $ui_component_base_path = 'components/ILIAS/UI/src'; $skin = $this->getCurrentSkin(); $style = $this->getCurrentStyle(); @@ -366,13 +367,10 @@ protected function getTemplatePath(string $a_tplname, string $a_in_module = ''): $template_name = substr($a_tplname, strrpos($a_tplname, '/') + 1); $ui_path = str_replace('/' . $template_name, '', $a_tplname); + $ui_path = str_replace($ui_component_base_path . '/templates/default/', '', $ui_path); + $ui_component = trim($ui_path, '/'); - if(!str_ends_with($ui_path, '/templates/default')) { - $ui_component = substr($ui_path, strrpos($ui_path, '/') + 1); - $ui_path = str_replace('/' . $ui_component, '', $ui_path); - } - - $component = str_replace('/templates/default', '', $ui_path); + $component = $ui_component_base_path; } } @@ -381,14 +379,14 @@ protected function getTemplatePath(string $a_tplname, string $a_in_module = ''): /// switch($template_type) { case 1: // Component Template - $default_path .= '/' . $component . '/templates/default'; + $default_path .= '/' . $component . '/templates/default/'; $skin_path .= '/' . $component . '/'; $style_path .= '/' . $component . '/'; break; case 2: // UI-Framework Template - $default_path .= '/' . $component . '/templates/default'; + $default_path .= '/' . $component . '/templates/default/'; if($ui_component !== null) { - $default_path .= '/' . $ui_component; + $default_path .= $ui_component . '/'; } break; From 9aa61735df70dd2a9dd1d25aacd4c3b7ab37b4fe Mon Sep 17 00:00:00 2001 From: BettyFromHH Date: Fri, 29 May 2026 17:29:22 +0200 Subject: [PATCH 03/11] Create comment with full description in class.ilTemplate.php for getTemplatePath-function --- .../ILIAS/UICore/classes/class.ilTemplate.php | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/components/ILIAS/UICore/classes/class.ilTemplate.php b/components/ILIAS/UICore/classes/class.ilTemplate.php index 6df072acc170..0f0aa79e6df6 100755 --- a/components/ILIAS/UICore/classes/class.ilTemplate.php +++ b/components/ILIAS/UICore/classes/class.ilTemplate.php @@ -333,6 +333,42 @@ protected function fileExistsInSkin(string $path): bool } /** + * Resolves the full filesystem path to a template while taking into account + * UI framework structure, component hierarchy, and custom skin/style overrides. + * + * The method supports three template types: + * - Basic templates (default templates without UI or component context) + * /templates/default/ + * - Component templates (templates inside ILIAS components) + * /components/ILIAS//templates/default/ + * - UI framework templates (templates from the ILIAS UI framework) + * /components/ILIAS/UI/src/templates/default// + * + * Additionally, it checks whether a custom skin is active. If so, the method + * first looks for an overridden version of the template in the skin or style + * directories. If no matching override is found, it falls back to the default + * template. + * + * Search order when a custom skin is active: + * 1. Style/SubStyle-specific paths (UI and component) + * 2. Skin-specific paths (UI and component) + * 3. Default template (fallback) + * + * Special notes: + * - UI framework templates are automatically detected via the "/UI/" path segment + * - Component templates are determined via the `$a_in_module` parameter + * - UI components can be resolved in a more granular way + * - fileexistsinskin() is used to check for skin overrides + * + * @param string $a_tplname + * Relative path to the template (e.g. "tpl.std.html" or full UI path) + * + * @param string $a_in_module + * Optional module path of the component (e.g. "components/ILIAS/XYZ") + * + * @return string + * Fully resolved filesystem path to the template (skin, style, or default) + * * @throws ilSystemStyleException */ protected function getTemplatePath(string $a_tplname, string $a_in_module = ''): string @@ -350,6 +386,9 @@ protected function getTemplatePath(string $a_tplname, string $a_in_module = ''): $is_custom_skin = !($skin === 'default' && $style === 'delos'); + $a_in_module = trim($a_in_module, '/'); + $a_tplname = trim($a_tplname, '/'); + $template_type = 0; $template_name = $a_tplname; $component = $a_in_module; From bb63ed666b961776afe40b9cb4c63387da16dac5 Mon Sep 17 00:00:00 2001 From: BettyFromHH Date: Fri, 29 May 2026 18:27:16 +0200 Subject: [PATCH 04/11] Fix Plugin-Path in getTemplatePath() in class.ilTemplate.php --- .../ILIAS/UICore/classes/class.ilTemplate.php | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/components/ILIAS/UICore/classes/class.ilTemplate.php b/components/ILIAS/UICore/classes/class.ilTemplate.php index 0f0aa79e6df6..7a2428c83eb6 100755 --- a/components/ILIAS/UICore/classes/class.ilTemplate.php +++ b/components/ILIAS/UICore/classes/class.ilTemplate.php @@ -388,7 +388,7 @@ protected function getTemplatePath(string $a_tplname, string $a_in_module = ''): $a_in_module = trim($a_in_module, '/'); $a_tplname = trim($a_tplname, '/'); - + $template_type = 0; $template_name = $a_tplname; $component = $a_in_module; @@ -400,17 +400,17 @@ protected function getTemplatePath(string $a_tplname, string $a_in_module = ''): /// if(str_starts_with($component, 'components/')) { $template_type = 1; - } else { - if($component === '' && str_contains($template_name, '/UI/')) { - $template_type = 2; + } elseif(str_contains($component, 'public/Customizing/global/plugins')) { + $template_type = 3; + } elseif($component === '' && str_contains($template_name, '/UI/')) { + $template_type = 2; - $template_name = substr($a_tplname, strrpos($a_tplname, '/') + 1); - $ui_path = str_replace('/' . $template_name, '', $a_tplname); - $ui_path = str_replace($ui_component_base_path . '/templates/default/', '', $ui_path); - $ui_component = trim($ui_path, '/'); + $template_name = substr($a_tplname, strrpos($a_tplname, '/') + 1); + $ui_path = str_replace('/' . $template_name, '', $a_tplname); + $ui_path = str_replace($ui_component_base_path . '/templates/default/', '', $ui_path); + $ui_component = trim($ui_path, '/'); - $component = $ui_component_base_path; - } + $component = $ui_component_base_path; } ///////////////////////////////////////////////// @@ -427,8 +427,9 @@ protected function getTemplatePath(string $a_tplname, string $a_in_module = ''): if($ui_component !== null) { $default_path .= $ui_component . '/'; } - break; + case 3: // Plugin Templates + return $default_path . '/' . $component . '/' . $template_name; default: // Basic Template $default_path .= '/templates/default/'; break; @@ -445,7 +446,7 @@ protected function getTemplatePath(string $a_tplname, string $a_in_module = ''): /// Return custom skins template or fallback /// $custom_skin_UI_paths = [ - "$style_path/components/ILIAS/UI/src/", + "$style_path/components/ILIAS/UI/src", "$style_path/components/ILIAS/UI", "$style_path/UI/src", "$style_path/UI", @@ -457,8 +458,8 @@ protected function getTemplatePath(string $a_tplname, string $a_in_module = ''): if($template_type === 2) { foreach ($custom_skin_UI_paths as $custom_skin_UI_path) { - if ($this->fileexistsinskin($custom_skin_UI_path . $template_name)) { - return $style_path . $template_name; + if ($this->fileexistsinskin($custom_skin_UI_path . '/' . $ui_component . '/' . $template_name)) { + return $custom_skin_UI_path . '/' . $ui_component . '/' . $template_name; } } } else { From f41316e42aad651605e9a9734ac3364e9e77aeeb Mon Sep 17 00:00:00 2001 From: BettyFromHH Date: Fri, 29 May 2026 18:43:07 +0200 Subject: [PATCH 05/11] Fix Plugin-Path in getTemplatePath() in class.ilTemplate.php --- components/ILIAS/UICore/classes/class.ilTemplate.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/components/ILIAS/UICore/classes/class.ilTemplate.php b/components/ILIAS/UICore/classes/class.ilTemplate.php index 7a2428c83eb6..faae8e824eef 100755 --- a/components/ILIAS/UICore/classes/class.ilTemplate.php +++ b/components/ILIAS/UICore/classes/class.ilTemplate.php @@ -429,6 +429,12 @@ protected function getTemplatePath(string $a_tplname, string $a_in_module = ''): } break; case 3: // Plugin Templates + if(str_starts_with($component, $default_path)) { + $component = str_replace($default_path . '/', '', $component); + } + if(!str_ends_with($component, '/templates/default')) { + $component .= '/templates/default'; + } return $default_path . '/' . $component . '/' . $template_name; default: // Basic Template $default_path .= '/templates/default/'; From 2788843f25cfce5d811ce1b815d0e6859974622c Mon Sep 17 00:00:00 2001 From: BettyFromHH Date: Fri, 29 May 2026 18:49:36 +0200 Subject: [PATCH 06/11] Fix Plugin-Path in getTemplatePath() in class.ilTemplate.php --- components/ILIAS/UICore/classes/class.ilTemplate.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/ILIAS/UICore/classes/class.ilTemplate.php b/components/ILIAS/UICore/classes/class.ilTemplate.php index faae8e824eef..9139418fbdb3 100755 --- a/components/ILIAS/UICore/classes/class.ilTemplate.php +++ b/components/ILIAS/UICore/classes/class.ilTemplate.php @@ -402,6 +402,10 @@ protected function getTemplatePath(string $a_tplname, string $a_in_module = ''): $template_type = 1; } elseif(str_contains($component, 'public/Customizing/global/plugins')) { $template_type = 3; + if($component === '') { + $component = substr($a_tplname, 0, strrpos($a_tplname, '/')); + $template_name = substr($a_tplname, strrpos($a_tplname, '/') + 1); + } } elseif($component === '' && str_contains($template_name, '/UI/')) { $template_type = 2; From 83b86474606bbc0e8673cb5f7467c686fa6c3930 Mon Sep 17 00:00:00 2001 From: BettyFromHH Date: Fri, 29 May 2026 19:00:54 +0200 Subject: [PATCH 07/11] Fix Plugin-Path in getTemplatePath() in class.ilTemplate.php --- .../ILIAS/UICore/classes/class.ilTemplate.php | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/components/ILIAS/UICore/classes/class.ilTemplate.php b/components/ILIAS/UICore/classes/class.ilTemplate.php index 9139418fbdb3..cbc4f5e346ea 100755 --- a/components/ILIAS/UICore/classes/class.ilTemplate.php +++ b/components/ILIAS/UICore/classes/class.ilTemplate.php @@ -402,10 +402,6 @@ protected function getTemplatePath(string $a_tplname, string $a_in_module = ''): $template_type = 1; } elseif(str_contains($component, 'public/Customizing/global/plugins')) { $template_type = 3; - if($component === '') { - $component = substr($a_tplname, 0, strrpos($a_tplname, '/')); - $template_name = substr($a_tplname, strrpos($a_tplname, '/') + 1); - } } elseif($component === '' && str_contains($template_name, '/UI/')) { $template_type = 2; @@ -433,13 +429,11 @@ protected function getTemplatePath(string $a_tplname, string $a_in_module = ''): } break; case 3: // Plugin Templates - if(str_starts_with($component, $default_path)) { - $component = str_replace($default_path . '/', '', $component); - } - if(!str_ends_with($component, '/templates/default')) { - $component .= '/templates/default'; + if($component === '') { + return $template_name; + } else { + return $component . '/templates/default/' . $template_name; } - return $default_path . '/' . $component . '/' . $template_name; default: // Basic Template $default_path .= '/templates/default/'; break; From 9ea693bbb90baac86397fff002ccef96bd9e8c3f Mon Sep 17 00:00:00 2001 From: BettyFromHH Date: Fri, 29 May 2026 19:21:38 +0200 Subject: [PATCH 08/11] Fix Plugin-Path in getTemplatePath() in class.ilTemplate.php --- components/ILIAS/UICore/classes/class.ilTemplate.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/ILIAS/UICore/classes/class.ilTemplate.php b/components/ILIAS/UICore/classes/class.ilTemplate.php index cbc4f5e346ea..8edb7e0537fd 100755 --- a/components/ILIAS/UICore/classes/class.ilTemplate.php +++ b/components/ILIAS/UICore/classes/class.ilTemplate.php @@ -398,10 +398,10 @@ protected function getTemplatePath(string $a_tplname, string $a_in_module = ''): ///////////////////////////////////////////////// /// Split & sort everything /// - if(str_starts_with($component, 'components/')) { - $template_type = 1; - } elseif(str_contains($component, 'public/Customizing/global/plugins')) { + if(str_contains($component, 'public/Customizing/global/plugins')) { $template_type = 3; + } elseif(str_starts_with($component, 'components/')) { + $template_type = 1; } elseif($component === '' && str_contains($template_name, '/UI/')) { $template_type = 2; @@ -432,7 +432,7 @@ protected function getTemplatePath(string $a_tplname, string $a_in_module = ''): if($component === '') { return $template_name; } else { - return $component . '/templates/default/' . $template_name; + return '/' . $component . '/templates/default/' . $template_name; } default: // Basic Template $default_path .= '/templates/default/'; From 993aa1c1826729b60015b8d37ac1ca0bf5e22f30 Mon Sep 17 00:00:00 2001 From: BettyFromHH Date: Fri, 29 May 2026 19:28:37 +0200 Subject: [PATCH 09/11] Fix Plugin-Path in getTemplatePath() in class.ilTemplate.php --- components/ILIAS/UICore/classes/class.ilTemplate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/ILIAS/UICore/classes/class.ilTemplate.php b/components/ILIAS/UICore/classes/class.ilTemplate.php index 8edb7e0537fd..7e2bebb9c2dc 100755 --- a/components/ILIAS/UICore/classes/class.ilTemplate.php +++ b/components/ILIAS/UICore/classes/class.ilTemplate.php @@ -430,7 +430,7 @@ protected function getTemplatePath(string $a_tplname, string $a_in_module = ''): break; case 3: // Plugin Templates if($component === '') { - return $template_name; + return '/' . $a_tplname; } else { return '/' . $component . '/templates/default/' . $template_name; } From c435bed886da854cff9ab3dedf94940e3b1202a8 Mon Sep 17 00:00:00 2001 From: BettyFromHH Date: Fri, 29 May 2026 19:37:45 +0200 Subject: [PATCH 10/11] Fix Plugin-Path in getTemplatePath() in class.ilTemplate.php --- components/ILIAS/UICore/classes/class.ilTemplate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/ILIAS/UICore/classes/class.ilTemplate.php b/components/ILIAS/UICore/classes/class.ilTemplate.php index 7e2bebb9c2dc..d9ce6988057f 100755 --- a/components/ILIAS/UICore/classes/class.ilTemplate.php +++ b/components/ILIAS/UICore/classes/class.ilTemplate.php @@ -398,7 +398,7 @@ protected function getTemplatePath(string $a_tplname, string $a_in_module = ''): ///////////////////////////////////////////////// /// Split & sort everything /// - if(str_contains($component, 'public/Customizing/global/plugins')) { + if(str_contains($component, 'public/Customizing/global/plugins') || str_contains($template_name, 'public/Customizing/global/components/')) { $template_type = 3; } elseif(str_starts_with($component, 'components/')) { $template_type = 1; From 8e6337798ade269f107b750ef27bd968fda255ea Mon Sep 17 00:00:00 2001 From: BettyFromHH Date: Fri, 29 May 2026 19:41:46 +0200 Subject: [PATCH 11/11] Fix Plugin-Path in getTemplatePath() in class.ilTemplate.php --- components/ILIAS/UICore/classes/class.ilTemplate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/ILIAS/UICore/classes/class.ilTemplate.php b/components/ILIAS/UICore/classes/class.ilTemplate.php index d9ce6988057f..6387b9e1efc7 100755 --- a/components/ILIAS/UICore/classes/class.ilTemplate.php +++ b/components/ILIAS/UICore/classes/class.ilTemplate.php @@ -398,7 +398,7 @@ protected function getTemplatePath(string $a_tplname, string $a_in_module = ''): ///////////////////////////////////////////////// /// Split & sort everything /// - if(str_contains($component, 'public/Customizing/global/plugins') || str_contains($template_name, 'public/Customizing/global/components/')) { + if(str_contains($component, 'public/Customizing/global/plugins') || str_contains($template_name, 'public/Customizing/global/plugins')) { $template_type = 3; } elseif(str_starts_with($component, 'components/')) { $template_type = 1;