Plugin Implementation
The main purpose of a Plugin is to extend or add new functionality by tapping into Player’s pipeline of components via hooks. In this section we’ll go over the steps to implement a plugin.
We’ll use the stage-revert-data plugin as example. After creating our plugin class, we’ll use the apply
method which provides access to the Player instance, which then gives access to the necessary hooks.
For this case we needed to define variables that will store references for the scope the hooks will share:
dataController
: Reference to the data controller hook in the Player instance, can be used to read, update or commit new changes to the data modelstageData
: View attribute that comes from the view state, used for enabling the staging of datacommitTransitions
: The list of view names which the shadow model should be committed if transitioned to. Comes from the view state attribute as well.commitShadowModel
: Flag that enables committing shadow model into data model after the transition, only ifstageData
is set to true and the next target view name is included incommitTransitions
.GatedDataMiddleware
Instance fromValidationMiddleware
to be used as a middleware to intercept the data-model pipeline before any data is committed and cache the data instead, only ifstageData
is set to true.
The next step is to tap into the necessary Player hooks. First we tap into the viewController
which we can then intercept the resolveView
hook. Player hooks are implemented with the Tapable package, so we can use the interception API’s call
method, this triggers everytime the hook is triggered, then we get access to the current view state and read the stageData
and commitTransitions
attributes.
Note
: notice how each time we tap into a hook, we use the this.name
property as the name of the plugin. This is important to avoid conflicts with other plugins.
Next we tap into the dataController
, so we can scope the data controller instance for future use. Then we tap into the resolveDataStages
plugin in this data controller instance. If the stage
property is set to true, we add our GatedDataMiddleware
to the data pipeline. If not, we return the data pipeline as is.
Finally, we tap into the flowController
so we can intercept the flow
hook. We then tap into the transition
hook, which is called every time the player transitions from one view to another. If the commitTransitions
includes the next view name, we set the commitShadowModel
flag to true, and commit the data stored in the shadow model through GatedDataMiddleware
into the data model. Whether the data was committed from the shadow model or not, we clear the shadow model paths in the GatedDataMiddleware
instance and set the commitShadowModel
flag to false as final steps.
And this is how we implement a plugin that manages the staging of data based on the view state attributes.
Code Snippets Reference: StageRevertDataPlugin