Skip to content

Commit cd3bd48

Browse files
committed
OXDEV-9553 Handle template module extensions of other modules
1 parent 2d3acb2 commit cd3bd48

7 files changed

Lines changed: 125 additions & 0 deletions

File tree

CHANGELOG-2.x.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
### Added
66
- Improved template rendering performance
77

8+
### Fixed
9+
- Extended the module template using an extension from another module
10+
811
## v2.6.0 - 2025-04-09
912

1013
### Added

services.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,11 @@ services:
279279
arguments:
280280
Symfony\Component\Filesystem\Filesystem: '@oxid_esales.symfony.file_system'
281281

282+
283+
OxidEsales\Twig\Resolver\TemplateChain\TemplateHandler\ChainPrepender:
284+
arguments:
285+
Symfony\Component\Filesystem\Filesystem: '@oxid_esales.symfony.file_system'
286+
282287
OxidEsales\Twig\Resolver\TemplateChain\TemplateHandler\ShopTemplateHandler:
283288

284289
OxidEsales\Twig\Resolver\TemplateChain\TemplateHandler\ModuleTemplateHandler:
@@ -295,6 +300,10 @@ services:
295300

296301
OxidEsales\Twig\Resolver\TemplateChain\TemplateHandler\ModuleExtensions\ModuleTemplateHandler:
297302

303+
OxidEsales\Twig\Resolver\TemplateChain\TemplateHandler\ModuleExtensions\ParentModuleTemplateHandler:
304+
arguments:
305+
- '@OxidEsales\Twig\Resolver\TemplateChain\TemplateHandler\ChainPrepender'
306+
298307
OxidEsales\Twig\Resolver\TemplateChain\TemplateHandler\ModuleExtensions\ModuleExtensionTemplateHandler:
299308

300309
oxid_esales.twig.resolver.template_chain.shop_template_chain_builder:
@@ -313,6 +322,7 @@ services:
313322
- '@OxidEsales\Twig\Resolver\TemplateChain\TemplateHandler\ModuleExtensions\ShopExtensionTemplateHandler'
314323
- '@OxidEsales\Twig\Resolver\TemplateChain\TemplateHandler\ModuleTemplateHandler'
315324
- '@OxidEsales\Twig\Resolver\TemplateChain\TemplateHandler\ModuleExtensions\ModuleTemplateHandler'
325+
- '@OxidEsales\Twig\Resolver\TemplateChain\TemplateHandler\ModuleExtensions\ParentModuleTemplateHandler'
316326
- '@OxidEsales\Twig\Resolver\TemplateChain\TemplateHandler\ModuleExtensions\ModuleExtensionTemplateHandler'
317327

318328
OxidEsales\Twig\Resolver\TemplateChain\TemplateChainBuilderInterface:

src/Resolver/TemplateChain/DataObject/TemplateChain.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ public function append(TemplateTypeInterface $templateType): void
3131
$this->chain[$templateType->getFullyQualifiedName()] = $templateType;
3232
}
3333

34+
public function prepend(TemplateTypeInterface $templateType): void
35+
{
36+
$this->chain = array_merge([$templateType->getFullyQualifiedName() => $templateType], $this->chain);
37+
}
38+
3439
public function remove(TemplateTypeInterface $templateType): void
3540
{
3641
unset($this->chain[$templateType->getFullyQualifiedName()]);

src/Resolver/TemplateChain/TemplateHandler/ChainAppender.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public function addToChain(
3030
if ($this->directoryContainsTemplateFile($directory, $templateType)) {
3131
$templateChain->append($templateType);
3232
}
33+
3334
return $templateChain;
3435
}
3536

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
/**
4+
* Copyright © OXID eSales AG. All rights reserved.
5+
* See LICENSE file for license details.
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace OxidEsales\Twig\Resolver\TemplateChain\TemplateHandler;
11+
12+
use OxidEsales\Twig\Resolver\DataObject\NamespacedDirectory;
13+
use OxidEsales\Twig\Resolver\TemplateChain\DataObject\TemplateChain;
14+
use OxidEsales\Twig\Resolver\TemplateChain\TemplateType\DataObject\TemplateTypeInterface;
15+
use Symfony\Component\Filesystem\Filesystem;
16+
use Symfony\Component\Filesystem\Path;
17+
18+
class ChainPrepender implements ChainAppenderInterface
19+
{
20+
public function __construct(
21+
private Filesystem $filesystem,
22+
) {
23+
}
24+
25+
public function addToChain(
26+
TemplateChain $templateChain,
27+
TemplateTypeInterface $templateType,
28+
NamespacedDirectory $directory
29+
): TemplateChain {
30+
if ($this->directoryContainsTemplateFile($directory, $templateType)) {
31+
$templateChain->prepend($templateType);
32+
}
33+
34+
return $templateChain;
35+
}
36+
37+
private function directoryContainsTemplateFile(
38+
NamespacedDirectory $directory,
39+
TemplateTypeInterface $template
40+
): bool {
41+
return $this->filesystem->exists(
42+
Path::join($directory->getDirectory(), $template->getRelativeFilePath())
43+
);
44+
}
45+
}

src/Resolver/TemplateChain/TemplateHandler/ModuleExtensions/ModuleTemplateHandler.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public function addToChain(
3232
return $templateChain;
3333
}
3434
$extension = $this->getExtension($templateType, $directory);
35+
3536
return $this->chainAppender->addToChain($templateChain, $extension, $directory);
3637
}
3738

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
/**
4+
* Copyright © OXID eSales AG. All rights reserved.
5+
* See LICENSE file for license details.
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace OxidEsales\Twig\Resolver\TemplateChain\TemplateHandler\ModuleExtensions;
11+
12+
use OxidEsales\Twig\Resolver\DataObject\NamespacedDirectory;
13+
use OxidEsales\Twig\Resolver\TemplateChain\DataObject\TemplateChain;
14+
use OxidEsales\Twig\Resolver\TemplateChain\TemplateHandler\ChainAppenderInterface;
15+
use OxidEsales\Twig\Resolver\TemplateChain\TemplateHandler\TemplateTypeCheckerInterface;
16+
use OxidEsales\Twig\Resolver\TemplateChain\TemplateType\DataObject\ModuleExtensionTemplateType;
17+
use OxidEsales\Twig\Resolver\TemplateChain\TemplateType\DataObject\TemplateTypeInterface;
18+
19+
class ParentModuleTemplateHandler implements ChainAppenderInterface, TemplateTypeCheckerInterface
20+
{
21+
public function __construct(
22+
private ChainAppenderInterface $chainAppender,
23+
) {
24+
}
25+
26+
public function addToChain(
27+
TemplateChain $templateChain,
28+
TemplateTypeInterface $templateType,
29+
NamespacedDirectory $directory
30+
): TemplateChain {
31+
$extension = $this->getExtension($templateType, $directory);
32+
if (!$this->canHandle($templateType) && !$this->isChildModule($templateChain, $extension)) {
33+
return $templateChain;
34+
}
35+
36+
return $this->chainAppender->addToChain($templateChain, $extension, $directory);
37+
}
38+
39+
public function canHandle(TemplateTypeInterface $templateType): bool
40+
{
41+
return $templateType->isModuleTemplate();
42+
}
43+
44+
private function isChildModule(TemplateChain $templateChain, ModuleExtensionTemplateType $extension): bool
45+
{
46+
return $templateChain->hasModuleId($extension->getParentNamespace())
47+
&& $extension->getParentNamespace() === $extension->getNamespace();
48+
}
49+
50+
private function getExtension(
51+
TemplateTypeInterface $templateType,
52+
NamespacedDirectory $directory
53+
): ModuleExtensionTemplateType {
54+
return new ModuleExtensionTemplateType(
55+
$templateType->getName(),
56+
$directory->getNamespace(),
57+
$templateType->getNamespace()
58+
);
59+
}
60+
}

0 commit comments

Comments
 (0)