Honovel Honovel Deno

Views in Honovel

Views in Honovel are powered by Edge.js, a modern template engine that provides an elegant syntax for building HTML pages. Edge allows you to create reusable layouts, components, and partials, making your frontend development clean and maintainable.

Creating Views

You can create views manually or use the CLI:

deno task smelt make:view pages/about

This creates a view file at resources/views/pages/about.edge.

Basic View Syntax

Edge templates use a simple, intuitive syntax with curly braces for output:

<h1>Hello, {{ $username }}</h1>
<p>The current time is {{ $date }}</p>

Returning Views from Controllers

Use the global view() function to return views from your controllers:

import Controller from "App/Http/Controllers/Controller.ts";

export default class PageController extends Controller {
    public async index({ request }) {
        return view("welcome"); // Returns resources/views/welcome.edge
    }

    public async about({ request }) {
        return view("pages.about", {
            title: "About Us",
            company: "Honovel"
        });
    }
}

Using Layouts

Layouts help you create consistent page structures. Define a layout and extend it in your views:

Layout file: resources/views/components/layouts/main.edge

<!DOCTYPE html>
<html>
<head>
    <title>{{ $title ?? 'Honovel App' }}</title>
</head>
<body>
    @!slot('content')
</body>
</html>

View file using the layout:

@layouts.main()

@slot('content')
    <h1>Welcome to Honovel</h1>
    <p>This content is inside the layout.</p>
@end

@endlayouts.main

Conditionals and Loops

Edge supports conditional statements and loops:

@if($user)
    <p>Welcome back, {{ $user.name }}!</p>
@else
    <p>Please log in.</p>
@end

@each($item in $items)
    <li>{{ $item.name }}</li>
@end

Components

Create reusable components in resources/views/components/:

Component file: resources/views/components/button.edge

<button class="btn btn-{{ $type ?? 'primary' }}">
    {{ $text }}
</button>

Using the component:

@component('components/button', { type: 'success', text: 'Click Me' })

Passing Data to Views

Pass data as a second argument to the view() function:

public async show({ request }, {id}) {
    const user = await User.find(id);
    
    return view("users/profile", {
        user: user,
        title: `${user.name}'s Profile`,
        posts: await user.posts().get()
    });
}

Edge Template Features

  • Includes: @include('partials/header')
  • Partials: Reusable template fragments
  • Slots: Named content sections in layouts
  • Escaping: {{ }} auto-escapes, {{{ }}} for raw output
  • Comments: {{-- This is a comment --}}

View Helpers

Edge provides helpful functions you can use in templates:

<!-- URL/Route helpers -->
<a href="{{ route('users.show', { id: $user.id }) }}">View Profile</a>

<!-- Asset helpers -->
<img src="{{ asset('images/logo.png') }}" alt="Logo">

<!-- Session/Flash messages -->
@if(session().get('success'))
    <div class="alert success">{{ session().get('success') }}</div>
@end

Best Practices

  • Keep views focused on presentation logic only
  • Use layouts to maintain consistent page structure
  • Create components for reusable UI elements
  • Pass only the data needed by each view
  • Use partials to break down complex views

Next Steps

Combine views with routes and controllers to build complete web pages. For API responses, use response().json() instead of views.