Using Angular Modules in the Central Package (CP) Best Practices

Created by

Paul Ojennus, Whitworth University


This document describes best practices for creating custom Angular modules in Primo’s central package.

System components

Package Manager/PBO

Skill set requirements

Angular, PBO

Implementation Steps


When developing customizations to be delivered through the Central Package, the PCSG is mandating the use of Angular modules. This will prevent conflicts between the Central Package and Local Package, where both packages need to inject code on the same controller.

Part 1: Distributing the code

Different parts of the code are stored in different objects; for implementing a customization in the Central Package that is activated from the Local Package, we are recommending a group of five objects, two in the Local Package and three in the Central Package. Depending on the complexity of the customization you may not need all five objects.

In the Local Package

  1. A component that injects an Angular declaration into one of the prm-example-after hooks. This should be an empty tag that the Central Package will use as its own hook. If the local Primo is already using this prm-example-after hook, they can keep their own customization and simply add the new declaration after their own.
  2. A constant that holds any variables that can be set for local needs. Separating this makes for very clean code in the component and the Local Package can omit this part if they want to accept the Central Package defaults.

In the Central Package

  1. A module to hold the other objects; this ensures that the code is isolated so that there is no possible interference with other parts of Primo that we don’t control, and ensures that the customization is opt-in; the browser will ignore the module if it is not included in the app definition in the Local Package. If this module depends on another module, be sure to include that dependency in the square brackets.
  2. A component that injects the code into the page; this will use as a hook the declaration that was defined in the component in the Local Package. The component will include the controller if any processing needs to be done (if there is complex processing, or you need to reuse custom functions from different parts of your code you should split this out into a factory within the module).
  3. A value that holds default values for any customizable variables. When possible the customization should work without the Local Package needing to set any variables.

Part 2: Activating the customization in the Local Package

Three changes may be made in the Local Package to activate the customization; two will be necessary for all customizations, one may be optional.

  1. Include the relevant module in the app definition, for example:

    var app = angular.module('viewCustom', ['exampleModule']);
  2. Add the component that inserts our custom declaration onto the relevant prm-example-after hood, for example:

    app.component('prmExampleAfter', { template: '<custom-example />' });
  3. Add a constant to hold any locally customizable variables; if at all possible this should be made optional, allowing implementers to use Central Package defaults, for example:

    app.constant('exampleModuleOptions', {
       custom_label_1: "Text string 1",
       custom_label_2: "Text string 2",
       custom_url: ""

Part 3: Example Code

Here I have taken the code originally supplied by ExLibris for adding a clickable icon to the header and factored it into different objects for implementation as a Central Package customization.

In the Local Package

  1. Include in the app definition:

    var app = angular.module('viewCustom', ['customLogos']);
  2. Add the component that insert the custom declaration:

    app.component('prmLogoAfter', {template: '<custom-logo />'});
  3. Add the constant to hold locally customizable variables:

    app.constant('customLogoOptions', {
    link: "",
    title: "Whitworth Library",
    alt: "Whitworth Library Logo"

In the Central Package

  1. Define the module:

    angular.module('customLogos', []);
  1. Add the component that hooks onto the custom declaration in the Local Package and inserts the relevant code into the page:

    angular.module('customLogos', []).component('customLogo', {
    bindings: {
    parentCtrl: '<'
    require: {
    parentCtrl: '^^prmLogo'
    template: '<div class="product-logo product-logo-local" layout="row" layout-align="start center" layout-fill id="banner" tabindex="0" role="banner">' + '<a title="{{ title }}" href="{{ link }}">' + '<img class="logo-image" alt="{{ alt }}" ng-src="{{ $ctrl.getIconLink() }}"/></a></div>',
    controller: ['$scope', 'customLogoOptions', function ($scope, customLogoOptions) {
    var vm = this;
        vm.getIconLink = getIconLink;
        function getIconLink() {
            return vm.parentCtrl.iconLink;
       $ =;
       $scope.title = customLogoOptions.title;
       $scope.alt = customLogoOptions.alt;
  1. Add a value that holds defaults for locally customizable variables:

    angular.module('customLogos').value('customLogoOptions', {
    link: "",
      title: "Library Logo",
      alt: "Add alternative text for accessibility"