Focus Mode - reggie7/aem-tools GitHub Wiki
Focus mode is the simplest special mode developed in AEM Tools. Initially its purpose was aimed at providing a better authoring of component pools.
So the story goes like this. We have some shared pool pages that allow editors to create and configure reusable components. Many of them can be placed in a single pool. Once these are ready they can be referenced from many other places (this whole idea was implemented before content fragments were introduced). For author's convenience each reference component displayed a link to the pool from which the referenced component came from. But as the pools were getting bigger this link was not helpful enough.
That's where the focus mode came in handy. It's initial purpose was exactly this - to strip the page from non-essential content and simply present the component in question:
The simplest example from the video is enigmatic/focusable. The focusable component can be found at enigmatic/test/focusable. cq:editConfig defines the custom action config for focus toggle button which comes from complex.js clientlib. focusable.html defines what the regular view renders and focus.html drives the selector inside the focus mode.
Another raw example is a pool and reference tandem. Poolable resources are rendered in the reference component. The latter is also displaying a focus link which is aimed at the author.
The most complex example is definitely the table. Focus is used there as a part of editing process. Focus enters the first layer of nested special modes and allows editing header dialog and rows parsys. Further editing capabilities are presented via second layer nested expand mode. These allow editing contents of the cells.
All of the above relies heavily on the custom parsys to which we can add custom selectors. The script that makes all of the above functionality work is parsys/focus.html. It's using a ComplexComponent model class. When in focus mode focus.html of the parsys will be used instead of the selectors-free code. And the selector script does the following (using output from the ComplexComponent c):
- displays author info, if the current parsys rendered is the direct parent of c.target resource (c.parent is true),
- displays c.child of the parsys if the child is an ancestor of c.target resource (c.outer is true),
- displays all its children if the parsys is a descendant of c.target resource (c.inner is true).
This will ensure to only show what is relevant in regards to the target resource passed as a parameter - just the way the video shows. Note that the described mechanism only covers content from paragraph systems of the page. Fixed resources need their own approach.
Up till this point it's basically the same as in the first part of zoom mode. The only difference is that here focus.html will display additional info before the focused component. That's because it was designed to work with all components, not only those that extend complex base component (which zoom assumes).
The simplest way to use the focus functionality is by incorporating the focus link the way it is showcased in the reference example. This way we'd stay with the initial purpose of focus feature. The page that the link targets would basically show the same component, but isolated from others (provided the target component does not implement 'focus' selector).
For complex components one can use focus to show different views within author environment the way it works inside focusable example. The two things to do then for the developer are to
- appropriately configure cq:editConfig (to enable the editbar button),
- add custom focus selector script.
The latter would then need to render the component the way we need to show it focused - most likely with additional authoring options. A nice example is the stage component's focus mode showcased in sample content's blog page. Another would be slider of home/lang page (where we needed custom item/focus.html additionally).
Focus is nice for one level depth of complexity. At least that's the way it's mostly showcased in the project. For even more complex components zoom mode has more examples within AEM Tools. To see how focus can be set up to work as a level of nested special modes please check table example or the slider in the blog page.
The most common (from my experience) usage comes from container-like complex components (like e.g. slider from blog page). Let's consider the schema below:
The component consists of an arbitrary number of items and the end user will see them in a parsys unfriendly layout. What is more - the markup of the items does not need to necessarily fit AEM's parsys markup. But as AEM developers we'd like to make it authorable - and actually parsys is usually our tool of choice in such events (if not - it should be). So in focus mode (also in zoom or expand modes) we would transform the layout to look like this:
What stands out is that:
- the layout is now much more parsys-friendly
- each single item is actually the complex container with one child inside
- arrows are skipped - representing all that is not necessarily needed for authoring
parsys/focus.html handles one part of our needs out of the box. But now we will need to handle the above transformation customized for each such component on its own. We'd do it like this:
- add focus action button to cq:editConfig,
- add focus.html to the complex container component and fill it with simplest code that includes appropriate raw parsys,
- add focus.html to the item component(s) to fill it with container's markup stripped out of useless stuff and replace the list of items by an include of current main script.
Let's say the container pseudo-markup looks like this:
<ul class="container">
<li>#include item_1</li>
<li>#include item_2</li>
<li>#include item_3</li>
...
</ul>
Then the container's pseudo-focus.html would look like this:
<div #include items></div>
and respectively for a single item's pseudo-focus.html we'd have:
<ul class="container">
<li #include item.html></li>
</ul>
There are many examples for zoom mode that conform to the above schema, please check e.g. gallery's sample page and code (also for item). The same example shows how similar those two special modes are - you can focus the same page and code (also for item) is basically an include of the zoom parts. The same applies to slider - it has its own focus achieved with focus.html and item/focus.html. Obviously if one was to choose only one special mode - the include code would be replaced by what is actually included. Here we're just reusing the stuff that is the same (DRY).