Class MustacheMixin
Compose into a host resource via
@Rest(mixins=MustacheMixin.class); the host then:
- Gains a default mount at
/mustache/*that serves raw Mustache templates from the importer's classpath by asking the configuredMustacheFactoryto compile and render them with no scope (raw render path; callers who want attributes useMustacheViewfrom a typed handler instead). - Routes the host's own
@RestOp-method return values of typeMustacheViewthrough the Mustache engine automatically.MustacheMixindeclares@Rest(mergeResponseProcessorsIntoHost=true), so a plain@Rest(mixins=MustacheMixin.class)folds itsMustacheViewRendererinto the host's own response-processor chain — nomergeIntoHostor explicitresponseProcessors=on the host needed.
Composition example (microservice):
Configurable mount path:
The default mount /mustache/* can be overridden via the SVL variable
${juneau.mustache.path:mustache} — set via system property
(-Djuneau.mustache.path=views), environment variable
(JUNEAU_MUSTACHE_PATH=views), or Config key
(juneau.mustache.path = views) to change the runtime mount without subclassing.
Resolution happens once at RestContext construction time (SVL resolution in @RestOp(path)).
Mixin-only deployment:
This resource is designed for composition via @Rest(mixins=...). The mount path is
pinned at the op level by
@RestGet(path="/{juneau.mustache.path:mustache}/*") on render(java.lang.String, org.apache.juneau.rest.server.RestRequest, org.apache.juneau.rest.server.RestResponse);
a class-level @Rest(paths=...) declaration would be silently ignored under the mixin
pattern (see @Rest(paths) Javadoc).
Choosing a MustacheFactory:
The juneau-rest-server-view-mustache module ships only the mustache.java
compiler API in provided scope. No factory bean is bundled. The bridge resolves
a MustacheFactory at first use from three sources, in order:
- User-supplied bean: register a
@Bean MustacheFactory(Spring) orBasicBeanStore.put(MustacheFactory.class, factory)(microservice). Allows full control of resolvers, object handlers, and encoders. - Bridge default: when nothing is registered, the bridge constructs a default
DefaultMustacheFactoryanchored on a resource root derived frombasePath(leading + trailing slashes trimmed; a"/"base yields a no-prefix factory). WithbasePath("/templates/"), the factory resolves template names like"hello.mustache"as classpath resourcetemplates/hello.mustache.
mustache.java's DefaultMustacheFactory caches compiled templates internally. The
bridge-default factory honors cacheTemplates(...)
(default true — production-safe): set false to have the bridge rebuild
the factory from a fresh, empty compile-cache on every render (dev hot-reload). Consumers who
supply their own @Bean MustacheFactory manage its caching themselves — the flag
only affects the bridge-default factory.
When no Mustache engine is on the classpath, the renderer surfaces
MustacheViewRenderer.NO_ENGINE_DIAGNOSTIC naming the missing dependency.
Template suffix:
Unlike the Thymeleaf bridge (which always appends .html via the engine resolver's
suffix setting), mustache.java has no resolver-suffix concept — the literal template name
is what factory.compile(...) sees. The
templateSuffix(...) builder knob fills the gap: when
non-blank, the bridge appends the configured suffix to template names that don't already end
with it (idempotent), so callers can write MustacheView.of("hello") or request
/mustache/hello and have it resolve to hello.mustache on the classpath.
Multiple base paths:
A host with /templates/ and /admin/templates/ template trees registers two
MustacheMixin beans, each mounted via a subclass declaring its own op-level
@RestGet(path=...) override and its own basePath. See the
MustacheMixin_MockRest_Test test in juneau-integration-tests for the canonical
pattern.
OpenAPI surface:
The greedy /* handler is not API-meaningful and is excluded from generated
Swagger / OpenAPI specs via @OpSwagger(ignore=true).
See Also:
- Since:
- 10.0.0
-
Nested Class Summary
Nested Classes -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final StringDefault base path applied when noMustacheMixin.Builder.basePath(String)call has been made.static final booleanDefault cache-templates setting —true(cache forever; production-safe).static final StringDefault template suffix — empty (literal template names, no implicit suffix). -
Constructor Summary
ConstructorsModifierConstructorDescriptionNo-arg constructor — usesDEFAULT_BASE_PATHas the base path andDEFAULT_TEMPLATE_SUFFIXfor the template suffix.protectedMustacheMixin(MustacheMixin.Builder builder) Builder constructor. -
Method Summary
Modifier and TypeMethodDescriptionapplyTemplateSuffix(String name) AppendsgetTemplateSuffix()tonameif not already present (idempotent).static MustacheMixin.Buildercreate()Creates a new builder.Returns the base path under which template resources are resolved.Returns the configured template-name suffix.booleanReturns whether the bridge's default factory caches compiled templates.voidrender(String path, RestRequest req, RestResponse res) [GET /mustache/*] — render a raw template through the Mustache engine.com.github.mustachejava.MustacheFactoryResolves the activeMustacheFactoryvia the sharedMustacheDispatcherworker.
-
Field Details
-
DEFAULT_BASE_PATH
Default base path applied when noMustacheMixin.Builder.basePath(String)call has been made.- See Also:
-
DEFAULT_TEMPLATE_SUFFIX
Default template suffix — empty (literal template names, no implicit suffix).- See Also:
-
DEFAULT_CACHE_TEMPLATES
Default cache-templates setting —true(cache forever; production-safe).- See Also:
-
-
Constructor Details
-
MustacheMixin
public MustacheMixin()No-arg constructor — usesDEFAULT_BASE_PATHas the base path andDEFAULT_TEMPLATE_SUFFIXfor the template suffix.The mixin walk falls back to this constructor when the
BeanStoredoes not have a registeredMustacheMixinbean. -
MustacheMixin
Builder constructor.- Parameters:
builder- The builder. Must not benull.
-
-
Method Details
-
create
Creates a new builder.- Returns:
- A new builder.
-
getBasePath
Returns the base path under which template resources are resolved.- Returns:
- The base path. Never
null.
-
getTemplateSuffix
Returns the configured template-name suffix.- Returns:
- The template suffix. Never
null.
-
isCacheTemplates
Returns whether the bridge's default factory caches compiled templates.- Returns:
- The cache flag. Defaults to
DEFAULT_CACHE_TEMPLATES.
-
applyTemplateSuffix
AppendsgetTemplateSuffix()tonameif not already present (idempotent).- Parameters:
name- The template name. Must not benull.- Returns:
- The template name with the configured suffix appended (if applicable).
-
resolveMustacheFactory
Resolves the activeMustacheFactoryvia the sharedMustacheDispatcherworker.- Parameters:
req- The current REST request.- Returns:
- The active Mustache factory. Never
null.
-
render
public void render(@Path("/*") String path, RestRequest req, RestResponse res) throws IOException, BasicHttpException [GET /mustache/*] — render a raw template through the Mustache engine.The
@Path("/*") String pathcaptures the multi-segment trailing remainder (e.g. a request for/mustache/about.mustachematches the mount withpath = "about.mustache"). Delegates to the sharedMustacheDispatcherworker (path-traversal hardening, suffix application, factory resolution, and render).Missing template surfaces as the engine's own
MustacheNotFoundException(HTTP 500 from the renderer's catch-all); missing engine surfaces asMustacheViewRenderer.NO_ENGINE_DIAGNOSTIC.- Parameters:
path- The trailing path segment after/mustache/(the template name relative to the configuredbase path; configured suffix appended if missing).req- The current REST request.res- The current REST response.- Throws:
IOException- If the underlying response writer fails.BasicHttpException- On boundary violation (403), missing engine (500), or render failure (500).
-