Skip to content

Commit

Permalink
docs(router): for aurelia#1338, aurelia#1339
Browse files Browse the repository at this point in the history
  • Loading branch information
Sayan751 committed Mar 3, 2022
1 parent a934ee8 commit dfe0359
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 11 deletions.
163 changes: 154 additions & 9 deletions docs/user-docs/developer-guides/routing/common-routing-tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,152 @@ The `active` property is a boolean value that we bind to. In this example, we us
You do not need to explicitly declare this property in your view model since it is a from-view binding. The underscore prefix of \_settings has no special meaning to the framework, it is just a common convention for private properties which can make sense for properties that are not explicitly declared in the view model.
{% endhint %}

## Setting The Title
## Setting the title

You can set the title while you are configuring the routes.
The title can be configured in the root level, as well as in the individual route level.
This can be seen in the following example using the `@route` decorator.

```typescript
import { route, IRouteViewModel } from '@aurelia/router';

@route({
title: 'Aurelia', // <-- this is the base title
routes: [
{
path: ['', 'home'],
component: import('./components/home-page'),
title: 'Home',
}
]
})
export class MyApp implements IRouteViewModel {}
```

If you prefer using the static `routes` property, the title can be set using a static `title` property in the class.
The following example has exactly the same effect as of the previous example.

```typescript
import { IRouteViewModel, Routeable } from "aurelia";

export class MyApp implements IRouteViewModel {
static title: string = 'Aurelia'; // <-- this is the base title
static routes: Routeable[] = [
{
path: ['', 'home'],
component: import('./components/home-page'),
title: 'Home',
}
];
}
```

With this configuration in place, the default-built title will be `Home | Aurelia` when user is navigated to `/` or `/home` route. That is the titles of the child routes precedes the base title.

### Customizing the title

Using the `buildTitle` method from the router customization the default title-building logic can overwritten.

```typescript
// main.ts
import { RouterConfiguration, Transition } from '@aurelia/router';
import { Aurelia } from '@aurelia/runtime-html';

const au = new Aurelia();
au.register(
RouterConfiguration.customize({
buildTitle(tr: Transition) {
const root = tr.routeTree.root;
const baseTitle = root.context.definition.config.title;
const titlePart = root.children.map(c => c.title).join(' - ');
return `${baseTitle} - ${titlePart}`;
},
}),
);
```

This customization in conjunction with the previously shown routing configuration will cause the title to be `Aurelia - Home` when user is navigated to `/` or `/home` route.

### Translating the title

When localizing your app, you would also like to translate the title.
Note that the router does not facilitate the translation by itself.
However, there are enough hooks that can be leveraged to translate the title.
To this end, we would use the `data` property in the route configuration to store the i18n key.

```typescript
import { IRouteViewModel, Routeable } from "aurelia";

export class MyApp implements IRouteViewModel {
static title: string = 'Aurelia';
static routes: Routeable[] = [
{
path: ['', 'home'],
component: import('./components/home-page'),
title: 'Home',
data: {
i18n: 'routes.home'
}
}
];
}
```

Loosely speaking, `data` is an object of type `Record<string, string>`.
Therefore you are free to chose the property names inside the `data` object.
Here we are using the `i18n` property to store the i18n key for individual routes.

In the next step we make use of the `buildTitle` customization as well as a `AppTask` hook to subscribe to the locale change event.

```typescript
import { I18N, Signals } from '@aurelia/i18n';
import { IEventAggregator } from '@aurelia/kernel';
import { IRouter, RouterConfiguration, Transition } from '@aurelia/router';
import { AppTask, Aurelia } from '@aurelia/runtime-html';

(async function () {
const host = document.querySelector<HTMLElement>('app');

const au = new Aurelia();
const container = au.container;
let i18n: I18N | null = null;
let router: IRouter | null = null;
au.register(
// other registrations such as the StandardRegistration, I18NRegistrations come here
RouterConfiguration.customize({
buildTitle(tr: Transition) {
// Use the I18N to translate the titles using the keys from data.i18n.
i18n ??= container.get(I18N);
const baseTitle = root.context.definition.config.title;
const child = tr.routeTree.root.children[0];
return `${baseTitle} - ${i18n.tr(child.data.i18n)}`;
},
}),
AppTask.afterActivate(IEventAggregator, ea => {
// Ensure that the title changes whenever the locale is changed.
ea.subscribe(Signals.I18N_EA_CHANNEL, () => {
(router ??= container.get(IRouter)).updateTitle();
});
}),
);

// start aurelia here

})().catch(console.error);
```

This infra in conjunction in conjunction with the previously shown routing configuration will cause the title to be `Aurelia - Startseite` when user is navigated to `/` or `/home` route and the current locale is `de`.
Here we are assuming that the i18n resource for the `de` locale contains the following.

```json
{
"routes": {
"home": "Startseite"
}
}
```

### Setting the title from component

While you would in many cases set the title of a route in your route configuration object using the `title` property, sometimes you want the ability to specify the title property from within the routed component itself.

Expand All @@ -50,15 +195,15 @@ We went over creating routes with support for parameters in the creating routes
```typescript
@route({
routes: [
{
id: 'home',
path: '',
component: import('./home'),
title: 'Home'
{
id: 'home',
path: '',
component: import('./home'),
title: 'Home'
},
{
path: 'product/:id',
component: import('./product'),
{
path: 'product/:id',
component: import('./product'),
title: 'Product',
data: {
requiresAuth: false
Expand Down
3 changes: 2 additions & 1 deletion docs/user-docs/developer-guides/routing/navigating.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,11 @@ And where things really start to get interesting is when you want to pass parame
<a load="route:profile; params.bind:{name: 'rob'}">View Profile</a>
```

In the above example, we provide the route value. But, then also provide an object of parameters. These parameter values correspond to any parameters configured in your route definition. In our case, our route looks like this:
In the above example, we provide the route (`id`) value. But, then also provide an object of parameters. These parameter values correspond to any parameters configured in your route definition. In our case, our route looks like this:

```typescript
{
id: 'profile',
path: 'profile/:name',
component: () => import('./view-profile'),
title: 'View Profile'
Expand Down
2 changes: 1 addition & 1 deletion packages/router/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -908,7 +908,7 @@ export class Router {
}
}

private updateTitle(tr: Transition): string {
public updateTitle(tr: Transition = this.currentTr): string {
const title = this.hasTitleBuilder ? (this.options.buildTitle!(tr) ?? '') : this.getTitle(tr);
if (title.length > 0) {
this.p.document.title = title;
Expand Down

0 comments on commit dfe0359

Please sign in to comment.