Customizing opentaps Applications

From Opentaps Wiki

Jump to: navigation, search

Frequently you will need to customize opentaps applications, such as change the tabs or shortcuts at the top or add new screens. Beginning with opentaps 1.5, you can make these changes without affecting the core opentaps code, making it easier for you to upgrade later when new versions of opentaps becomes available.

opentaps 1.5 supports the following new features to help you customize its applications:

  • The tabs and shortcuts available are now stored in the database, so you can rearrange or change the user interface labels.
  • Other user interface elements are also now defined in configuration database entities.
  • You can "inject" new controller entries into opentaps applications, making it possible to load your screens and actions into an opentaps application.

Contents


General Approach

We would recommend that you keep all of your code in separate modules, or components, similar to the ones found in the `hot-deploy` directories of opentaps 1.4 and earlier or `opentaps` directories of later versions.

Each module can contain its own entity definitions, service definitions, seed and demo data, Java source code, screens, and controller.

If your module needs to modify existing opentaps user interface, you can do so by changing the webapp user interface entities and using controller injection.

Webapp User Interface Database Entities

OpentapsWebApps : defines a webapp (eg: crmsfa, financials), they are listed in the top navigation menu.

  • linkUrl should correspond to the home page of the application (eg: /crmsfa/control/main).
  • shortName, description, applicationName, imageUrl and imageHoverUrl are used in the opentaps main home page (accessed at /opentaps)
  • shortName is also used in top navigation menu as the link label
  • sequenceNum is to specify the display order in the nvaigation menu and the opentaps main home page

OpentapsWebAppTab : a webapp may have multiple tabs (eg: home, orders, accounts .. in crmsfa), they are listed as tabs in the webapp below the top navigation menu.

  • uiLabel is the label of the tab, this can use a localized string when present in one of the localized resources, else will be displayed as is
  • linkUrl can be just the request name in the application, or if isExternal is set to Y it will be used as is (eg: /opentaps, http://www.example.com/somewhere for external urls)
  • sequenceNum is to specify the display order
  • securityModule, securityAction, handlerMethod, handlerParameter see below

OpentapsShortcutGroup : a shortcut group is a small menu in the left column of the page with a title and a list of shortcuts (links), and it belongs to a tab

  • uiLabel is the label of the title of the group, this can use a localized string when present in one of the localized resources, else will be displayed as is. If left blank it defaults to the localized string "Shortcuts"
  • sequenceNum is to specify the display order
  • securityModule, securityAction, handlerMethod, handlerParameter see below

OpentapsShortcut : a link in a shortcut group

  • uiLabel is the label of the shortcut, this can use a localized string when present in one of the localized resources, else will be displayed as is
  • linkUrl can be just the request name in the application, or if isExternal is set to Y it will be used as is (eg: /opentaps, http://www.example.com/somewhere for external urls)
  • sequenceNum is to specify the display order
  • securityModule, securityAction, handlerMethod, handlerParameter see below

String substitution

In OpentapsWebAppTab, OpentapsShortcutGroup and OpentapsShortcut the linkUrl and uiLabel supports automatic substitutions according to the current context so "${partyId}" will be changed into the context value of partyId.

Permission

OpentapsWebAppTab, OpentapsShortcutGroup and OpentapsShortcut all have the securityModule and securityAction fields to specify a basic permission the user must have in order to see the corresponding entity. eg: securityModule="CRMSFA_CONTACTS" securityAction="VIEW" for the contact tab.

Note: this only affects the display on the page, not actual access control (yet).

Handlers

In some cases the basic permission will not be enough, or we need more control over what should actually be displayed or not. For this the handlerMethod and handlerParameter fields can be used.

handlerMethod is java method that takes a context Map (Map<String, Object>) and the entity being checked (OpentapsWebAppTab or OpentapsShortcutGroup or OpentapsShortcut or a generic <T extends EntityInterface>) as parameters, and returns the given entity. This method is called before display and is then free to modify any part of the entity like url, label which will then affect how it is displayed to the current user; and if the entity should not be displayed it can simply return null. handlerParameter can then be used to provide data to a generic handler (like a complex permission to check, a view preference, etc ...)

Example of handlers:

  • org.opentaps.warehouse.security.WarehouseSecurity.checkFacilityPermission : checks the current user permission on the current facility (as selected when entering the warehouse application) against the permission set in handlerParameter
  • org.opentaps.webapp.handlers.CommonHandlers.checkSessionValueAbsent : checks if the user session does not contain the key specified by handlerParameter (or has a null value)
  • org.opentaps.webapp.handlers.CommonHandlers.checkSessionValuePresent : checks if the user session contains the key specified by handlerParameter (has a non null value)
  • org.opentaps.webapp.handlers.CommonHandlers.checkHasNoCart : check the current user session does not have a shopping cart
  • org.opentaps.webapp.handlers.CommonHandlers.checkHasCart : check the current user session has a shopping cart
  • org.opentaps.webapp.handlers.CommonHandlers.checkBoolean : check the current context has a value named by handlerParameter as a boolean True or a string Y/y
  • org.opentaps.webapp.handlers.CommonHandlers.checkViewPreferenceForTab : check the current user view preference in the current tab; handlerParameter should contain 2 colon separated values: prefType:valueToCheck:default (eg: "MY_OR_TEAM_ACCOUNTS:MY_VALUES:TEAM_VALUES" checks if the MY_OR_TEAM_ACCOUNTS view preference is set to MY_VALUES, and use TEAM_VALUES as default if the view preference is empty)

Controller Injection

The ControllerInject entity allows to inject a controller xml file into another. Usually this is done to customize one of the existing application without modifying their controller file directly, and so keeping the customization isolated from the base code.

The injectUrl field specify the url of the controller to inject, and injectIntoUrl the target controller.

For example see the opentaps/controllerinjectex component, activate it by:

  • add <load-component component-location="controllerinjectex"/> in opentaps/component-load.xml

Then either mount is a normal webapp:

  • uncomment the webapp definition in its ofbiz-component.xml
  • access /controllerinjectex/ in a browser

Or use the controller injection by:

  • importing as seed data (in webtools import XML)
    <ControllerInjection injectUrl="component://controllerinjectex/webapp/controllerinjectex/WEB-INF/controller.xml"
                      injectIntoUrl="component://crmsfa/webapp/crmsfa/WEB-INF/controller.xml" sequenceNum="99" />
  • access /crmsfa/control/echo in a browser
  • note: opentaps/controllerinjectex/data/InjectData.xml also contains an example Shortcut which will be inserted in the crmsfa home tab shortcut group for access to this page

Note that with injection its WEB-INF/web.xml is no longer needed.

The result will be the same as the previous and more complex process:

  1. commenting the webapp to customize mount point in its ofbiz-component.xml
  2. creating a webapp in the custom component (WEB-INF/web.xml and mount point in the ofbiz-component.xml, with the same name as the original webapp mount point)
  3. including the controller to customize (eg: component://crmsfa/webapp/crmsfa/WEB-INF/controller.xml) in the custom component controller


© Open Source Strategies, Inc. Development of this documentation site is sponsored by Open Source Strategies, Inc.
Help support opentaps with a subscription to this documentation site.