T
- the type of object-to-render that this decorator decoratespublic interface RenderableDecorator<T>
rendered
.
While this type is called renderable decorator, it is not restricted to decorating Renderable
implementations
but is used to decorate all types of objects to be rendered.
Renderable decorators are able to decorate/transform objects to be rendered.
That is, they effectively sit between the call to Context.render(Object)
and Renderer.render(Context, Object)
of the target renderer.
All of the decorators that are type compatible with the object to be rendered are invoked cumulatively in the order that they are returned from the context registry.
It is not required, but generally advisable for decorators to return a new object instead of mutating the object they receive.
import ratpack.test.embed.EmbeddedApp;
import ratpack.render.Renderer;
import ratpack.render.RenderableDecorator;
import static org.junit.Assert.*;
public class Example {
public static void main(String... args) throws Exception {
EmbeddedApp.fromHandlers(chain -> chain
.register(registry -> registry
.add(Renderer.of(Integer.class, (ctx, i) -> ctx.render(i.toString())))
.add(RenderableDecorator.of(Integer.class, (ctx, i) -> i * 2))
.add(RenderableDecorator.of(Integer.class, (ctx, i) -> i * 2))
)
.get(ctx -> ctx.render(1))
).test(httpClient ->
assertEquals("4", httpClient.getText())
);
}
}
Such decorators are often used to augment the “model” being given to a template rendering engine to include implicit services and so forth.
Note that decorators are selected based on the exact runtime type of the object being rendered, that is based on its Object.getClass()
.
As such, decorators must advertise to decorate concrete types as opposed to interfaces or super classes.
A decorator effectively cannot change the type of the object-to-render.
Modifier and Type | Method and Description |
---|---|
Promise<T> |
decorate(Context context,
T object)
Decorates the given object on its way to being rendered.
|
java.lang.Class<T> |
getType()
The type of objects that this decorator decorates.
|
static <T> RenderableDecorator<T> |
of(java.lang.Class<T> type,
java.util.function.BiFunction<? super Context,? super T,? extends T> impl)
Creates a renderable decorator implementation for the given type that uses the function as decorator.
|
static <T> RenderableDecorator<T> |
ofAsync(java.lang.Class<T> type,
java.util.function.BiFunction<? super Context,? super T,? extends Promise<T>> impl)
Creates a renderable decorator implementation for the given type that uses the function as decorator.
|
default Action<RegistrySpec> |
register()
A registration action, typically used with
RegistrySpec.with(Action) . |
static <T> TypeToken<RenderableDecorator<T>> |
typeOf(java.lang.Class<T> type)
Creates a type token for a decorator of objects of the given type.
|
static <T> TypeToken<RenderableDecorator<T>> typeOf(java.lang.Class<T> type)
T
- the object-to-render typetype
- the object-to-render typejava.lang.Class<T> getType()
Promise<T> decorate(Context context, T object)
Implementations may either mutate the object and return it, or return an entirely new object.
context
- the request contextobject
- the object-to-renderstatic <T> RenderableDecorator<T> of(java.lang.Class<T> type, java.util.function.BiFunction<? super Context,? super T,? extends T> impl)
The function must return the renderable, not a promise.
If the decoration needs to perform async ops, use ofAsync(Class, BiFunction)
.
T
- the type of object-to-render to decoratetype
- the type of object-to-render to decorateimpl
- the implementation of the decorate(Context, Object)
methodstatic <T> RenderableDecorator<T> ofAsync(java.lang.Class<T> type, java.util.function.BiFunction<? super Context,? super T,? extends Promise<T>> impl)
The function must return a promise for the renderable.
If the decoration does not need to perform async ops, use of(Class, BiFunction)
.
T
- the type of object-to-render to decoratetype
- the type of object-to-render to decorateimpl
- the implementation of the decorate(Context, Object)
methoddefault Action<RegistrySpec> register()
RegistrySpec.with(Action)
.
Registers this object with the type RenderableDecorator<T>
(where T
is the value of getType()
), not its concrete type.