enonic / xp

Enonic XP
https://enonic.com
GNU General Public License v3.0
199 stars 34 forks source link

Add javascript object as property on response object, which can be used in response filters #6122

Open ComLock opened 6 years ago

ComLock commented 6 years ago

The way the current response object works is very coupled with HTML and thymeleaf. Components are not rendered inline so what the page returns is a finished HTML, but rather is contains component comments. I'm guessing the components are rendered async and put together in postProcess sorta like promises.

BTW are the order of pageContributions in the same order as the components on a page?

Working with render-js I autogenerate css and html from a javascript object.

Example render-js javascript object: https://github.com/ComLock/render-js/blob/master/test/obj.test.es#L95-L140

Currently the css is put inside a html string as a style element and then added to pageContributions.headEnd.

Since various components use the same autogenerated classes I built a filter to try to make it unique:

If I could pass a javascript object to the filters, it would open a lot more possibilities and make it possible to make much smarter implementations.

This may also be relevant in cases where you want to return something else than HTML...

I have previously discovered that you cannot add your own properties on the response object: https://discuss.enonic.com/t/passing-data-from-page-controller-to-responsefilter-via-http-response/609

Ideas, thoughts?

Documentation: http://xp.readthedocs.io/en/stable/developer/ssjs/http-response.html http://xp.readthedocs.io/en/stable/developer/site/filters.html

sigdestad commented 6 years ago

We need to discuss this in detail before implementing. I want to understand what it means.

ComLock commented 6 years ago

This is related to middlewares between server and application. We are pretty close to the JSGI "standard".

We could add a "env" property into which server and middlewares could pass along data. http://wiki.commonjs.org/wiki/JSGI/Level0/A/Draft2#request.env

Ref:

ComLock commented 6 years ago

I've been thinking a bit more about it though. The current response.body is a flat structure, while what the browser or client-side apps typically work with is hierarchal.

Hierarchal stuff:

In javascript the built-in hierarchical structure we got is the object. Which is what Render-js is utilising.

So instead of having Enonic XP component comments inside a string, I would like similar functionality as values somewhere inside an object tree.

If we implemented support for an response.env property, I could implement such features myself.

I could leave the body empty and only populate response.env.renderJs until the Render-js middleware was reached (response filter). There I could collate page, layout, parts, etc into a single dom and render it to body.

ComLock commented 6 years ago

This would make Enonic XP a more programmer friendly platform instead of a single way of doing things. Isn't that what we are trying to achieve with purplejs and modularizing?

ComLock commented 6 years ago

Keep this in mind when implementing pre-filters too. Those are also in essence middle-wares.

ComLock commented 6 years ago

I now have an example usecase for this. Duplicated page contributions.

A page contribution will not be added twice if it's identical.

At a customer they add tracking meta tags using page contributions.

Some meta tags are added by default in page. And sometimes the same metatags are added by parts. This leads to duplicated meta tags in the final html.

The metatag name attribute is the same while the content attribute is now the same. This is not something pageContributions handle (nor should it).

Using response.env I could implement my own smarter tracking middleware which would handle this easily.

ComLock commented 6 years ago

This could also be used to render React components server-side. In order for each component to have a unique css classname there needs to be a global stylesheet. So you would generate the css once, rather than many times if say for instance an Enonic XP part was a react component.

The same applies to any CSS-in-JS implementations.

ref:

https://raw.githubusercontent.com/axept/prejss/master/docs/prejss-schema.png

sigdestad commented 5 years ago

This is indeed interesting, Glenn will research how this can be done and if there are any side-effects.