Summary

We offer out-of-the-box the possibility to extend the functionality of the site by hooking on the execution of the functions on browser side. Although this feature was initially designed to allow different integrations (such as GA/GTM or New Relic), it is perfectly adapted to extend the functionality of the site as it may be needed. Be aware that using extensions requires development skills (mostly on Javascript). The level of the required skills depends on the complexity of the extension.

The basic principle of hooks is that are executed immediately after the execution of the target function (which has to be known in the global scope), it is aware of the result of the execution of the target function, it is aware of the arguments used to execute the target function and it can take additional parameters to further extend the functionality.

Target function

The target function needs to be known in the global scope to be hookable. You may take a look to this document to see an example of how to make a function hookable.

The hook is set by hooks.addAction method which takes the following parameters:

  • hookable function: the name of the target function
  • additional arguments: array of values which will be attached to the hook besides of the target function arguments which are passed by default to any hook
  • priority (0 is the highest): sets the order of execution for the hooks attached to the same target function
  • hook type: string which can be init or pre or post

Hook type

There are three types of hooks, depending on what target function is needed to be extended. There are three intervals in which the potential target functions are executed:

  1. Executed outside/before document.ready (INIT-HOOKS).
  2. Executed after document.ready and before the document/page is fully loaded, including all async functions (PRE-HOOKS)
  3. Executed on user action such as click on buttons (POST-HOOKS)

INIT-HOOKS

These hooks are ideally for inline functions executed within <script> tags and for functions executed outside document.ready blocks. These hooks are located in _includes/siteIncludes/partials/init-hooks.html.

Example of an init hook:

<script id="init-hooks">
    
    /*
     * define here the actions that hooks into site init proces
     * init process = any function executed before document.ready event
     * can be useful to hook on any function called by <script> tag
     * only settings superglobal is visible here
     * HEADS UP!!!
     * AT LEAST ONE INIT HOOK ACTION MUST BE SET IN ORDER TO ALLOW PRE AND POST HOOKS
    */

    hooks.addAction('customiseTheme', (functionName, result, args) => { 
        console.log(`init hook after: ${functionName} on {{page.permalink}}`);
        nrLog(
            'loading page', 
            `executed ${functionName}`, 
            'info', 
            {
                functionName: functionName,
                result: result,
                args: args
            }
        );
    }, 0, 'init');
    
</script>

PRE_HOOKS

These hooks are ideally for functions executed after document.ready and before the document/page is fully loaded. These hooks are located in assets/js/pre-hooks.js.

Examples of pre-hooks:

hooks.addAction('removeUselessElements', (functionName, result, args) => { 
    console.log(`sample pre-hook after: ${functionName} on ${$('page-data-permalink').text()}`) 
}, 5, 'pre');

hooks.addAction('removeUselessElements', (functionName, result, args) => { 
    console.log(`sample pre-hook after: ${functionName} on ${$('page-data-permalink').text()} higher priority`) 
}, 4, 'pre');

hooks.addAction('setPageButtonsFunctions', (functionName, result, args) => { 
    console.log(`sample pre-hook after: ${functionName} on ${$('page-data-permalink').text()}`) 
}, 1, 'pre');

hooks.addAction('addCat', (functionName, result, args) => { 
    console.log(`sample pre-hook after: ${functionName} on ${$('page-data-permalink').text()} lower priority`) 
},7, 'pre');

POST-HOOKS

These hooks are ideally for functions executed in user actions such as click on buttons (POST-HOOKS). These hooks are located in assets/js/post-hooks.js.

Examples of post-hooks:

postHooksActions = {

    addNoteAction: (functionName, result, args, ...extraArgs) => {
        const userToken = Cookies.get(settings.user.userTokenCookie);
        gtmObject = {
            'userToken': userToken,
            'event': 'Add_Custom_Note' 
        };
        fireGTMTag(gtmObject);
    },

    addTagAction: (functionName, result, args, ...extraArgs) => {
        const userToken = Cookies.get(settings.user.userTokenCookie);
        gtmObject = {
            'userToken': userToken,
            'event': 'Add_Custom_Tag' 
        };
        fireGTMTag(gtmObject);
    },
    addCatAction: (functionName, result, args, ...extraArgs) => {
        const userToken = Cookies.get(settings.user.userTokenCookie);
        gtmObject = {
            'userToken': userToken,
            'event': 'Add_Custom_Cat' 
        };
        fireGTMTag(gtmObject);
    },
    savedItemsToJsonAction: (functionName, result, args) => {
        nrLog(
            'savedItems to JSON', 
            'savedItems saved to JSON', 
            'info', 
            {
                functionName: functionName,
                result: result,
                args: args
            }
        );
    },
    savedItemsFromJsonAction: (functionName, result, args, ...extraArgs) => {
        nrLog(
            'savedItems from JSON', 
            'savedItems loaded from JSON', 
            'info', 
            {
                functionName: functionName,
                result: result,
                args: args, 
                argsExtra: extraArgs, 
            }
        );
    },

    showToastAction: (functionName, result, args, ...extraArgs) => {
        nrLog(
            'toast was shown', 
            'show toast', 
            'warn', 
            {
                functionName: functionName,
                result: result,
                args: args, 
                argsExtra: extraArgs, 
            }
        );
    }

}

hooks.addAction('addNote', globUtils.bindArgsAtEnd(postHooksActions.addNoteAction, ), 0, 'post'); // hook by function name
hooks.addAction('addTag', globUtils.bindArgsAtEnd(postHooksActions.addTagAction, ), 0, 'post');
hooks.addAction('addCat', globUtils.bindArgsAtEnd(postHooksActions.addCatAction, ), 0, 'post');
hooks.addAction('saveLocalStorageKeyAsJsonFile', postHooksActions.savedItemsToJsonAction, 0, 'post');
hooks.addAction('loadLocalStorageKeyFromJsonFile', globUtils.bindArgsAtEnd(postHooksActions.savedItemsFromJsonAction, ), 0, 'post');

hooks.addAction('showToast', postHooksActions.showToastAction, 0, 'post');

// the following hooks are tests, may be removed later
hooks.addActionEX(deleteNote, (functionName, result, args) => { 
    console.log(`sample post-hook by object after: ${functionName} on ${$('page-data-permalink').text()}`) 
}, 0, 'post'); // hook by function object

hooks.addAction('addCat', (functionName, result, args) => { 
    console.log(`sample post-hook after: ${functionName} on ${$('page-data-permalink').text()}`) 
},4, 'post');

hooks.addAction('addCat', (functionName, result, args) => { 
    console.log(`sample post-hook after: ${functionName} on ${$('page-data-permalink').text()} higher priority`) 
},3, 'post')

On this page



Comments
Title : pageTitle
Reference : anchor