Fragment Entry Processors

thumbnail
Christoph Rabel, modified 5 Years ago. Liferay Legend Posts: 1555 Join Date: 9/24/09 Recent Posts
So, I have started to fool around with FragmentEntryProcessors and created a PoC implementation for some usecases I have.
I'd like to mention my usecases first, to show why I am trying to do this and what I want to achieve. Maybe there are other ways to solve this. I have already created some tickets that touch the usecases here, but till they are implemented, I need to do some things by myself.
a) I want to know in freemarker, if I am in edit or view mode. I'd like to print different markup in that case.
https://issues.liferay.com/browse/LPS-115828
I  decided to simply inject a freemarker variable ([#assign fragmentEditmode = 'VIEW' /]) into the fragment before the FreeMarkerFragmentEntryProcessor is executed.
b) I want to have a picture tag with srcset for to provide optimized image versions for various resolutions.
https://issues.liferay.com/browse/LPS-94984
I have some nice code for freemarker templates here, but in Fragments, I have no image url. The url is only injected by the EditableFragmentEntryProcessor and not available in the fragment. But I need to know which image was selected to provide alternative images/resolutions.
For flexibility reasons I have decided to inject the url of the images as freemarker variables. This allows me to use the url in various place, call backend services with it and so on.
I got it working with limitations ...

1) Validate of FreeMarkerFragmentEntryProcessor fails ...
So, I inject a new variable fragmentEditmode into the fragment:
html = "[#assign fragmentEditmode = '" + fragmentEntryProcessorContext.getMode() + "' /]".concat(html);
Works perfectly in the editor.

But I can't SAVE the fragment anymore, because FreeMarkerFragmentEntryProcessor.validateFragmentEntryHTML fails since fragmentEditmode does not exist when the fragment is validated ...
I can work around that but this is a bit annoying. Maybe the validation function could be changed to:
public String validateFragmentEntryHTML(String html, String configuration)  // allows me to return a "fixed" html to the next validator in line.

Also: It might also be reasonable to validate the processed html in each step instead of the original one.

2) I also am a bit unhappy about the HUGE codeblock I needed to copy & "fix" from EditableFragmentEntryProcessor to get the image url. I am not sure if all of it still works, I didn't test it at all with display page and mappings.
Maybe that huge if-cascade in processFragmentEntryLinkHTML that determines the value could be moved into the FragmentEntryProcessorHelper? Could be useful for BackgroundImageFragmentEntryProcessor too. It contains a similar block and I am not exactly sure if all the differences are intended. Maybe, maybe not.

3) Performance
I am unsure about the performance implications of that. How does it impact caching if I create a FragmentEntryProcessor. How does it know, if a fragment can be cached or not? The behavior I would prefer is: It should be cached in VIEW mode and I should never inject something that e.g. depends on the current user.
4) Documentation & IDE/Blade module template
Documentation is a bit, well, non-existent. The blog by Pavel is quite useful (https://liferay.dev/blogs/-/blogs/fragments-extension-fragment-entry-processors ) but the github link is broken.
A module project template would be nice, too.
6) fragment.entry.processor.priority 0 - 6
I noticed that the fragment.entry.processor.priority for existing processors goes from 0 to 6 (or maybe 7).
If I were to add multiple processors to inject Freemarker, I would need to set the order to 0 for all my processors. I don't like that, I'd rather have a clear order. While it won't be an issue in my case, because the features are pretty orthogonal, that might not be always the case. e.g. I might need to RELIABLY inject my own processor between FragmentEntryProcessor (order 1) and EditableFragmentEntryProcessor (order 2).  It would be far better if the order of the standard processors was done in steps of at least ten.