Apps in Liferay DXP can restrict their data to specific scopes. Scopes provide a context for the application’s data. For example, a site-scoped app can display its data across a single site. For a detailed explanation of scopes, see the user guide article Application Scope. To give your applications scope, you must manually add support for it. This tutorial shows you how.
Scoping Your Entities
In your service layer, your entities must have a companyId
attribute of type
long
to enable scoping by portal instance and a groupId
attribute of type
long
to enable scoping by site. Using
Service Builder
is the simplest way to do this. For instructions on this, see the tutorial
series
Service Builder Persistence
and
Business Logic with Service Builder.
Enabling Scoping
To enable scoping in your app, set the property
"com.liferay.portlet.scopeable=true"
in your portlet class’s @Component
annotation. For example, this property is set to true
in the @Component
annotation of
Web Content Display Portlet’s portlet class:
@Component(
immediate = true,
property = {
...
"com.liferay.portlet.scopeable=true",
...,
},
service = Portlet.class
)
public class JournalContentPortlet extends MVCPortlet {...
That’s it! You can now access your app’s scope in your code. The next section shows you how.
Accessing Your App’s Scope
Users can typically set an app’s scope to a page, a site, or the entire portal. To handle your app’s data, you must access it in its current scope. Liferay DXP gives you techniques to do this. Your app’s scope is available:
-
Via the
scopeGroupId
variable that is injected in your JSPs whenever you use the<liferay-theme:defineObjects />
tag. This variable contains your app’s current scope. For example, Liferay’s Bookmarks app usesscopeGroupId
in itsview.jsp
to retrieve the bookmarks and total number of bookmarks in the current scope:... total = BookmarksEntryServiceUtil.getGroupEntriesCount(scopeGroupId, groupEntriesUserId); bookmarksSearchContainer.setTotal(total); bookmarksSearchContainer.setResults(BookmarksEntryServiceUtil.getGroupEntries(scopeGroupId, groupEntriesUserId, bookmarksSearchContainer.getStart(), bookmarksSearchContainer.getEnd())); ...
-
By calling the
getScopeGroupId()
method on the request’sThemeDisplay
instance. This method returns your app’s current scope. For example, theEditEntryMVCActionCommand
class in Liferay’s Blogs app does this in itssubscribe
andunsubscribe
methods:protected void subscribe(ActionRequest actionRequest) throws Exception { ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute( WebKeys.THEME_DISPLAY); _blogsEntryService.subscribe(themeDisplay.getScopeGroupId()); } protected void unsubscribe(ActionRequest actionRequest) throws Exception { ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute( WebKeys.THEME_DISPLAY); _blogsEntryService.unsubscribe(themeDisplay.getScopeGroupId()); }
If you know your app always needs the portal instance ID, use
themeDisplay.getCompanyId()
. -
By calling the
getScopeGroupId()
method on aServiceContext
object. You can find more information on this, and an example, in the tutorial UnderstandingServiceContext
. If you know your app always needs the portal instance ID, use thegetCompanyId()
method on aServiceContext
object.
Awesome! Now you know how to get your app’s scope. Next, you’ll learn about a special use case: getting the site scope for entities that belong to a different app.
Accessing the Site Scope Across Apps
There may be times when you need to access a different app’s site-scoped data,
even though your app may be scoped to a page or the portal. For example, web
content articles can be created in the page, site, or portal scope.
Structures and Templates
for such articles, however, can only exist in the site scope. If you use the
above techniques to retrieve the app’s current scope, you won’t always get the
site scope required for Structures and Templates. You might get the page or
portal scope instead, if that’s how the user configured your app. What a pickle!
Never fear, the ThemeDisplay
method getSiteGroupId()
is here! This method
always gets the site scope, no matter your app’s current scope. For example,
the Web Content app’s edit_feed.jsp
uses this method to get the site ID needed to retrieve Structures:
...
ddmStructure = DDMStructureLocalServiceUtil.fetchStructure(themeDisplay.getSiteGroupId(),
PortalUtil.getClassNameId(JournalArticle.class), ddmStructureKey, true);
...
Great! Now you know how to scope your apps, access their scope, and even get the site scope of entities that belong to other apps. Now that’s minty-fresh breath!