Search code examples
apostrophe-cms

Apostrophe-CMS Render Widget Templating


I've been working on a utility to change what widgets are shown inside of other widgets based on the page they are on. For example, I only want to be able to add a special "anchor" widget when an editor is on a special "anchor" page, but they also need to be able to add them inside of a two-column widget I created. Since I don't want the option to be present in the two-column widget unless they are still on the "anchor" page, I set up a service that passes in the widget options to apos.area depending on the widget and page information.

The issue I'm running into is that the template code on the widget does not appear to have run when I add a widget to the page. Specifically, I've added a {{data.page.type}} string to the widget to test. When I first add the widget, if I don't reload, the text does not show up. At first glance, I'm assuming it is probably because data.page is not available during render-widget, so the page type cannot be viewed. Is that correct, and is there any way around it besides overriding the rendering method to take page into account?

Thanks!


Solution

  • That is the issue, yes: render-widget doesn't know about the page. Widgets were originally meant to be self-sufficient, partly to enable easier caching, but the number of situations in which people want them to be aware of the page is larger than we expected.

    You can pass the information about the page that you really need as options to the widget every time you make an apos.singleton or apos.area call. Don't pass the entire page as that would produce a great deal of JSON in the markup.

    Of course this is extra work and thus unsatisfying. So, consider using a nunjucks macro that passes what's needed to replace your direct apos.area and apos.singleton calls.

    It is on our radar to look at adding support for accessing data.page in a widget. It is a fairly deep change.