diff --git a/cms-core/src/main/java/com/gentics/contentnode/object/parttype/handlebars/ChannelCMSResolver.java b/cms-core/src/main/java/com/gentics/contentnode/object/parttype/handlebars/ChannelCMSResolver.java new file mode 100644 index 0000000000..412878d866 --- /dev/null +++ b/cms-core/src/main/java/com/gentics/contentnode/object/parttype/handlebars/ChannelCMSResolver.java @@ -0,0 +1,49 @@ +package com.gentics.contentnode.object.parttype.handlebars; + +import com.gentics.api.lib.exception.NodeException; +import com.gentics.contentnode.object.ContentFile; +import com.gentics.contentnode.object.Folder; +import com.gentics.contentnode.object.Node; +import com.gentics.contentnode.object.Page; +import com.gentics.contentnode.object.Tag; +import com.gentics.contentnode.object.Template; +import com.gentics.contentnode.object.parttype.CMSResolver; + +public class ChannelCMSResolver extends CMSResolver { + + static { + properties.put("channel", new Property() { + public Object get(CMSResolver cmsResolver) { + if (cmsResolver instanceof ChannelCMSResolver channeled) { + return channeled.getChannel(); + } + return null; + } + }); + } + + protected Node channel; + + public ChannelCMSResolver(CMSResolver cmsResolver, Node channel) throws NodeException { + this( + (Page) cmsResolver.get("page"), + (Template) cmsResolver.get("template"), + (Tag) cmsResolver.get("tag"), + (Folder) cmsResolver.get("folder"), + (Node) cmsResolver.get("node"), + (ContentFile) cmsResolver.get("file"), + channel + ); + } + + public ChannelCMSResolver(Page page, Template template, Tag tag, Folder folder, Node node, ContentFile file, Node channel) + throws NodeException { + super(page, template, tag, folder, node, file); + + this.channel = channel; + } + + protected Node getChannel() { + return channel; + } +} diff --git a/cms-core/src/main/java/com/gentics/contentnode/object/parttype/handlebars/HelperSource.java b/cms-core/src/main/java/com/gentics/contentnode/object/parttype/handlebars/HelperSource.java index f6e64e64c7..b5adc56aaa 100644 --- a/cms-core/src/main/java/com/gentics/contentnode/object/parttype/handlebars/HelperSource.java +++ b/cms-core/src/main/java/com/gentics/contentnode/object/parttype/handlebars/HelperSource.java @@ -33,6 +33,7 @@ import com.gentics.contentnode.object.NodeObject; import com.gentics.contentnode.object.Tag; import com.gentics.contentnode.object.Value; +import com.gentics.contentnode.object.parttype.CMSResolver; import com.gentics.contentnode.object.parttype.CmsFormPartType; import com.gentics.contentnode.object.parttype.ImageURLPartType; import com.gentics.contentnode.object.parttype.NodePartType; @@ -196,8 +197,18 @@ public static CharSequence gtx_channel(Object context, Options options) throws I return options.fn(); } + Object cms = options.context.get("cms"); try (final ChannelTrx trx = new ChannelTrx(node)) { + if (cms != null) { + if (cms instanceof ResolvableMapWrapper wrapper) { + options.context.combine("cms", new ResolvableMapWrapper(new ChannelCMSResolver((CMSResolver) wrapper.getWrapped(), node))); + } + } return options.fn(); + } finally { + if (cms != null) { + options.context.combine("cms", cms); + } } } diff --git a/cms-core/src/test/java/com/gentics/contentnode/tests/assertj/AbstractNodeObjectAssert.java b/cms-core/src/test/java/com/gentics/contentnode/tests/assertj/AbstractNodeObjectAssert.java index c6b2c20924..980b036c4e 100644 --- a/cms-core/src/test/java/com/gentics/contentnode/tests/assertj/AbstractNodeObjectAssert.java +++ b/cms-core/src/test/java/com/gentics/contentnode/tests/assertj/AbstractNodeObjectAssert.java @@ -7,6 +7,7 @@ import com.gentics.api.lib.exception.NodeException; import com.gentics.contentnode.events.Dependency; import com.gentics.contentnode.events.DependencyManager; +import com.gentics.contentnode.events.DependencyManager.DependencyImpl; import com.gentics.contentnode.events.Events; import com.gentics.contentnode.object.AbstractContentObject; import com.gentics.contentnode.object.Folder; @@ -79,6 +80,9 @@ public S isDeleted(boolean flag) { */ public S dependsOn(NodeObject sourceObject, String sourceProperty, int channelId) throws NodeException { Dependency dependency = DependencyManager.createDependency(sourceObject, null, sourceProperty, actual, null, Events.UPDATE); + if (channelId != 0) { + ((DependencyImpl) dependency).addChannelId(/*channelId*/ 0); // TODO why? + } assertThat(DependencyManager.getDependenciesForObject(actual, null, null)).as(String.format("Dependencies of %s", descriptionText())) .contains(dependency); return myself; @@ -94,6 +98,9 @@ public S dependsOn(NodeObject sourceObject, String sourceProperty, int channelId */ public S doesNotDependOn(NodeObject sourceObject, String sourceProperty, int channelId) throws NodeException { Dependency dependency = DependencyManager.createDependency(sourceObject, null, sourceProperty, actual, null, Events.UPDATE); + if (channelId != 0) { + ((DependencyImpl) dependency).addChannelId(/*channelId*/ 0); // TODO why? + } assertThat(DependencyManager.getDependenciesForObject(actual, null, null)).as(String.format("Dependencies of %s", descriptionText())) .doesNotContain(dependency); return myself; diff --git a/cms-core/src/test/java/com/gentics/contentnode/tests/parttype/handlebars/AbstractHandlebarsPartTypeRenderingTest.java b/cms-core/src/test/java/com/gentics/contentnode/tests/parttype/handlebars/AbstractHandlebarsPartTypeRenderingTest.java index e8dd254851..758b603cd8 100644 --- a/cms-core/src/test/java/com/gentics/contentnode/tests/parttype/handlebars/AbstractHandlebarsPartTypeRenderingTest.java +++ b/cms-core/src/test/java/com/gentics/contentnode/tests/parttype/handlebars/AbstractHandlebarsPartTypeRenderingTest.java @@ -72,67 +72,67 @@ public abstract class AbstractHandlebarsPartTypeRenderingTest { @ClassRule public static DBTestContext testContext = new DBTestContext(); - final static int creationTimestamp = (int) (System.currentTimeMillis() / 1000) - 2 * 86400; + protected final static int creationTimestamp = (int) (System.currentTimeMillis() / 1000) - 2 * 86400; - final static int editTimestamp = (int) (System.currentTimeMillis() / 1000) - 86400; + protected final static int editTimestamp = (int) (System.currentTimeMillis() / 1000) - 86400; - final static int publishTimestamp = (int) (System.currentTimeMillis() / 1000); + protected final static int publishTimestamp = (int) (System.currentTimeMillis() / 1000); - final static String creationdate = new ContentNodeDate(creationTimestamp).toString(); + protected final static String creationdate = new ContentNodeDate(creationTimestamp).toString(); - final static String editdate = new ContentNodeDate(editTimestamp).toString(); + protected final static String editdate = new ContentNodeDate(editTimestamp).toString(); - final static String publishdate = new ContentNodeDate(publishTimestamp).toString(); + protected final static String publishdate = new ContentNodeDate(publishTimestamp).toString(); - static SystemUser creator; + protected static SystemUser creator; - static SystemUser editor; + protected static SystemUser editor; - static SystemUser publisher; + protected static SystemUser publisher; - static Node node; + protected static Node node; - static Folder rootFolder; + protected static Folder rootFolder; - static Folder homeFolder; + protected static Folder homeFolder; - static Folder testFolder; + protected static Folder testFolder; - static Folder subFolder; + protected static Folder subFolder; - static File testFile; + protected static File testFile; - static ImageFile testImage; + protected static ImageFile testImage; - static Construct handlebarsConstruct; + protected static Construct handlebarsConstruct; - static Template template; + protected static Template template; - static Page targetPage; + protected static Page targetPage; - static Page testPage; + protected static Page testPage; - static Page englishPage; + protected static Page englishPage; - static Construct testConstruct; + protected static Construct testConstruct; - static Construct overviewConstruct; + protected static Construct overviewConstruct; - static Construct datasourceConstruct; + protected static Construct datasourceConstruct; - static Datasource datasource; + protected static Datasource datasource; - static Construct singleSelectConstruct; + protected static Construct singleSelectConstruct; - static Construct multiSelectConstruct; + protected static Construct multiSelectConstruct; - static Construct urlsConstruct; + protected static Construct urlsConstruct; - static Construct checkboxConstruct; + protected static Construct checkboxConstruct; - static Construct nodeConstruct; + protected static Construct nodeConstruct; - static Integer shortTextConstruct; + protected static Integer shortTextConstruct; @BeforeClass public static void setupOnce() throws NodeException { @@ -742,12 +742,23 @@ public static List getGenericTestCases() { ); } + /** * Assert that the rendered testPage has the expected dependencies * @param expectedDependencies expected dependencies * @throws NodeException */ protected void assertDependencies(List> expectedDependencies) throws NodeException { + assertDependencies(expectedDependencies, 0); + } + + /** + * Assert that the rendered testPage has the expected dependencies over the given channel + * @param expectedDependencies expected dependencies + * @param channelId + * @throws NodeException + */ + protected void assertDependencies(List> expectedDependencies, int channelId) throws NodeException { if (CollectionUtils.isNotEmpty(expectedDependencies)) { operate(() -> { for (Pair dep : expectedDependencies) { @@ -758,7 +769,7 @@ protected void assertDependencies(List> expectedDependencie try { Field field = AbstractHandlebarsPartTypeRenderingTest.class.getDeclaredField(fieldName); NodeObject nodeObject = ObjectTransformer.get(NodeObject.class, field.get(null)); - assertThat(testPage).dependsOn(nodeObject, property, 0); + assertThat(testPage).dependsOn(nodeObject, property, channelId); } catch (Exception e) { throw new NodeException(e); } diff --git a/cms-oss-changelog/src/changelog/entries/2026/08/8895.SUP-20052.bugfix b/cms-oss-changelog/src/changelog/entries/2026/08/8895.SUP-20052.bugfix new file mode 100644 index 0000000000..260d9e7a3a --- /dev/null +++ b/cms-oss-changelog/src/changelog/entries/2026/08/8895.SUP-20052.bugfix @@ -0,0 +1 @@ +Handlebars: Now when `gtx_channel` helper is used, the targeted channel data can be accessed via `cms.channel` context item. \ No newline at end of file