Edge Templates
Gate template markup on feature flags with Edge tags and the flick global.
Flick integrates with Edge, the AdonisJS templating engine, so you can render markup conditionally based on a feature's state. The same scope and resolution rules from Resolving Features apply: every check needs a scope, and the resolved value is coerced to a boolean for the active/inactive tags.
The Edge integration is optional. It registers itself automatically when your application uses Edge, so there is nothing to configure. If Edge is not installed, Flick simply skips the integration.
Passing the scope
Tags and the global never assume a scope for you. You pass it explicitly, exactly like in TypeScript. In an HTTP view that is usually the authenticated user, which you share with the template from your controller:
return view.render("checkout", { user: auth.user });The examples below assume user is available in the template.
The @feature tag
@feature(feature, scope) renders its block when the feature resolves to a truthy value:
@feature('new_checkout', user)
@include('checkout/new')
@endAdd an @else branch to render fallback markup when the feature is inactive:
@feature('new_checkout', user)
@include('checkout/new')
@else
@include('checkout/legacy')
@endThe @featureInactive tag
@featureInactive(feature, scope) is the inverse. It renders its block when the feature resolves to a falsy value, which reads better than an empty @feature with only an @else:
@featureInactive('beta_program', user)
<a href="/beta/join">Join the beta</a>
@endBoth tags coerce the resolved value to a boolean, following the same rule as
isActive: any truthy value is active, and false, 0, '', null, or
undefined are inactive. To branch on a specific variant value, read it
with the flick global instead.
The flick global
Flick also exposes the service as a flick global, so the full resolver API is available inside templates. Because resolution is asynchronous, remember to await it.
Use it with Edge's native @if when you need @elseif chains or a condition the tags do not cover:
@if(await flick.for(user).isActive('new_checkout'))
@include('checkout/new')
@elseif(await flick.for(user).isActive('legacy_checkout'))
@include('checkout/legacy')
@else
@include('checkout/default')
@endRead a variant value with an interpolation:
<button class="btn-{{ await flick.for(user).value('checkout_button_color') }}">
Checkout
</button>Registering the plugin manually
The provider registers the plugin for you. If you manage your own Edge instance, or want to register it explicitly, import the plugin and pass it the Flick service:
import edge from "edge.js";
import flick from "@foadonis/flick/services/main";
import { edgePluginFlick } from "@foadonis/flick/plugins/edge";
edge.use(edgePluginFlick(flick));