-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lambdas: extension to Rich Attributes that allow transformation of objects and to render arbitrary widgets #1021
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestions for minor language changes and some formatting in the docs.
Co-authored-by: PBia <[email protected]>
@yankovs: Yeah, it would be something that is both a transformer and renderer 🤔
There is no lazy loading in typical case because all attributes are eagerly loaded by MWDB. But items itself may contain widgets that are implemented by plugin and lazy-load some additional data. |
0edec6b
to
6129d5b
Compare
Well.. I have done some pagination. I see these tables are not the most beautiful thing 😆 I have also not tested whether components within rows are preserving their state after clicking "More", but it should work. Solution is a bit hacky because lambda emits React objects, so we need to build Markdown from parts and call Markdown renderer ourselves. |
Ok, I'm going to merge it and give it a try. |
Your checklist for this pull request
- [ ] I've added automated tests for my change (if applicable, optional)This is next rework of great idea from #951 and its extension from #955. It introduces a concept of transformers (called using pipeline syntax) that modify objects and renderers that allow to put any object we want within a render.
This time I was able to render a very complex view with collapsible lists, sections, custom icons and so on.
Technical details
Marked&Mustache rendering looks as follows.
Transformers are simple, it's just a function that gets an object as an argument and returns a modified object. To make it possible, I introduced pipeline syntax
which is equivalent to
entries(sort(view["value"]))
.More complicated thing is renderer. It is usually called using a section syntax e.g.
If lambda returns an object that is not a simple string (e.g. rendered component), it is stored in MustacheContext with an unique id e.g.
lambda_result417
. Then proper reference is put in Markdown string[](lambda#lambda_result417)
. Finally, Markdown renderer retrieves object from MustacheContext and puts it in rendered React object tree.Rendering process can be nested and lambda may subrender section part of template into React. It may also run only the Mustache renderer and only the context-related Markdown renderer if needed.
Finally, lambdas can be parametrized using previously rendered values in special sections.
indicator.type
is a lambda that renders subtemplate (danger
) using only the Mustache renderer and preserve the resulting string inindicatorType
key in MustacheContext.lambdaContext. Then, this value is retrieved byindicator
lambda to use proper icon. I used this pattern to implement if-clause, groupBy and other parametrized lambdas. This means we are not only able to call functions but also to parametrize them with values from the object.Example template code and attribute value
Attribute value: