Studio Developer Manual / Version 2406.0
Table Of ContentsSection Section 9.2, “Adding Entries to the Apps Menu” covers how to add App Menu entries from the perspective of the Content App and the Workflow App. This section covers all relevant aspects of app manifests and how they are used for custom Studio Apps.
App manifests are the basic mechanism to loosely couple the different Studio Apps.
All apps that are integrated into the workspace as described above in Section Section 9.36.2, “Workspace Integration”
know each other: Each app is equipped with a manifest that holds information about the app and each app
loads the manifests of all other apps to use that information. This takes place during
the above-mentioned app bootstrap method studioAppsContext._.initAppServices()
.
One of the immediate consequences of having an app being equipped with a manifest is that the app automatically appears the the Apps Menu of the built-in CoreMedia apps as shown in the following figure for the My-Edited-Contents App entries.
Currently, CoreMedia does not provide a reusable apps menu component
for a custom app that is not implemented with ExtJs. However, the studioAppsContext
utility already
provides the model for it. Calling studioAppsContext._.observeRunAppSections()
returns so-called
RunAppEntries / RunAppSections
that can be used to build a custom apps menu from scratch.
Each entry / section has a run()
method which automatically starts the corresponding
app if it is not already running and focuses an app (brings it into the foreground) if it is already running.
For ReactJs, the demo My-Edited-Contents App already contains an apps menu implementation
that looks similar to the one from the built-in CoreMedia apps.
For app manifests, CoreMedia follows the Web standard
Web App Manifests.
The manifest of a custom app can include all the properties from the standard, but in addition,
some CoreMedia-specific properties can be included. The latter
are prefixed with cm
.
Among the various properties supported by the standard, the following basic ones are mandatory for CoreMedia Studio apps:
"icons": [ { "src": "icons/edited-contents-24.svg", "type": "image/svg", "sizes": "24x24" }, ... ]
- cmKey: The unique app key.
- name: The app name.
- short_name: The app short name.
- icons: App icons in different sizes (24x24, 192x192, 512x512) where each icon is configured in terms of an object with properties "src", "type" (the MIME type, e.g. "image/png" or "image/svg") and "sizes".
In addition to these basic manifest properties, there are some advanced properties that are of particular interest for CoreMedia Studio apps.
- categories: This is a string list of categories of the app. If none are given, the app's
short name is considered as its sole category. The first category of this list is important for the result
of
studioAppsContext._.observeRunAppSections()
for the Apps Menu: The first category of an app makes up its ownRunAppSection
. These are e.g. "Content", Workflows", "Campaigns" and "My Edited Contents" in Figure Figure 9.29, “Apps Menu With My-Edited-Contents App”. - shortcuts: For an app, so-called shortcuts can be specified. These are sub-paths/URLs
into the app. In the Apps Menu, these shortcuts are by default displayed as
sub-entries (of type
RunAppEntry
) of the app'sRunAppSection
. For example, the "New v2" shortcut of the "My Edited Contents" section is defined as follows:"shortcuts": [ { "cmKey": "mec-v2", "name": "New v2", "url": "under-construction" } ],
For this to work, the app needs to offer a
RouterService
(for more details, see Section 9.36.5.2, “Built-In Services And Utilities”). This service is called viaRouterService#setPath()
once the shortcut entry is clicked. The service has to take care of setting the specified URL of the shortcut. For example, in the My-Edited-Contents App, a ReactJsHashRouter
is in place and the service's implementation uses theuseNavigate()
hook to set the url.It is also possible for a shortcut to appear outside its app's
RunAppSection
. For a shortcut, a customcmCategory
can be set. If this category matches any app'sRunAppSection
, the shortcut is placed there as a sub-RunAppEntry
. If no such section exists, the shortcut makes up its own top-level section. For example, the "Dashboard" section in Figure Figure Figure 9.29, “Apps Menu With My-Edited-Contents App” is actually a shortcut of the Content App. But the app's category is "Content" while the shortcut'scmCategory
is "Dashboard". - cmServiceShortcuts: While the ordinary shortcuts from above specify a sub-path/URL
into the app, so-called service shortcuts are shortcuts where an app's service
is called when the shortcut is run / clicked. For more details about services, see Section
Section 9.36.5, “App Services” below.
For now, it is sufficient to say that a service shortcut specification complies to the
ServiceShortcut
type where the service to call is given via the propertycmService
of typeServiceMethodDescriptorWithProps
. But it is also possible to leave out the property. In that case, an under-the-hood default service is used, and it is sufficient to register a ShortcutRunner for the shortcut'scmKey
. For example, for the My-Edited-Contents App, this service shortcut is specified in the manifest."cmServiceShortcuts": [ { "cmKey": "mec-info", "name": "Info", } ],
For this to work without any service specification, the app also registers a runner for this shortcut.
useEffect(() => { studioAppsContext._.getShortcutRunnerRegistry() .registerShortcutRunner( "mec-info", () => alert("This is the My Edited Contents app!") ); }, []);
- cmServices: These are the "guaranteed" services an app offers (actually, so called
service descriptors are used here, see Section Section 9.36.5.1, “Service Agent API” below.).
An app might or might not offer additional services, but these services that are specified in the manifest are required to
be offered by the app. So the developer must make sure to register these services early on
in the app's lifecycle. One important thing that the Studio Apps framework
offers is that for these services, a service runner is automatically set up. This means that
although an app is not yet running, other apps already know the app's services with state "runnable".
If such a service is requested via
ServiceHandler#fetch()
and the app is not yet running, it is automatically opened in a browser tab. For more details on services and service runners, see Section Section 9.36.5, “App Services”.For example, the My-Edited-Contents App specifies one service in its manifest:
"cmServices": [ { "name": "myEditedContentsService" } ],
The required service is then registered early on in the app's lifecycle right after the app's basic app initialization.
studioAppsContext._.initAppServices().then(() => { myEditedContentsServiceDesc = createMyEditedContentsServiceDescriptor({ providingApp: studioAppsContext._.getMyAppDescriptor().cmKey }); const myEditedContentsService = new MyEditedContentsServiceImpl(setSortModel); getServiceAgent().registerService(myEditedContentsService, myEditedContentsServiceDesc); });
The code fragment shows an important aspect. All of the
cmServices
from the manifest are required to includeWithProvidingApp
in their descriptor properties. Upon registration, it is mandatory to set the propertyWithProvidingApp#providingApp
. The result fromstudioAppsContext._.getMyAppDescriptor().cmKey
is identical with the value ofcmKey
from the manifest but it is only available afterstudioAppsContext._.initAppServices()
.