Getting started with Crema
Crema is Kona’s server-side view engine. You write templates under src/main/resources/views, pass a data map from a controller, and Crema expands @ directives and {{ }} echoes into HTML. Templates use the extensions *.crema.html or *.crema.kt (plain text with the same directive syntax).
Crema was inspired by familiar server-side template menus; everything after this sentence describes Crema on its own terms.
What a view is
Section titled “What a view is”A view is a named template plus the data used to render it. The name is dotted (home, posts.show) and maps to a file path under the views root (home.crema.html, posts/show.crema.html). After boot, the view helper resolves that name through the app-bound engine and returns a View (or an HTML Response).
Typical request path:
- A route hits a controller method.
- The controller calls
view("welcome", …)(Kotlin) orViews.make("welcome", …)(Java). - Crema loads the template, runs directives, escapes echoes, and returns HTML via
toResponse().
Scaffolding
Section titled “Scaffolding”kona new (default web kit) already registers CremaServiceProvider and ships a welcome view. Add more templates with grind:
./grind make:view home./grind make:view posts.showThat creates src/main/resources/views/home.crema.html and src/main/resources/views/posts/show.crema.html.
Minimal template
Section titled “Minimal template”{{-- src/main/resources/views/home.crema.html --}}<h1>Hello {{ name }}</h1>{{ name }} prints the name entry from the data map with HTML escaping. Missing or null values become an empty string.
Render from a controller
Section titled “Render from a controller”Register CremaServiceProvider (the web scaffold does this) and boot the app. Then use the view helper:
import org.konaframework.crema.viewimport org.konaframework.http.Requestimport org.konaframework.http.Response
class WelcomeController { fun index(request: Request): Response = view("welcome", mapOf("name" to "Kona")).toResponse()}import org.konaframework.crema.Views;import org.konaframework.http.Request;import org.konaframework.http.Response;import java.util.Map;
public final class WelcomeController { public Response index(Request request) { return Views.make("welcome", Map.of("name", "Kona")).toResponse(); }}Full factory API (share, first, existence, Java/Kotlin tables): View helper.
View paths and config
Section titled “View paths and config”| Setting | Behavior |
|---|---|
| Default root | {basePath}/src/main/resources/views |
| Fallbacks | build/resources/main/views, then legacy resources/views |
| Override | Config key view.path (absolute or app-relative path) |
Dotted names become path segments: mail.orders.shipped → mail/orders/shipped.crema.html. Crema tries .crema.html first, then .crema.kt.
Data the engine looks for
Section titled “Data the engine looks for”Some directives read conventional keys from the same data map (or a child context). You pass them from the controller or middleware:
| Key | Used by |
|---|---|
_token / csrf_token |
@csrf |
asset_url / assetUrl |
@asset base prefix |
__authenticated, auth_user, user |
@auth / @guest |
__abilities or can |
@can / @cannot |
errors |
@error('field') |
lang |
@lang overrides before Lang.get |
Directive menu
Section titled “Directive menu”| Area | Directives |
|---|---|
| Echoes | {{ }}, {!! !!}, @@, {{-- --}} |
| Layouts | @extends, @section / @endsection / @show, @yield, @parent, @hasSection, @sectionMissing |
| Stacks | @push / @endpush, @prepend / @endprepend, @stack |
| Includes | @include, @includeIf, @includeWhen, @includeUnless, @includeFirst, @once, @verbatim |
| Conditionals | @if / @elseif / @else / @endif, @unless, @isset, @empty |
| Loops | @while, @foreach / @each / @for, @forelse, loop.* |
| Auth | @auth, @guest, @can, @cannot |
| Switch | @switch / @case / @break / @default / @endswitch |
| Components | @component / @slot, <x-*>, <x-slot> |
| Helpers | @json, @csrf, @method, @asset, @lang, @vite, @error |
Full tables: Directive reference.
Related surfaces
Section titled “Related surfaces”- Brew — reactive components that render Crema templates and keep the browser in sync.
- Inertia — optional root Crema view that hosts a client-side page app.
- Vite / assets — bundling; Crema’s
@vitehelper emits thin script/link tags.
Next steps
Section titled “Next steps”- View helper —
view()/Views, share,first, responses - Rendering & data — echoes, escaping, expressions,
@json,@lang - Layouts & inheritance —
@extends, sections,@yield,@parent - Components & slots — reusable views, named slots,
<x-*>tags - Control structures — conditionals, loops, auth
- Includes & partials — shared fragments
- Stacks — scripts and styles
- Forms — CSRF, method spoofing, field errors