From 0d0d7ab5bf682031aca92dacd1c2cdc96374a486 Mon Sep 17 00:00:00 2001 From: "M. Drew LaMar" Date: Wed, 7 Oct 2026 16:13:30 -0400 Subject: [PATCH] Component views: look for overrides under the component that owns the view A group's wiki renders com_wiki's views inside a com_groups request, so template overrides were searched for under html/com_groups/pages/ and html/com_wiki/pages/ overrides (e.g. wikimenu.php, submenu.php) were ignored. When no override_path is given, derive the component from the view's base_path instead of the request's option. Co-Authored-By: Claude Opus 5.5 --- core/libraries/Hubzero/Component/View.php | 30 +++++++++++++++++++ .../Hubzero/View/Tests/OverrideRootsTest.php | 24 +++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/core/libraries/Hubzero/Component/View.php b/core/libraries/Hubzero/Component/View.php index 299930f8e57..3f7e3bfbec3 100644 --- a/core/libraries/Hubzero/Component/View.php +++ b/core/libraries/Hubzero/Component/View.php @@ -61,6 +61,17 @@ class View extends AbstractView */ public function __construct($config = array()) { + // Look for overrides under the component that owns the view, not + // the one the request is for: a group's wiki is com_wiki's views + // rendered inside com_groups, and belongs in html/com_wiki/ + if (!array_key_exists('override_path', $config) && !empty($config['base_path'])) + { + if ($component = self::componentFromPath($config['base_path'])) + { + $config['override_path'] = $component; + } + } + parent::__construct($config); // Set a base path for use by the view @@ -76,6 +87,25 @@ public function __construct($config = array()) $this->_basePath = $config['base_path']; } + /** + * The component (com_*) a path lies inside, if any + * + * @param string $path A component path, such as core/components/com_wiki/site + * @return string|null + */ + protected static function componentFromPath($path) + { + foreach (array_reverse(preg_split('#[/\\\\]+#', $path)) as $segment) + { + if (preg_match('/^com_[A-Z0-9_\.-]+$/i', $segment)) + { + return strtolower($segment); + } + } + + return null; + } + /** * Create a component view and return it * diff --git a/core/libraries/Hubzero/View/Tests/OverrideRootsTest.php b/core/libraries/Hubzero/View/Tests/OverrideRootsTest.php index 55a44b848ac..d042a8b7f27 100644 --- a/core/libraries/Hubzero/View/Tests/OverrideRootsTest.php +++ b/core/libraries/Hubzero/View/Tests/OverrideRootsTest.php @@ -140,6 +140,30 @@ public function testDirectlyConstructedComponentViewSeesEveryRoot() ); } + /** + * A component's views rendered inside another component's request (a + * group's wiki: com_wiki views under option=com_groups) are overridden + * from the owning component's directory, not the request's + * + * @return void + */ + public function testComponentViewOverridesFollowItsOwnComponent() + { + $view = new ComponentView([ + 'name' => 'pages', + 'base_path' => $this->env->root . '/components/com_wiki/site', + ]); + + $this->assertSame( + $this->expectedOverrides('com_wiki', 'pages'), + array_slice($this->templatePaths($view), 0, 2) + ); + + $child = $this->templatePaths($view->view('wikimenu')); + + $this->assertSame($this->expectedOverrides('com_wiki', 'pages'), array_slice($child, 0, 2)); + } + /** * @return void */