Views

AdonisJs makes use Edge.js as the templating engine, which is blazing fast and comes with an elegant API to create dynamic views.

Under the hood, Edge supports.

  1. Layouts & partials

  2. Components

  3. Runtime debugging using chrome dev tools

  4. Logical tags and everything in between.

Basic example

Let’s start with the basic example of saying Hello world by rendering an edge template. All of the views are stored inside resources/views directory and ends with .edge extension.

Make sure that the ViewProvider is registered as a provider inside start/app.js file.

+

const providers = [
  '@adonisjs/framework/providers/ViewProvider'
]

As always you can use the adonis command to create the view.

adonis make:view home

Output

✔ create  resources/views/home.edge

So let’s create a route to render the home.edge view.

Route.get('/', ({ view }) => {
  return view.render('home')
})

The view.render method takes the relative path to the view file. There is no need to type .edge extension, since that is obvious.

Also, you can render views from the sub folders with dot notation.

// file path - users/list.edge

view.render('users.list')

Request information

All views have access to the current request object, and you can call request methods inside your templates as well.

The request URL is {{ request.url() }}

Also, there is a helper to get the URL.

The request URL is {{ url }}

Globals

All of the edge.js globals are supported as it is. Here is the list of globals specific to AdonisJs only.

css

Add link tag to a CSS file. The file name should be relative from the public directory.

{{ css('style') }}

Or

{{ css('https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css') }}

script

Adds a script tag to the document

{{ script('app') }}

assetsUrl

Returns path of a file relative from the public directory.

<img src="{{ assetsUrl('logo.png') }}" />

route

Get actual URL for a route

Expecting the route to be registered as following

Route.get('users/:id', 'UserController.show').as('profile')
<a href="{{ route('profile', { id: 1 }) }}">
  View profile
</a>

Also, you can use the controller method name.

<a href="{{ route('UserController.show', { id: 1 }) }}">
  View profile
</a>

url

The current request url

The request URL is {{ url }}

auth

If you are using the auth provider, then you can access the current logged in user using the auth object.

{{ auth.user }}

csrfField

If you are using the shield middleware, you can access the csrfToken and field using one of the following methods.

{{ csrfToken }}
{{ csrfField() }}

Outputs

<input type="hidden" name="_csrf" value="..." />

cspMeta

When using shield middleware, the CSP headers are set automatically. However can also set them using HTML meta tag.

<head>
  {{ cspMeta() }}
</head>

Tags

Tags are building blocks for edge templates. For example: @if, @each all are the tags shipped with the edge by default.

Also, edge exposes a very powerful API to add new tags to it. Here is a list of the tags specific to AdonisJs only.

loggedIn

The loggedIn tag allows you to write if/else clause around the logged in user. For example:

@loggedIn
  <h2> You are logged in </h2>
@else
  <p> <a href="/login">Click here</a> to login </p>
@endloggedIn

Everything inside @loggedIn tag gets executed when the user is logged in.

inlineSvg

Render an SVG file inline inside the HTML. The tag expects the relative path to the file from the public directory.

<a href="/login">
  @inlineSvg('lock')
  Login
</a>

Templating

The templating syntax is same as the Edge. So make sure to read the edge documentation.

Extending views

You can also extend views by adding your view globals or tags. Globals and tags should only be added once, so make sure to use the start/hooks.js file to extend views.

Globals

const { hooks } = require('@adonisjs/ignitor')

hooks.after.providersBooted(() => {
  const View = use('View')

  View.global('currentTime', function () {
    return new Date().getTime()
  })
})

Above global returns the current time when you reference it inside the views.

{{ currentTime() }}

Of course, you can extract the code inside providersBooted to a different file and require it.

Globals scope

The value of this inside globals closure is bound to the view context so that you can access runtime values from it.

View.global('button', function (text) {
  return this.safe(`<button type="submit"> ${text} </button>`)
})

The safe method makes sure that returned HTML is not escaped.

To use other global methods or values, make use of the this.resolve method.

View.global('messages', {
  success: 'This is a success message',
  warning: 'This is a warning message'
})

View.global('getMessage', function (type) {
  const message = this.resolve('messages')
  return messages[type]
})
{{ getMessage('success') }}

Tags

The tags are registered the same way as globals inside start/hooks.js file. Learn more about tags from the Edge docs.

const { hooks } = require('@adonisjs/ignitor')

hooks.after.providersBooted(() => {
  const View = use('View')

  class MyTag extends View.engine.BaseTag {
  }

  View.engine.tag(new MyTag())
})

Runtime values

Quite often you want to share request specific values with your views, and same can be done by creating a middleware and sharing locals.

class SomeMiddleware {

  async handle ({ view }, next) {
    view.share({
      apiVersion: request.input('version')
    })

    await next()
  }
}

Moreover, inside your views, you can access it like any other value

{{ apiVersion }}

Syntax highlighting

The plugins for the following editors are available to get syntax highlighting support for Edge.

  1. For Sublime text.

  2. For Atom.

  3. For Vscode.