View Structure and Component-Based Layouts

In this lesson, we'll get our view and component structures set up. Then, we'll take an abnormal approach and cover how to use components for your layouts.

Published
Oct 21, 23
Duration
4m 32s

Developer, dog lover, and burrito eater. Currently teaching AdonisJS, a fully featured NodeJS framework, and running Adocasts where I post new lessons weekly. Professionally, I work with JavaScript, .Net C#, and SQL Server.

Adocasts

Burlington, KY

Let’s take a brief moment to get our view structure prepared for the various pages and components we’ll be building in this series. Then, to keep with the component theme of this series, we’ll learn how we can utilize components for layouts instead of the traditional EdgeJS Layout approach.

Organizing Our Views

First, let’s move our welcome page into a separate directory called “pages” within our views directory.

mv resources/views/welcome.edge resources/views/pages/welcome.edge
Copied!

Next, let’s move into our start/routes.ts file to update the path for this page.

Route.get('/', async ({ view }) => {
  return view.render('welcome')
  return view.render('pages/welcome')
})
Copied!
  • start
  • routes.ts

Cool, so we should be good there. From now on when we create a page, we’ll be creating it within resources/view/pages to help keep our pages separated from everything else.

Using Components for Layouts

For our layout, we’re going to do something a little bit different. Since we’re focusing on components within this series, we’re not going to use a typical layout for our layout. Instead, we’ll be creating a component to serve as our layout.

First, let’s create a components directory inside the views directory.

mkdir resources/views/components
Copied!

Then, within the components directory, we’ll create a subdirectory called layouts with a file inside it called app.edge. This app.edge file will serve as our application’s layout.

mkdir resources/views/components/layouts
touch resources/views/components/layouts/app.edge
Copied!

Creating Our Layout Component

Let’s then copy all the markup within our welcome.edge page and paste it into our new app.edge layout file.

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  @entryPointStyles('app')
</head>
<body>
  <h1 
    x-data="{ text: 'Hello world!' }" 
    x-text="text"
    class="text-3xl font-bold underline text-red-500">
  </h1>
</body>
</html>
Copied!
  • resources
  • views
  • components
  • layouts
  • app.edge

For the actual body content, let’s replace our test h1 with the below.

<div class="max-w-4xl mx-auto my-8">
  <header class="bg-gray-100 p-6 -mx-6 mb-6 rounded-md">
    @if (title != 'Home')
      <a href="/" class="text-xs">Home</a>
    @endif
    <h1 class="text-2xl font-bold">{{ title }}</h1>
  </header>

  <main>
    {{{ await $slots.main() }}}
  </main>
</div>
Copied!
  • resources
  • views
  • components
  • layouts
  • app.edge

First, we’re accepting a single prop to this component called title.

Within our header, we have a simple check that will display a breadcrumb back to the home page if the title does not equal “Home”.

Then, we’ll display the provided title prop within an h1.

Lastly, we’ll render our main slot content inside a main element.

The main slot is always going to be provided even if you don’t provide any content into the component’s slot. So, we don’t need to worry about this being undefined or null here. The three curly braces as opposed to the two curly braces allows us to plop raw HTML into the page, which is exactly what we’ll need to do for slots.

Using Our Layout Component

Our layout is now set up and ready to go, let’s now dive back into our welcome.edge page and get rid of everything inside of here so we’re left with an empty file.

To actually make use of our layout component we have a couple of options. First, we could use the component tag.

@component('components/layouts/app', { title: 'Home' })

  <h1>Page contents here</h1>

@endcomponent
Copied!
  • resources
  • views
  • welcome.edge

This, though verbose, will work just fine. However, we have a shorthand readily available to use since we strategically placed our components directory directly inside our views directory. AdonisJS will automatically register EdgeJS files placed within resources/views/components as direct tags, meaning we can do the below.

@layouts.app({ title: 'Home' })

  <h1>Page contents here</h1>

@end
Copied!
  • resources
  • views
  • welcome.edge

We can now reach directly for our layouts directory as a tag, via @layouts, then we can reach inside this folder using a dot, and finally specify the file name of the component we want to use.

Here are a couple more examples of component-to-tag name conversions.

@!component('components/pagination')
@!pagination()

@!component('components/menu_bar')
@!menuBar()

@!component('components/tab/data')
@!tab.data()

@!component('components/text/animation/drop_in')
@!text.animation.dropIn()
Copied!

Join The Discussion! (0 Comments)

Please sign in or sign up for free to join in on the dicussion.

robot comment bubble

Be the first to Comment!