Skip to content

Commit

Permalink
feat(plugins): simplify plugins load via hooks
Browse files Browse the repository at this point in the history
A plugin can be loaded via a single attachPlugin method via hooks.js
  • Loading branch information
amoncaldas committed Jul 19, 2021
1 parent 736adf1 commit 52d684f
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 17 deletions.
14 changes: 5 additions & 9 deletions src/config-examples/hooks-example.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,12 @@
// without the -example on the same folder that it resides.


// THE CODE BELOW IS COMMENTED out BECAUSE THEY ARE JUST EXAMPLES
// THE CODE BELOW IS COMMENTED OUT BECAUSE THEY ARE JUST EXAMPLES

/*
import main from '@/main'
import PluginExample from '@/plugins/plugin-example/plugin-example.js'
// Create a var that will have a reference to the
// plugin instance when it is instantiated in
// appLoaded hook defined below.
var pluginExample
const appHooks = main.getInstance().appHooks
// When adding a hook, three parameters can be passed:
Expand All @@ -24,10 +19,13 @@ const appHooks = main.getInstance().appHooks
// parameter value that is passed when the hook is run.
appHooks.add('appLoaded', (vueInstance) => {
pluginExample = new PluginExample(vueInstance)
const pluginExample = new PluginExample(vueInstance)
appHooks.attachPlugin(pluginExample, vueInstance)
// Do something when the app is loaded
}, 1)
// #### INDIVIDUAL HOOKS DEFINITION ###
// The catch all hook allows, as the name says, catching all
// the hooks. It receives as parameters not only the hook parameter
// arg, but also the hook name. It can be used to run plugin functions
Expand All @@ -43,8 +41,6 @@ appHooks.add('catchAll', (hookName, hookData) => {
}
}, 1)
// #### INDIVIDUAL HOOKS DEFINITION ###
// If you want to define the hooks individually,
// then the templates are shown below.
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/plugin-example/plugin-example.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class PluginExample {
* @param {Object} hookData
*/
mapReady (hookData) {
console.log('PluginExample: mapReady callback', hookData)
// hookData has the following structure {context: Object, map: Object}
// The leaflet `map` object is passed and
// you can potentially change it by adding or removing controls
Expand All @@ -45,6 +46,7 @@ class PluginExample {
* @param {*} mapViewData
*/
mapViewDataChanged (mapViewData) {
console.log('PluginExample: mapViewDataChanged callback', mapViewData)
// change the mapViewData object
// so that it will update the map view
}
Expand Down
12 changes: 6 additions & 6 deletions src/plugins/readme.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# Plug-ins folder #
# Plugins folder #

Each plug-in must be contained in a folder created under the `plugins` folder.
Each plug-in must be contained in a folder created under the `src/plugins` folder.
For example: src/plugin/my-awesome-plugin. No file should be directly put in the root of the `plugins` folder.

Each plug-in must have a class and methods/functions that can be called on hooks defined in the hooks.js.
Check the ExamplePlugin in `plugin-example/plugin-example.js` and `/src/config/hook-example.js` for more details.

## What can be used in a plug-in ? ##

Next to the parameters passed to each method via hook call, inside a plug-in you can use the values stored in the
[vuex](https://vuex.vuejs.org/guide/) store (you need to import store from '@/store/store') and access,
In addition to the parameters passed to each method via hook call, inside a plug-in you can use the values stored in the
[vuex](https://vuex.vuejs.org/guide/) store. In order to access the app store you need to import store from '@/store/store') and access it via,
for example `store.getters.mapBounds`.
You can also use the app constants to compare values.
For this import `constants` from `@/resources/constants`.

You can also use the app constants to compare values. For this import `constants` from `@/resources/constants`.

Within the plug-in you can also set listeners to events emitted via `evenBus`, for example `mapViewDataChanged`,
as well as emit those events.
Expand Down
35 changes: 33 additions & 2 deletions src/support/app-hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import lodash from 'lodash'
*/
class AppHooks {
/**
* MapViewData constructor
* AppHooks constructor
*/
constructor () {
this.hooks = []
this.plugins = []
}

/**
Expand Down Expand Up @@ -49,6 +50,7 @@ class AppHooks {
let targetHooks = lodash.filter(this.hooks, function(h) { return h.name === hookName })

arg = this.executeCatchAllHooks(hookName, arg)
arg = this.runPluginHook(hookName, arg)

// Only continue if there hooks
if (targetHooks.length > 0) {
Expand Down Expand Up @@ -88,6 +90,35 @@ class AppHooks {
}
return arg
}

/**
* Attach a plugin to the hooks system
* @param {Object} pluginInstance
*/
attachPlugin (pluginInstance, vueInstance) {
this.plugins.push(pluginInstance)
if (pluginInstance && typeof pluginInstance.appLoaded === 'function') {
return pluginInstance.appLoaded(vueInstance)
}
}

/**
* Execute a hook of a plugin
* @param {Object} hookName
* @param {String} arg
* @returns {Object} arg
*/
runPluginHook (hookName, arg) {
if (Array.isArray(this.plugins) && this.plugins.length > 0) {
for (let key in this.plugins) {
let plugin = this.plugins[key]
if (plugin && typeof plugin[hookName] === 'function') {
return plugin[hookName](arg)
}
}
}
return arg
}
}
// export the AppHooks json builder class
// Export the AppHooks class
export default AppHooks

0 comments on commit 52d684f

Please sign in to comment.