Plugin Templates
Copy-pastable example snippets for accelerating plugin development

Method of a component

In this example - render
1
const render = (args, callback, instance) => (
2
<>
3
{ callback.apply(instance, args) }
4
</>
5
);
6
7
export default {
8
'Component/NAME/Component': {
9
'member-function': {
10
render
11
}
12
}
13
};
Copied!

Container functions

Common case - when you need to pass an additional function from parent to child
1
export class NAMEContainerPlugin {
2
containerFunctions = (originalMember, instance) => ({
3
...originalMember,
4
handleSomething: this.handleSomething.bind(instance)
5
});
6
7
handleSomething(arg) {
8
console.log(arg);
9
}
10
}
11
12
const { containerFunctions } = new NAMEContainerPlugin();
13
14
export default {
15
'Component/NAME/Container': {
16
'member-property': {
17
containerFunctions
18
}
19
}
20
};
Copied!

Prop types

You need to add an additional prop to propTypes after passing an additional prop to the component? No problem!
1
import PropTypes from 'prop-types';
2
3
const propTypes = (originalMember) => ({
4
...originalMember,
5
handleSomething: PropTypes.func.isRequired
6
});
7
8
export default {
9
'Component/NAME/Component': {
10
'static-member': {
11
propTypes
12
}
13
}
14
};
Copied!

Default props

Not required new propType - do this.
1
const defaultProps = (originalMember) => ({
2
...originalMember,
3
pluginProp: 'PluginProp'
4
});
5
6
export default {
7
'Component/NAME/Container': {
8
'static-member': {
9
defaultProps
10
}
11
}
12
};
Copied!

More state

Additional fields for the state.
1
const state = (originalMember) => ({
2
...originalMember,
3
PluginState: 'PluginState'
4
});
5
6
export default {
7
'Component/NAME/Container': {
8
'member-property': {
9
state
10
}
11
}
12
};
Copied!

Adding a Reducer to the Redux Store

Add reducers to the application as follows.
1
import { NAMEReducer } from '../store/NAME;
2
3
const getStaticReducers = (args, callback, instance) => ({
4
...callback(...args),
5
NAMEReducer
6
});
7
8
export const config = {
9
'Store/Index/getReducers': {
10
function: getStaticReducers
11
}
12
};
13
14
export default config;
Copied!

Query fields

Additional query field shown below!
1
const _getMETHODFields = (args, callback, instance) => [
2
...callback.apply(instance, args),
3
'field_name'
4
];
5
6
export default {
7
'Query/NAME': {
8
'member-function': {
9
_getMETHODFields
10
}
11
}
12
};
Copied!

Reducer Initial State

1
const getInitialState = (args, callback, instance) => (
2
{
3
...callback(...args),
4
new_state: 'true'
5
}
6
);
7
8
export default {
9
'Store/NAME/Reducer/getInitialState': {
10
function: getInitialState
11
}
12
};
Copied!

mapStateToProps

Connect an additional piece of state to the component
1
const mapStateToProps = (args, callback, instance) => {
2
const [state] = args;
3
4
return {
5
...callback(...args),
6
pluginProp: state.SomeReducer.someState
7
};
8
};
9
10
export default {
11
'Component/NAME/Container/mapStateToProps': {
12
function: mapStateToProps
13
}
14
};
Copied!

mapDispatchToProps

Connect an additional dispatch function to the component
1
const { letsDoSomething } = import('Store/STORENAME/STORENAME.action');
2
3
const mapDispatchToProps = (args, callback, instance) => {
4
const [dispatch] = args;
5
6
return {
7
...callback(...args),
8
doSomething: (value) => dispatch(letsDoSomething(value))
9
};
10
};
11
12
export default {
13
'Component/NAME/Container/mapDispatchToProps': {
14
function: mapDispatchToProps
15
}
16
};
Copied!

Adding a Route to the Router

Note how we use async import(...) statement here in order to optimize bundle sizes!
1
import { lazy } from 'react';
2
import { Route } from 'react-router-dom';
3
4
import { withStoreRegex } from 'Component/Router/Router.component';
5
6
export const YourPage = lazy(() => import(
7
/* webpackMode: "lazy", webpackChunkName: "extension-name" */
8
'../route/YourPage'
9
));
10
11
const SWITCH_ITEMS_TYPE = (originalMember) => [
12
...originalMember,
13
{
14
component: (
15
<Route
16
path={ withStoreRegex('/path') }
17
render={ (props) => <YourPage { ...props } /> }
18
/>
19
),
20
position: 100
21
}
22
];
23
24
export const config = {
25
'Component/Router/Component': {
26
'member-property': {
27
SWITCH_ITEMS_TYPE
28
}
29
}
30
};
31
32
export default config;
Copied!

Extending maps

Example: creating a new tab in MyAccount
1
import { lazy } from 'react';
2
3
import {
4
MY_TAB_PATH,
5
MY_TAB_NAME
6
} from '../component/MyAccountCustomTab/MyAccountCustomTab.config';
7
8
import MyAccountCustomTab from '../component/MyAccountCustomTab';
9
10
const renderMap = (originalMember) => ({
11
[MY_TAB_NAME]: MyAccountCustomTab,
12
...originalMember,
13
});
14
15
const tabMap = (originalMember) => ({
16
...originalMember,
17
[MY_TAB_NAME]: {
18
url: `/${ MY_TAB_PATH }`,
19
name: __('My Tab')
20
}
21
});
22
23
export default {
24
'Route/MyAccount/Container': {
25
'static-member': {
26
tabMap
27
}
28
},
29
'Route/MyAccount/Component': {
30
'member-property': {
31
renderMap
32
}
33
}
34
};
Copied!