Forums de discussion

Set type page programmatically

Jacopo Bartolini, modifié il y a 7 années.

Set type page programmatically

Junior Member Publications: 28 Date d'inscription: 19/01/17 Publications récentes
Hi,
I do not even know if this is possible, so also answers like "It's not possible because..." are gladly welcomed. I would like to set programmatically the type of some pages to be "Link to a page of this site". My pages are organized in a tree-like structure, and I would like to set pages which are on root level, but which are not the first page, to automatically redirect to their first child. Is it possible? Thanks in advance.
thumbnail
Olaf Kock, modifié il y a 7 années.

RE: Set type page programmatically

Liferay Legend Publications: 6403 Date d'inscription: 23/09/08 Publications récentes
Jacopo Bartolini:
I do not even know if this is possible, so also answers like "It's not possible because..." are gladly welcomed. I would like to set programmatically the type of some pages to be "Link to a page of this site". My pages are organized in a tree-like structure, and I would like to set pages which are on root level, but which are not the first page, to automatically redirect to their first child. Is it possible?


It certainly is possible. What you don't say is where/when you're expecting to do this. Whenever you create a new top level page? Or retrofit it into the current page structure?

All of Liferay's API is open to you, this involves a bit of scripting/programming. A page in the API is called layout - If you know your way around the API, look for LayoutLocalService for the version that doesn't check permissions, or LayoutService for the one that does. Enumerate the pages of a site and change their type and metadata.

If you want to do this whenever a top level page is created, you'll most likely write a ServiceWrapper.
Jacopo Bartolini, modifié il y a 7 années.

RE: Set type page programmatically

Junior Member Publications: 28 Date d'inscription: 19/01/17 Publications récentes
Well, thanks for this answer too, really appreciate it. I would like this behaviour to apply to all new top level pages, if possible. So yes, I think I should write a ServiceWrapper. Think I can handle this, now that someone pointed me in the right direction. Thanks a lot, really.
thumbnail
Olaf Kock, modifié il y a 7 années.

RE: Set type page programmatically

Liferay Legend Publications: 6403 Date d'inscription: 23/09/08 Publications récentes
I've had some fun playing around. No guarantee that this is complete or elegant, but it withheld the first UI-level clicking:

Assuming you're on Liferay 7 or DXP

@Component(
		immediate = true, 
		property = {}, 
		service = ServiceWrapper.class
		)
public class HierarchyEnforcerWrapper extends LayoutLocalServiceWrapper {

	public HierarchyEnforcerWrapper() {
		super(null);
	}

	@Override
	public Layout addLayout(long userId, long groupId, boolean privateLayout, long parentLayoutId,
			Map<locale, string> nameMap, Map<locale, string> titleMap, Map<locale, string> descriptionMap,
			Map<locale, string> keywordsMap, Map<locale, string> robotsMap, String type, String typeSettings,
			boolean hidden, Map<locale, string> friendlyURLMap, ServiceContext serviceContext) throws PortalException {
		if (parentLayoutId == 0 &amp;&amp; !hidden &amp;&amp; "portlet".equals(type)) {
			// We won't create a top level "empty" page, rather create a "link to page" with the same name, 
			// linking to its first child page.
			Layout secondLevel = super.addLayout(userId, groupId, privateLayout, 0, nameMap,
					titleMap, descriptionMap, keywordsMap, robotsMap, type, typeSettings, hidden, friendlyURLMap,
					serviceContext);
			String topLevelTypeSettings = "linkToLayoutId=" + secondLevel.getLayoutId() + "\n" +
					"groupId=" + secondLevel.getGroupId() + "\n" + 
					"privateLayout=" + privateLayout;
			Layout topLevel = super.addLayout(userId, groupId, privateLayout, parentLayoutId, nameMap, titleMap,
					descriptionMap, keywordsMap, robotsMap, LayoutConstants.TYPE_LINK_TO_LAYOUT, topLevelTypeSettings, hidden,
					friendlyURLMap, serviceContext);
			secondLevel.setParentLayoutId(topLevel.getLayoutId());
			updateLayout(secondLevel);
			return topLevel;
		} else {
			return super.addLayout(userId, groupId, privateLayout, parentLayoutId, nameMap, titleMap, descriptionMap,
					keywordsMap, robotsMap, type, typeSettings, hidden, friendlyURLMap, serviceContext);
		}
	}
}</locale,></locale,></locale,></locale,></locale,></locale,>
Lucy W, modifié il y a 6 années.

RE: Set type page programmatically

Junior Member Publications: 50 Date d'inscription: 21/09/16 Publications récentes
How would we do this on a per page basis? For instance to be able to set a first-child redirect on some parent pages but not others, and have the flexibility to change or add to additional pages in the future.
thumbnail
Olaf Kock, modifié il y a 6 années.

RE: Set type page programmatically

Liferay Legend Publications: 6403 Date d'inscription: 23/09/08 Publications récentes
Lucy W:
How would we do this on a per page basis? For instance to be able to set a first-child redirect on some parent pages but not others, and have the flexibility to change or add to additional pages in the future.


As far as I remember the code above, this will provide the default, but can be changed later on (just change the page type). Naturally there will be more effort involved if you need to adopt the user interface to make the administrator select which kind of page they want to create.

You might be lucky with just letting them know what kind of structure you expect them to create. After all, there's not a ridiculously high number of top level pages that one can create in a site. I'd question if this is something that you should automate at all. Yes, it's work to create two pages manually, but so is documenting that Liferay automatically creates two pages when the administrator only expects a single page to be created, cover all the exceptions etc.
thumbnail
Christoph Rabel, modifié il y a 6 années.

RE: Set type page programmatically

Liferay Legend Publications: 1554 Date d'inscription: 24/09/09 Publications récentes
Not sure if it is possible at all, but maybe you could create your own layout-type-controller:
https://github.com/liferay/liferay-portal/tree/master/modules/apps/web-experience/layout/layout-type-controller

To give it a test you could copy the code, rename the class and change the package names and try to get it working.