Dynamic Layouts

What are best practices in order to have my aurelia app support very different layouts? I have read in other threads that maybe setRoot() should be used that routes the user but can anyone point me to a good example?

My use case:
1 main site structure (using viewports)
1 layout that is specific for dialogs, when I load a dialog via iframe I would like to enforce a stripped out layout structure

1 Like

As an alternative can I have some views use viewPorts (so pull page refresh doesnt occur) and some use layouts?

1 Like

What about having components with layouts or viewports as the root level views in the router with the pages that render with them as children?

1 Like

Can you expand or provide example? Trying to grasp the idea.

1 Like

See this sandbox with a router demo: https://codesandbox.io/s/mo6llw3xy9.

Notice that Home and Settings both have the same layout but profile uses a child router to render a slightly different layout. I imagine something like this (psuedo-code, wrote from memory, might not compile):

app.html

<template>
  <router-view></router-view>
</template>

app.js

export class App {
	router: Router;

	configureRouter(config: RouterConfiguration, router: Router): void {
		this.router = router;
		config.map([
			{ route: '', moduleId: PLATFORM.moduleName('layouts/default') },
			{ route: 'custom', moduleId: PLATFORM.moduleName('layouts/custom') },
		]);
	}
}

layouts/default.html

<template>
  <nav></nav>
  <h1>I am a layout with top nav</h1>
  <router-view></router-view>
</template>

layouts/default.ts

export class DefaultLayout {
	router: Router;

	configureRouter(config: RouterConfiguration, router: Router): void {
		this.router = router;
		config.map([
			{ route: '', moduleId: PLATFORM.moduleName('../pages/home') },
			{ route: 'about', moduleId: PLATFORM.moduleName('../pages/about') },
		]);
	}
}

layouts/custom.html

<template>
  <h1>I am a layout with bottom nav</h1>
  <router-view></router-view>
  <nav></nav>
</template>

layouts/default.ts

export class CustomLayout {
	router: Router;

	configureRouter(config: RouterConfiguration, router: Router): void {
		this.router = router;
		config.map([
			{ route: 'user', moduleId: PLATFORM.moduleName('../pages/user/profile') },
			{ route: 'admin', moduleId: PLATFORM.moduleName('../pages/admin/dashboard') },
		]);
	}
}

Usage:

The urls host.com/ and host.com/about will load the home and about pages in the default layout while host.com/custom/user and host.com/custom/admin will load the user and admin pages with the custom layout.


Another thought I had was just to create the layouts as components and wrap each page’s view with it. Something like:

about.html

<template>
  <default-template>
    <h1>About</h1>
  </default-template>
</template>

user.html

<template>
  <custom-template>
    <h1>User</h1>
  </custom-template>
</template>

You could probably also achieve this with decorators.

1 Like

While I was confirming my syntax just now in the docs I came across this that I never noticed: https://aurelia.io/docs/routing/configuration#layouts. Should also achieve the same purpose.

1 Like