Introduction
Introduction
Modules are what allows the portal to be so flexible in its uses. They provide the main functionality of the portal from a user viewpoint. Although the portal comes with a few basic modules, any module can be made to extend the functionality.
In this documentation, we will explore how modules are designed and built, and introduce you to a number of tools for further integrating your module with the portal framework.
Read on for an introduction to what modules are, how they are loaded and the features they can use, or continue to the next page to get started making your own module.
What is a module?
In essence, a module is simply a Laravel app which has two main routes. These can be thought of as an admin side and a participant side.
Take, for example, a module which allows you to upload files. Its user side would show all the files belonging to that user, and allow a user to upload a new one. An admin side, however, would probably show all the files uploaded to the module and allow their status to be changed, them to be downloaded etc. Using laravel, making something like this is a breeze.
Of course, a real module would probably have an API too, as well as many more customizable features. This module is then published with composer, and can be pulled into any portal to be used.
To further understand how a module is used in the portal to provide functionality to users, check out the portal documentation.
Module Instances
To allow users to use your module multiple times, we create instances of your module. Say you’re creating a module to upload a file, and you want to create an API route to get all files.
If the API was created just for the module, not for the specific module instance, when we retrieved all files we would get all files ever uploaded through your module. If we had two services which used your module (an expense claim service and a risk assessment service), our API would return both expense claim submissions and risk assessment submissions from either module instance, which is not ideal.
Instead, your API should just return files specific to a single module instance, so either the expense claim service or the risk assessment service. Your 'get all files' route will exist as
-
GET /api/expense-claims/evidence/upload-file/file
-
GET /api/risk-assessment/new/upload-file/file
Notice the activity and the module slugs change and the results of the API change depending on the module or activity in use.
When we create a new module instance, it is assigned a slug. When this slug is accessed, we can load your module page and pass it the settings for the module instance, load permissions etc.
In general, you should find that you don’t need to think about this too much since the SDK takes care of most the complications. However, it is good to have it in mind when developing a module.
How does a module integrate?
So we’ve got a couple of pages which allow us to do something like upload and view files, and possibly an API and some settings too. How do we let the portal know how to use the module and let users create many instances of our module to be used in different services?
It’s as simple as using our service provider! All packages have a service provider, which tells Laravel what your package does and how to use it. We utilise this container information to register your module. For example, we will register any filters your module defines, register that the module exists with a name and description, and we’ll define the permissions the module makes use of.
To save and retrieve this information, we use the SDK. The SDK allows us to register all this information, and provides us with helpful interfaces and methods to make building the features for the portal easy. For example, we provide an abstract filter class, so you only have to implement a couple of methods to make your filter work!
The portal, the playground or any other frontend can then retrieve this information by also using the SDK and do with it what it wants. The playground will get all modules from the SDK, which will be returned as a 'Module' class, which is created by the SDK when your service provider is booted. Neat, huh?
The below shows how the communication works in an example of something like the playground or portal wanting a list of all modules that’re available to it.
In this way, we can create services using your module. When someone opens your module as part of a service, we redirect them to a route we automatically define for you (so from the modules point of view, it’s just the root url '/'). We load the current module instance, service etc and let your module define what the user sees and can do.
What does the SDK allow us to do?
The rest of this documentation will go through these features in more depth. As well as the features listed below, which are the things we feel modules will use most often, any module is welcome to use any part of the SDK. For example, a module could be made that creates new services by using the SDK like the portal does! For more information about these additional features, see the component reference.