diff --git a/components/ILIAS/UICore/classes/class.ilTemplate.php b/components/ILIAS/UICore/classes/class.ilTemplate.php index c26b2e22f472..6387b9e1efc7 100755 --- a/components/ILIAS/UICore/classes/class.ilTemplate.php +++ b/components/ILIAS/UICore/classes/class.ilTemplate.php @@ -333,80 +333,149 @@ 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 { - $ilias_root = realpath(__DIR__ . '/../../../../') . '/'; + $ilias_root = realpath(__DIR__ . '/../../../../'); + $ui_component_base_path = 'components/ILIAS/UI/src'; - 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); - } + $a_in_module = trim($a_in_module, '/'); + $a_tplname = trim($a_tplname, '/'); - // Special Cases for plugins - if (str_starts_with($a_tplname, 'Customizing/global/plugins/')) { - $a_tplname = "public/$a_tplname"; - } + $template_type = 0; + $template_name = $a_tplname; + $component = $a_in_module; + $ui_component = null; - if (str_contains($a_tplname, 'public/Customizing/global/plugins')) { - $tpl_sub_path = ''; - } - // Proceed with skin lookup - $base_path = $ilias_root; - $default = $base_path . $a_in_module . $tpl_sub_path . $a_tplname; + ///////////////////////////////////////////////// + /// Split & sort everything + /// + 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; + } elseif($component === '' && str_contains($template_name, '/UI/')) { + $template_type = 2; - $skin = $this->getCurrentSkin(); - if ($skin === 'default') { - return $default; - } + $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, '/'); - $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", - ]; + $component = $ui_component_base_path; + } - foreach ($paths as $path) { - if (is_dir($path)) { - $a_in_module = str_replace($base_skin_path . '/', '', $path); + ///////////////////////////////////////////////// + /// 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 . '/'; + } + break; + case 3: // Plugin Templates + if($component === '') { + return '/' . $a_tplname; + } else { + return '/' . $component . '/templates/default/' . $template_name; + } + 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 . '/' . $ui_component . '/' . $template_name)) { + return $custom_skin_UI_path . '/' . $ui_component . '/' . $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; } /**