Apps can restrict their data to specific scopes. Scopes provide a context for the application’s data.
Global: One data set throughout a portal instance.
Site: Separate data sets for each Site it’s added to.
Page: Separate data sets for each page it’s added to.
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 Widget 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. The
Service Builder Persistence
and
Business Logic with Service Builder
tutorials show you how.
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, the
Web Content Display Portlet’s portlet class
sets this component property:
@Component(
immediate = true,
property = {
...
"com.liferay.portlet.scopeable=true",
...,
},
service = Portlet.class
)
public class JournalContentPortlet extends MVCPortlet {...
That’s it! Next, you’ll access your app’s scope in your code.
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. Your app’s scope is available in these ways:
-
Via the
scopeGroupId
variable that is injected in your JSPs that use the<liferay-theme:defineObjects />
tag. This variable contains your app’s current scope. For example, the Liferay Bookmarks app’sview.jsp
uses itsscopeGroupId
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, the Liferay Blogs app’sEditEntryMVCActionCommand
class 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. The tutorial UnderstandingServiceContext
provides an example and details. If you know your app always needs the portal instance ID, use theServiceContext
object’sgetCompanyId()
method.
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 must access a different app’s Site-scoped data from
your app that is 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, exist only in the Site scope. The above techniques
return the app’s scope, which might not be the Site scope. 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.