Components
Components allows you to split the application UI into reusable pieces with isolated state. You can use components to define layouts or create a collection of different UI elements.
Before we talk more about components, let's understand how they differ from components in the frontend ecosystem.
-
No reactivity: Since Edge is a backend template engine, there is no concept of reactivity in Edge or its components layer.
-
No support CSS or frontend JavaScript: Edge templates are not processed using build tools. Therefore we do not process inline CSS or create frontend bundles.
Creating components
Components are regular Edge templates created with the purpose of reuse. Components can access additional runtime properties like $props and $slots, which are unavailable to other Edge templates.
We recommend you create components inside the components directory of your template's root path. This helps create a visual boundary between the components and the rest of the templates used by your application.
Let's start by creating a button component. We will store it inside the components/button.edge file.
<button type="{{ type || 'submit' }}"> {{ text }} </button>
Using components
You must use the @component tag to render a component inside your templates. The component tag accepts the template path as the first parameter and props as the second parameter.
<form>
@!component('components/button', { text: 'Login' })
@!component('components/button', { text: 'Cancel', type: 'reset' })
</form>
Output
<form>
<button type="submit"> Login </button>
<button type="reset"> Cancel </button>
</form>
Components from named disks can be referenced by prefixing the disk name.
@!component('uikit::components/button', { text: 'Login' })
Passing props
The component props are passed as the second parameter using the @component tag. Props are always represented as an object, and you can access them inside the component's template using the object property name.
See also: Props reference
@component('components/button', {
type: 'submit',
class: 'btn btn-large',
text: 'Login'
})
{{ type }}
{{ class }}
{{ text }}
Another way to access props is using the $props property. For example:
{{ $props.get('type') }}
{{ $props.get('class') }}
{{ $props.get('text') }}
Using Slots
Slots are named outlets with markup inside them. Since writing HTML markup within props can quickly become messy, the slots provide a better authoring experience.
In the following example, we render the contents of the main slots using the $slots.main function.
See also: Slots reference
<button {{ $props.toAttrs() }}>
{{{ await $slots.main() }}}
</button>
The contents of the main slot are place between the opening and the closing tags.
@component('components/button', {
class: ['flex', 'align-center', 'space-x-4']
})
<i class="fa-lock"></i>
<span> Login </span>
@end
Components as tags
Edge allows you to reference components as tags. So, instead of using the @component tag, you can use the component filename as the tag name to render it.
Components as tags only work for components stored inside the components directory.
<div class="modal">
<header>
{{{ await $slots.header() }}}
</header>
<main>
{{{ await $slots.content() }}}
</main>
<footer>
{{{ await $slots.footer() }}}
</footer>
</div>
Given the above template is stored inside the modal.edge file, you can render it as follows.
@modal()
@slot('header')
<h2> Delete post </h2>
@end
@slot('content')
<p> You are about to delete the post permanently </p>
@end
@slot('footer')
<button> Yes, delete it </button>
<button> Cancel </button>
@end
@end
You can reference components as tags from named disks by prefixing the disk name with a dot separator.
{{-- Component as a tag from the uikit disk --}}
@!uikit.input()
{{-- Via component tag --}}
@!component('uikit::input')
Filename to tagName conversion
You can reference the files stored within the components directory as tags inside your edge templates. The following transformation rules are applied when creating a tag from the file name.
| Template path | Tag name |
|---|---|
form/input.edge | @form.input |
tool_tip.edge | @toolTip |
checkout_form/input.edge | @checkoutForm.input |
modal/index.edge | @modal |