Breaking Up with Private Pages: It’s Not Us, It’s Them

Liferay has deprecated the Private Pages feature for some time now, although it has been available for all that time. The removal of Private Pages is, however, forthcoming. With the time remaining, let's chart a path showing how you can break up with Private Pages before they can break our hearts...

Time to Break Up with Private Pages

Introduction

For a long time now Private Pages have been deprecated by Liferay...

From a platform perspective, they are really a pain. A site can be made up of two different kinds of pages, public and private, they [potentially] have different host urls, but generally they are confusing to new Liferay adopters (we often hear questions like "What's the difference between a public and a private page?" and "When should I use a public page without guest view permissions vs a private page?", etc.).

For these and other reasons (including complexity in the internal code having to deal with two different types of pages and page sets), we have really wanted to eliminate private pages...

However, for existing sites and implementations that use private pages, well removal of private pages would have been a hard thing to do without. Many arguments against this are available, from "it will take too much time/effort for us to convert private pages to public pages", "we need the separate site for the private pages", "the tools to ensure a site only has private pages are incomplete or lacking", ...

These counter arguments are finally starting to fall away. Liferay is working on an upgrade process to migrate private pages to public pages (still a work in progress, check the conclusion for how you can help). Separate url for the private pages really just means a new site with that friendly url assigned. And the tools necessary for bulk-managing private pages are now available and ready (I'll review these more below).

So now that Liferay sees the remaining arguments have been dealt with, the days for private pages are truly numbered.

Okay, so how do we prepare for this in advance? How do we learn about the new bulk-managing of private pages? All we need to do is keep reading...

Private Site Alternative

Okay, so the first alternative we have to talk about is the private site...

Often what we would do is have a single private site with both public and private pages. The public pages are visible to guests and authenticated users (typically the content was the same for both), and then the private pages were reserved for the authenticated users. With the private pages, a separate domain name could be assigned so authenticated users could access the private pages directly, although with the /web/ and /group/ URL prefixes, there were alternate paths to access the private pages even when they had the same friendly URLs as public pages (i.e. you can have a public page as /welcome and a private page as /welcome).

With this model, site content (web contents, documents, etc.) could be used in both the public and private pages since it was all a single site.

So what are the alternatives here? One is two sites plus an asset library...

In the asset library, we store all of the site content (those web contents, documents, etc) and share it with the sites. This ensures that we can share content between the public and private sites just like the way content could be used in a single site with public and private pages. However, we will not be able to share design artifacts between the two sites (like fragments, templates, etc.).

If our site has both public and private pages, we now want to separate this into two sites, one for the public pages and one to contain the private pages.

A second alternative is a public site with the private pages moved to a child site. As a child site, it would have access to the content and design artifacts of the parent, public site, but the sharing can only be in one direction and the child site, well the pages there need to have no guest view permissions on their pages (more on how to do this below).

Private Page Management

The big advantage for private page management - any page you put in the private pages section, whether you changed permissions or not, guests were unable to view the pages in that section.

Since you didn't have to think about permissions when putting a page into the private pages, often times we didn't, we just created the page and then started editing it.

When private pages are eliminated, as page creators we will be responsible for verifying and managing that there are no guest view permissions on a page.

Verifying Guest View Permissions

In the latest quarterly release (2024.Q3 for me), you can see some of the changes Liferay has made to help confirm private pages. In the screenshot below, we see the Pages control panel; one page is private in that it has no guest view permission, and we can see that Liferay has decorated this page with a special icon:

This visual marker allows us to easily see pages that guests can view vs the private pages they can't.

Bulk Permission Changes

In the previous image, we note that only one page is marked to indicate it is not guest viewable. But what if we needed to change all pages so they were not guest viewable?

In the past we'd have to go to each page separately, open the permissions dialog, remove the guest view permission, save the dialog, close it, then wash/rinse/repeat for every page separately.

Well also in the 2024.Q3 release we now support the changing of page permissions in bulk.

See all of those checkboxes to the left of the page name? Just click all of the ones that you want to change, and in the toolbar click the Permissions action. Then just remove the guest view permissions and save and close the dialog.

Currently you'll be forced to refresh the page, but when you do you'll see that all of the pages that you've selected all have the same indicator icon that we reviewed in the last section.

Unfortunately at the moment the permissions do not cascade, so you can't for example remove guest view from a parent page and expect that it gets removed from all child pages... But at least with the bulk option, we can update all of the child pages easily through the checkbox mechanism covered here.

Default Permissions

A new feature available in later versions of Liferay but hidden behind a Feature Flag is the new settings for Default Permissions.

If you navigate to the Instance Settings control panel, then pick the Feature Flags item, you can find and enable the Default Permissions feature flag:

Once you enable this feature flag, in the Instance settings as well as in the Site Settings there is a new panel for Default Permissions:

With Default Permissions, you can set the default permissions to be used for all new assets (currently only Pages are supported, new asset types will be added on demand, so if you need this be sure to open a support ticket).

When you change the Instance settings, these will be the default permissions for all sites that do not have explicit settings of their own. When you change the Site settings, these will be the settings used for the selected site only, not for other sites.

If you try this on 2024.Q3.12, you'll find that you can't change the guest view permissions. This is fixed by https://liferay.atlassian.net/browse/LPD-35542, but I don't know when it will be released.

Using this mechanism, you can set the Default Permissions for pages so they do not have guest view (basically making them private pages).

You'll still be able to edit the permissions for a given page and add/remove guest view permissions, but the default permissions will ensure that you are only doing this for exceptions instead of having to remember to do them for all pages as you create them.

Call To Action

Rather than the usual Conclusion section that I typically have, this blog is going to close with a Call To Action.

Basically we need to hear from you. We need to know about your use of private pages (whether you use them separately or in addition to public pages). We need to know about the UI enhancements that have been made to make working with and managing pages (just pages now, not public or private pages any longer) to ensure they do or do not have the guest visibility as required.

We need to know about gaps - gaps in our plans for the upgrade process that will remove private pages, gaps in usability, etc.

So this Call To Actions is basically asking you to reach out to us. If you're a DXP client, open a support ticket and start the conversation now (while changes can be made to accommodate your use cases before the change goes live).

If you're a partner, reach out through the typical channels to share your implementation stories with us.

Even if you're using Liferay CE, reach out to us on the Community Slack and let us know what you're thinking.

This change is coming, and it will happen. We're asking for as much feedback as we can get to ensure that when it happens it will be the least impactful way. Now is your opportunity to share that feedback, so I really do encourage you to reach out and make sure that your voices are heard.

Blogs

In some use cases The Private Pages used to serve only the Member of the Site authenticated user that not member of the Site cannot not to see these Private Pages. I hope that Liferay thinked about this case to help customer fill this gap when then change go live.

For that case, though, you should be able to permission the page so only site members can view and no others

Hi David,

It's great to know that Liferay developed replacement strategies for the Private Pages; so far, it has been very difficult to move away from them. Having the bulk permission update and default permissions makes it doable. I have two doubts though, that do not appear not to be covered:

1. The Sites/Asset Library or Subsites strategies seem fine for new websites, but how about migrating the existing portals? Should the content be reorganized manually before the upgrade or will there be any way to define it for the automatic process? How the manual reorganization could be done if there is no UI feature that allows moving portal artifacts (Web Contents, Documents but also Categories) between Sites or Asset Libraries?

2. How about shared Fragments? I remember they are not inherited from the parent site and they also can't be added to the Asset Library. If we end up with two sites (former private and public) the Fragment library must have been managed independently for each one, or stored in Global scope (which I'm trying to avoid).

Thanks,

KG

 

For #1, Liferay is planning on building an upgrade process that is going to do _something_ to existing sites with public and private pages. They have some ideas but are asking for input (hence the Call To Action section in this post). You are going to know your sites better than Liferay does; if you submit details about how you would like to see the change happen, you'll be providing that insight to the team and they can take that into account as they work on the upgrade process that will automate this.

For #2, I'm not sure if they've considered the fragments/templates/etc, but I'll be sure to bring it to their attention! As should you, of course, using the mechanisms in the Call To Action section...

Thanks for your answer, I'll try describe what we have and what we need, and open a Support Ticket. I feel though, that the deployment and sharing Fragments (the overall management) is still an issue in Liferay.

Thanks for the insights David.

Just shared a feedback through customer support. Hope it finds a way to product managers.

We are currently mostly still using private pages because in the distant past it was required. We are willing to migrate, but I'm looking for a save way to move pages from private to public. The basic idea was to use the groovy scripting option and basicly:

- Use `LayoutLocalServiceUtil#getLayouts` to fetch all affected layouts - Use `Layout#setPrivateLayout` method and set it to `false` - Use `LayoutLocalServiceUtil#updateLayout` to save that layout

It turns out, that this is too naive (I tested this with a fresh 7.4.3.129-ga129 installation):

Friendly URLs must be manually updated if there are private and public pages with the same friendly URL as you violate a unique index if you don't change it. Additionally the layoutId has to be updated because liferay allows you to generate two layouts with same layoutId, if they just differ in their private page state.

That above is still not enough, as it seems updating the `friendlyUrl` in the Layout is not enough. The URLs were not updated, most probably I'd have to also update/remove/recreate the FriendlyURLEntry entries for these pages using FriendlyURLEntryLocalServiceUtil. At this point I learned, that there are seperate ClassNameIds for private and public pages (the class names I saw where com.liferay.portal.kernel.model.Layout-true and com.liferay.portal.kernel.model.Layout-false).

TL;DR at this point is, that I have a bad feeling moving pages, because I lack a method, that lets me change the savely change the public/private state of a Layout.

I would suggest continuing to use private pages and ditch the groovy script idea.

Liferay is going to be creating an upgrade process which will do something with those private pages (I don't think it has been determined what that something is just yet), so you shouldn't need to manually muck with groovy scripts to affect the same.

Getting your feedback on expectations (i.e. should they be a separate site or same site, child site or sibling site, etc) will help them figure out what the upgrade process should do.

More importantly, if you do this using groovy, the responsibility and risk is all on you. If you wait for Liferay's upgrade process to do it, the responsibility and risk will be on them.

But getting your expectations known and whatever limiting factors or restrictions you are facing, those are the details the Liferay team needs.

Let me give you some more insight:

We currently have a public site and a private site. The public site mirrors parts of the private site to make contents accessible to the public. The contents that is accessible to the public uses the same friendly url (modulo the group/site prefix) as the private contents.

My preliminary vision for our process is this: We identifiy all pages that share the same friendly URL. For these pages we ensure, that the public layout holds the same content as the private page (hiding the content for the internal users in JournalArticles with the appropriate permissions). These private layouts will not be transitioned. All private child layouts shall be relocated to the public layout, that share the same friendly URL as the private layout. The then not relocated layouts are the ones, that will be dropped.

We need some more work as we have contents on the public pages, that shall only be shown to guest users, so we also need to switch from "Site-Members inherit the Guest-Role" to "Guest-Role is only assigned to guest users". That will also require a massive reassignment of rights, as have several JournalArticle/Layouts/Files/Folders that are accessible to Site members because these assests are accessible to Guest users.

The changes that will be necessary will touch literally thousands of objects (layouts, journal article, files, folders, ...). Of course I can get me several colleges and we can click for a few hours. On the other hand we have 2025, things like this should be scripted, so that I can run this complex change on a copy of the production system, check it, fix issues, reiterate and then do the change in production in one compact operation. ​​

Hi David,

I think there should be something like Default Permissions for Document & Media uploads.

Let me explain, currently when you upload a file there are three options in Permissions:

- Anyone (Guest role) - Site Member -- This is the default value in our Private sites - Owner

Once you remove the Private Page from Private sites, how do you setup the default value for permissions? will it be "Site Member" in all cases (public and private)?

I think the administrator should be able to setup what is the default value for each site in order to avoid security risks in Private sites.

Thanks

Please open a support ticket, including all of this information. This will turn into a feature request for the team to prioritize and implement when they can.

I hope I'm still in time to add another perspective.

In my case, I find the current way of managing private and public pages to be more secure. When managing a site, you can quickly see which pages are private and which are public at a glance. The different URLs (web, group) also provide a quick way to check and ensure that private content is not mistakenly made public.

Of course, permissions can control the privacy of a page, but verifying them requires a deeper knowledge to manage them and it could be easier to overlook mistakes or misassign permissions.  In our case, if a private page were to become publicly visible by mistake, it could have significant consequences.

Which is why we've introduced the new UI changes to show at a glance whether a page is "private" or not. We absolutely want you to have the same confidence in page visibility that you have today, we're just trying to do it with a "slimmed down" Liferay that doesn't need complex logic for managing two different page groups...

Have you tried the new features? Do you think they'll provide the same level of confidence? Or if you feel something is missing, what would that be?