Search code examples
apostrophe-cms

Apostrophe-CMS PageBeforeSend Specific to Module


I have a module that is extending apostrophe-custom-pages. I'm trying to add some extra data into the page request (in an async way, preventing use of a helper).

I was hoping to hook into the pageBeforeSend event, but then realized that it runs for EVERY page request, even ones that don't actually hit the pages in the module.

Is there an equivalent method to pageBeforeSend that will only be called if the page being requested is actually in the module where the method is defined?

I'm currently using dispatch to handle this, but I was hoping there might be a better way.


Solution

  • The short answer to your question is no. In Apostrophe 2.x (the current stable release) you must decide for yourself if your pageBeforeSend function is interested in a particular document and return or invoke the callback (if you have one) immediately if it is not relevant.

    However here is a longer answer that may shed more light on the question for you.

    The pageBeforeSend method is special: it is invoked for every module in which it exists. This is known as a callAll method.

    So in callAll methods you are responsible for deciding whether the request or document is relevant to your interests or not. And if you look at our own callAll method handlers you will note that if there is any doubt, we always begin by immediately invoking the callback and returning if the request or document is not relevant.

    Please note that in new code you should not write new callAll handlers. You should write promise event handlers instead. This is recommended in 2.x and in 3.x it will be the only way. However in 2.x your question has the same answer when writing promise event handlers: you must determine if the request or document is relevant to your interests, and if not, politely return without doing anything.

    In 3.x, we will be improving on this. The 3.x code (very much a work in progress, not ready for projects!) emits events like beforeInsert via the document manager module for the document in question, but lets you decide whether to catch them via that module's name, or via a parent class like apostrophe-doc-type-manager (matching all beforeInsert events for all doc types) or apostrophe-pieces (matching all beforeInsert events for pieces, but not for pages).