Ticket #1074 (closed Enhancement: fixed)

Opened 4 years ago

Last modified 3 years ago

Realizing thymeleaf page context preparation (viewData) across multiple plugins

Reported by: Malte Owned by:
Priority: Major Milestone: Release 4.8.7
Component: 3rd Party Plugins Version: 4.8.6
Keywords: Cc: jri, dgf, JuergeN
Complexity: 3 Area: Application Framework / API
Module: deepamehta-webactivator

Description

Example, in Plugin1.java

@Path("/my")
public Viewable myPages() {
    // prepare standard page
    viewData("pages", listOfPages);
    // FIRE CUSTOM event HERE so other plugins and their listeners can react
    // return thymelaef template
    return view("my-pages");
}

Trying to utilize dm4's custom event mechanism I could not enable "Plugin2.java" to contribute its own viewData() for this particular resource managed by "Plugin1". As dm4 web apps are usually seperated across many services it would be great if those services could enrich each other server side pages (e.g. prepare template fragments shared across many plugins, like e.g. navigation, footer or other menu areas).

Due to the nature of dm4 customs event, before any third party plugin (listening to the custom event fired by this resource) could react to this event, the resource method already returned.

In a growing web app built with dm4 this has lead me to many "quirky" workarounds and usability issues... Do you have any proposals on how we could achieve/implement this functionality (preparing page context over across many dm4-applications) so plugins remain de-coupled?

Thanks for your support!

Change History

comment:1 Changed 4 years ago by jri

Due to the nature of dm4 customs event, before any third party plugin (listening to the custom event fired by this resource) could react to this event, the resource method already returned.

I can't acknowledge that as DM events are fired synchronously.
Once dm4.fireEvent() returns you're sure all event listeners have been executed.
So, you should be able to solve your problem with a DM custom event.

Along with the event you could pass the Thymeleaf page context to give plugins an opportunity to modify it.

dm4.fireEvent(YOUR_CUSTOM_EVENT, context())

This would require to make the context() method protected in ThymeleafPlugin.java (at the moment it's private).

A 3rd party plugin (which listens to your custom event) would modify the page context this way:

import org.thymeleaf.context.AbstractContext;
import org.thymeleaf.context.VariablesMap;

@Override
public void yourListener(AbstractContext context) {
    // prepare page
    context.setVariable(name, value);    // name is a String, value is an arbitrary Object, just like in your viewData() calls

    // you can also inspect the variables already set
    VariablesMap<String, Object> data = context.getVariables();
}

Note: the context object passed is actually a org.thymeleaf.context.WebContext.

Last edited 4 years ago by jri (previous) (diff)

comment:2 Changed 4 years ago by jri

Can this ticket be closed?

comment:3 Changed 3 years ago by Malte

I am trying to realize this but have troubles getting th dm4-webpages dependencies resolved.

I could not succeed to provide the dm4-webpages module usage of the org.thymeleaf.context package (which should be provided by dm4-thymeleaf, i guess). Here is what I thought should be working:

In dm4-thymeleaf pom.xml declare:

                        <Export-Package>
                            org.thymeleaf.context;
                        </Export-Package>

In dm4-webpages pom.xml declare:

                        <Import-Package>
                            org.thymeleaf.context, *
                        </Import-Package>

But when I now try to start the plugins with this bundle-configuration I get the followung "unresolved constraint" message

org.osgi.framework.BundleException: Unresolved constraint in bundle de.mikromedia.webpages [43]: Unable to resolve 43.15: missing requirement [43.15] osgi.wiring.package; (&(osgi.wiring.package=de.deepamehta.thymeleaf)(version>=0.6.0)(!(version>=1.0.0)))

Does anyone has an idea on how to provide the dm4-webpages module with knowledge about the dm4-thymeleaf context package?

That would be very helpful.

comment:4 Changed 3 years ago by Malte

In this case, the dm4-thymeleaf bundle state is "Active" when inspecting osgi bundles with the gogo shell but the "dm4 internal plugin state" of the dm4-thymeleaf plugin does not reach the "Activated" log-line.

comment:5 Changed 3 years ago by Malte

Adapting the export declaration of the dm4-thymeleaf plugin to the following let the plugins start:

<Export-Package>
    org.thymeleaf.context;version="2.1.3.RELEASE",
    de.deepamehta.thymeleaf;version="0.6.2"
</Export-Package>

If this holds up and no exception will be thrown when consuming events of the dm4-webpages plugin I think we can close the ticket.

comment:6 Changed 3 years ago by jri

To my understanding this should be sufficient:

<Export-Package>
    org.thymeleaf.context
</Export-Package>

Note: no trailing semicolon here.
Explicit version numbers are not required as these are taken from pom.xml.

Explicit <Import-Package> is not required when dm4-webpages Java imports from that package anyways.
The imports are generated by the bundle plugin then.

Explicit export of de.deepamehta.thymeleaf is not required as the activator package is exported anyways.

See the generated imports and exports in /META-INF/MANIFEST.MF in your .jar bundle.

comment:7 Changed 3 years ago by Malte

  • Status changed from new to closed
  • Resolution set to fixed

As dm4-thymeleaf-0.6.2 this is now realized and in effect with the dm4-kiezatlas-website module.

Thanks for your support

Last edited 3 years ago by Malte (previous) (diff)
Note: See TracTickets for help on using tickets.