Repository: gentics/cms-oss
Pull request #506: SUP-17776 Change startpage default tagmap entry to text
Author: login: yrucrem
Created: 2025-02-27T16:18:06Z | Merged: 2025-03-12T11:16:22Z



Diff:
diff --git a/cms-core/src/main/java/com/gentics/contentnode/object/parttype/UrlPartType.java b/cms-core/src/main/java/com/gentics/contentnode/object/parttype/UrlPartType.java
index 33174f2aa..e3addfa02 100644
--- a/cms-core/src/main/java/com/gentics/contentnode/object/parttype/UrlPartType.java
+++ b/cms-core/src/main/java/com/gentics/contentnode/object/parttype/UrlPartType.java
@@ -187,7 +187,13 @@ public Object get(String key) {
 				logger.error("Error while getting node for " + this, e);
 			}
 		}
-
+		if ("url".equals(key)) {
+			try {
+				return render(new RenderResult(), key);
+			} catch (NodeException e) {
+				logger.error("Error while resolving url of " + this, e);
+			}
+		}
 		// TODO: how to handle 'encoded' and obj-props for file?
 
 		// compatiblity syntax hack
diff --git a/cms-core/src/main/java/com/gentics/contentnode/rest/resource/impl/ContentRepositoryResourceImpl.java b/cms-core/src/main/java/com/gentics/contentnode/rest/resource/impl/ContentRepositoryResourceImpl.java
index 2c551d11d..36afa942d 100644
--- a/cms-core/src/main/java/com/gentics/contentnode/rest/resource/impl/ContentRepositoryResourceImpl.java
+++ b/cms-core/src/main/java/com/gentics/contentnode/rest/resource/impl/ContentRepositoryResourceImpl.java
@@ -610,6 +610,7 @@ protected void addDefaultTagmapEntries(ContentRepository cr) throws NodeExceptio
 			cr.addEntry("folder.description", "description", Folder.TYPE_FOLDER, 0, AttributeType.text, false, true, false, false, false, false);
 			cr.addEntry("folder.pub_dir", "pub_dir", Folder.TYPE_FOLDER, 0, AttributeType.text, false, true, true, false, false, false);
 			cr.addEntry("object.startpage.parts.url.target", "startpage", Folder.TYPE_FOLDER, Page.TYPE_PAGE, AttributeType.link, false, false, false, false, false, false);
+			cr.addEntry("object.startpage.parts.url.url", "startpageurl", Folder.TYPE_FOLDER, 0, AttributeType.text, false, false, false, false, false, false);
 			cr.addEntry("object.navhidden", "navhidden", Folder.TYPE_FOLDER, 0, AttributeType.bool, false, false, false, false, false, false);
 			cr.addEntry("object.navsortorder", "navsortorder", Folder.TYPE_FOLDER, 0, AttributeType.integer, false, false, false, false, false, false);
 			cr.addEntry("folder.creator", "creator", Folder.TYPE_FOLDER, 0, AttributeType.text, false, false, false, false, false, false);
diff --git a/cms-core/src/test/java/com/gentics/contentnode/tests/publish/CRComparator.java b/cms-core/src/test/java/com/gentics/contentnode/tests/publish/CRComparator.java
index c4565891f..393c21f61 100644
--- a/cms-core/src/test/java/com/gentics/contentnode/tests/publish/CRComparator.java
+++ b/cms-core/src/test/java/com/gentics/contentnode/tests/publish/CRComparator.java
@@ -167,7 +167,7 @@ private void doContentattributeCompareStep2(ArrayList diffAttributes) throws Dat
 			String attributeName = ((String) it.next());
 
 			logger.info("CRComparator - Comparing: " + attributeName);
-			if (attributeName.equalsIgnoreCase("startpage")) {
+			if (attributeName.equalsIgnoreCase("startpage") || attributeName.equalsIgnoreCase("startpageurl")) {
 				// TODO handle this diff
 				logger.info("CRComparator - Skipping startpage");
 				continue;
diff --git a/cms-core/src/test/java/com/gentics/contentnode/tests/publish/mesh/MeshPublishTest.java b/cms-core/src/test/java/com/gentics/contentnode/tests/publish/mesh/MeshPublishTest.java
index 47c9b40f4..893073d13 100644
--- a/cms-core/src/test/java/com/gentics/contentnode/tests/publish/mesh/MeshPublishTest.java
+++ b/cms-core/src/test/java/com/gentics/contentnode/tests/publish/mesh/MeshPublishTest.java
@@ -73,6 +73,7 @@
 import com.gentics.contentnode.testutils.mesh.MeshTestRule;
 import com.gentics.mesh.core.rest.node.field.BinaryField;
 import com.gentics.mesh.core.rest.node.field.NodeField;
+import com.gentics.mesh.core.rest.node.field.StringField;
 import com.gentics.mesh.core.rest.node.field.impl.StringFieldImpl;
 import com.gentics.mesh.core.rest.project.ProjectResponse;
 import com.gentics.mesh.core.rest.schema.impl.SchemaCreateRequest;
@@ -217,13 +218,13 @@ public void testEmptyPublish() throws Exception {
 	 */
 	@Test
 	public void testPublishFolder() throws Exception {
-		Trx.operate(() -> {
+		operate(() -> {
 			PublishQueue.undirtObjects(new int[] {node.getId()}, Folder.TYPE_FOLDER, null, 0, 0);
 			PublishQueue.undirtObjects(new int[] {node.getId()}, File.TYPE_FILE, null, 0, 0);
 			PublishQueue.undirtObjects(new int[] {node.getId()}, Page.TYPE_PAGE, null, 0, 0);
 		});
 
-		Folder folder = Trx.supply(() -> {
+		Folder folder = supply(() -> {
 			return create(Folder.class, f -> {
 				f.setMotherId(node.getFolder().getId());
 				f.setName("Testfolder");
@@ -626,6 +627,49 @@ public void testPublishFolderWithStartpage() throws Exception {
 				assertThat(startPageField).as("Startpage").isNotNull();
 				assertThat(startPageField.getUuid()).as("Startpage").isEqualTo(MeshPublisher.getMeshUuid(page));
 			});
+			assertObject("Check folder startpage URL", mesh.client(), MESH_PROJECT_NAME, folder, true, meshFolder -> {
+				StringField startPageField = meshFolder.getFields().getStringField("startpageurl");
+				assertThat(startPageField).as("Startpage").isNotNull();
+				assertThat(startPageField.getString()).as("Startpage value").isEqualTo(String.format("{{mesh.link(%s, %s, %s)}}", MeshPublisher.getMeshUuid(page), MeshPublisher.getMeshLanguage(page), node.getName()));
+			});
+		});
+	}
+
+	/**
+	 * Test publishing a folder with an external startpage into an empty Mesh CR instance
+	 * @throws Exception
+	 */
+	@Test
+	public void testPublishFolderWithExternalStartpage() throws Exception {
+		operate(() -> {
+			PublishQueue.undirtObjects(new int[] {node.getId()}, Folder.TYPE_FOLDER, null, 0, 0);
+			PublishQueue.undirtObjects(new int[] {node.getId()}, File.TYPE_FILE, null, 0, 0);
+			PublishQueue.undirtObjects(new int[] {node.getId()}, Page.TYPE_PAGE, null, 0, 0);
+		});
+
+		Folder folder = supply(() -> {
+			return create(Folder.class, f -> {
+				f.setMotherId(node.getFolder().getId());
+				f.setName("Testfolder");
+				getPartType(PageURLPartType.class, f.getObjectTag("startpage"), "url").setExternalTarget("https://gentics.com");
+			});
+		});
+
+		try (Trx trx = new Trx()) {
+			context.publish(false);
+			trx.success();
+		}
+
+		operate(() -> {
+			ProjectResponse project = mesh.client().findProjectByName(MESH_PROJECT_NAME).blockingGet();
+			assertFolders(mesh.client(), MESH_PROJECT_NAME, project.getRootNode().getUuid(), supply(() -> node.getFolder()));
+			assertFolders(mesh.client(), MESH_PROJECT_NAME, MeshPublisher.getMeshUuid(node.getFolder()), folder);
+
+			assertObject("Check folder startpage URL", mesh.client(), MESH_PROJECT_NAME, folder, true, meshFolder -> {
+				StringField startPageField = meshFolder.getFields().getStringField("startpageurl");
+				assertThat(startPageField).as("Startpage").isNotNull();
+				assertThat(startPageField.getString()).as("Startpage value").isEqualTo("https://gentics.com");
+			});
 		});
 	}
 
diff --git a/cms-oss-changelog/src/changelog/entries/2025/02/8177.SUP-17776.enhancement b/cms-oss-changelog/src/changelog/entries/2025/02/8177.SUP-17776.enhancement
new file mode 100644
index 000000000..312bdc365
--- /dev/null
+++ b/cms-oss-changelog/src/changelog/entries/2025/02/8177.SUP-17776.enhancement
@@ -0,0 +1 @@
+Now a plain text property @startpageurl@ is added to the list of folder fields of Mesh Content Repository, allowing using the external URL as a startpage, or just simplifying the start page resolving in the case of single language setup.


Reviews:
user: login: plyhun
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-03T12:04:36Z
user: login: plyhun
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-04T12:33:17Z

Review comments:
diff_hunk: @@ -629,6 +630,56 @@ public void testPublishFolderWithStartpage() throws Exception {
 		});
 	}
 
+	/**
+	 * Test publishing a folder with a startpage into an empty Mesh CR instance
+	 * @throws Exception
+	 */
+	@Test
+	public void testPublishFolderWithExternalStartpage() throws Exception {
+		Trx.operate(() -> {
+			PublishQueue.undirtObjects(new int[] {node.getId()}, Folder.TYPE_FOLDER, null, 0, 0);
+			PublishQueue.undirtObjects(new int[] {node.getId()}, File.TYPE_FILE, null, 0, 0);
+			PublishQueue.undirtObjects(new int[] {node.getId()}, Page.TYPE_PAGE, null, 0, 0);
+		});
+
+		Folder folder = Trx.supply(() -> {
+			return create(Folder.class, f -> {
+				f.setMotherId(node.getFolder().getId());
+				f.setName("Testfolder");
+			});
+		});
+
+		Page page = Trx.supply(() -> {
+			return create(Page.class, p -> {
+				p.setTemplateId(template.getId());
+				p.setFolderId(folder.getId());
+				p.setName("Page");
+			});
+		});
+
+		Trx.operate(() -> update(folder, f -> {
+			getPartType(PageURLPartType.class, f.getObjectTag("startpage"), "url").setExternalTarget("https://gentics.com");
+		}));
+		Trx.operate(t -> t.getObject(page, true).publish());
+
+		try (Trx trx = new Trx()) {
+			context.publish(false);
+			trx.success();
+		}
+
+		operate(() -> {
+			ProjectResponse project = mesh.client().findProjectByName(MESH_PROJECT_NAME).blockingGet();
+			assertFolders(mesh.client(), MESH_PROJECT_NAME, project.getRootNode().getUuid(), Trx.supply(() -> node.getFolder()));
+			assertFolders(mesh.client(), MESH_PROJECT_NAME, MeshPublisher.getMeshUuid(node.getFolder()), folder);
+			assertPages(mesh.client(), MESH_PROJECT_NAME, MeshPublisher.getMeshUuid(folder), MeshPublisher.getMeshLanguage(page), page);
+
+			assertObject("Check folder startpage URL", mesh.client(), MESH_PROJECT_NAME, folder, true, meshFolder -> {
+				StringField startPageField = meshFolder.getFields().getStringField("startpageurl");
+				assertThat(startPageField).as("Startpage").isNotNull().matches(field -> "https://gentics.com".equals(field.getString()));
path: cms-core/src/test/java/com/gentics/contentnode/tests/publish/mesh/MeshPublishTest.java
user: login: plyhun
body: Fails -- no external startpage saved.
created_at: 2025-03-03T12:04:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -187,7 +187,13 @@ public Object get(String key) {
 				logger.error("Error while getting node for " + this, e);
 			}
 		}
-
+		if ("url".equals(key)) {
+			try {
+				return render(new RenderResult(), key);
path: cms-core/src/main/java/com/gentics/contentnode/object/parttype/UrlPartType.java
user: login: plyhun
body: Those parameters do not actually matter.
created_at: 2025-03-04T12:33:17Z
author_association: CONTRIBUTOR

PR comments:
user: login: CLAassistant
created_at: 2025-03-03T11:59:21Z
body: [![CLA assistant check](https://cla-assistant.io/pull/badge/not_signed)](https://cla-assistant.io/gentics/cms-oss?pullRequest=506) <br/>Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our [Contributor License Agreement](https://cla-assistant.io/gentics/cms-oss?pullRequest=506) before we can accept your contribution.<br/>**4** out of **5** committers have signed the CLA.<br/><br/>:white_check_mark: plyhun<br/>:white_check_mark: yrucrem<br/>:white_check_mark: npomaroli<br/>:white_check_mark: deckdom<br/>:x: GenticsDev<br/><sub>You have signed the CLA already but the status is still pending? Let us [recheck](https://cla-assistant.io/check/gentics/cms-oss?pullRequest=506) it.</sub>
author_association: NONE
user: login: CLAassistant
created_at: 2025-03-03T11:59:21Z
body: [![CLA assistant check](https://cla-assistant.io/pull/badge/not_signed)](https://cla-assistant.io/gentics/cms-oss?pullRequest=506) <br/>Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our [Contributor License Agreement](https://cla-assistant.io/gentics/cms-oss?pullRequest=506) before we can accept your contribution.<br/>**4** out of **5** committers have signed the CLA.<br/><br/>:white_check_mark: plyhun<br/>:white_check_mark: yrucrem<br/>:white_check_mark: deckdom<br/>:white_check_mark: npomaroli<br/>:x: GenticsDev<br/><sub>You have signed the CLA already but the status is still pending? Let us [recheck](https://cla-assistant.io/check/gentics/cms-oss?pullRequest=506) it.</sub>
author_association: NONE