Skip to content

Commit

Permalink
Merge pull request #19850 from abpframework/issue-19834
Browse files Browse the repository at this point in the history
Update title strategy service to get project name from localized text
  • Loading branch information
sumeyyeKurtulus authored May 17, 2024
2 parents 39f846a + d1c6055 commit 45531b3
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 29 deletions.
59 changes: 59 additions & 0 deletions docs/en/UI/Angular/Title-Strategy-Service.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Title Strategy For Angular

## **ABP has a default title strategy for Angular UI**.

This strategy is based on the title property. Provide a title property when setting a new route.

**Example**

```ts
{
path: 'customers',
component: CustomersComponent,
title: 'AbpCustomers::Roles'
},
```

- It is better to use localized text in the title property. It will be translated by **LocalizationService**.
- The **`title`** property is already set in **ABP internal packages**.

## How it looks

When you create a new route and provide a **`title`** property, it will look like this **`<title> | <projectName>`**

### What is `projectName` and How to Customize

- **`projectName`** is the name of your application. By default, ABP sets a [**`projectName`**](https://github.com/abpframework/abp/blob/f48f78618a326644843c01424b093f0d79448769/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/en.json#L4) for your application. This localization text is added for customization and can be changed for different languages.

### Disable `projectName`

- If you don't want to show **`projectName`** in the title, you can disable it.

**app.module.ts**

```ts
import { DISABLE_PROJECT_NAME } from '@abp/ng.core';

providers: [
...,
{ provide: DISABLE_PROJECT_NAME, useValue: true}
],
```

- Now only title will be shown.

## Override ABP's Default Title Strategy

**app.module.ts**

```ts
import { TitleStrategy } from '@angular/router';
import { YourCustomStrategy } from './title-strategy.service.ts';

providers: [
...,
{ provide: TitleStrategy, useExisting: YourCustomStrategy },
],
```

- You can check [Angular Documentation](https://angular.io/api/router/TitleStrategy) to write a custom **`TitleStrategy`**.
4 changes: 4 additions & 0 deletions docs/en/docs-nav.json
Original file line number Diff line number Diff line change
Expand Up @@ -1188,6 +1188,10 @@
{
"text": "Abp Window Service",
"path": "UI/Angular/Abp-Window-Service.md"
},
{
"text": "Title Strategy",
"path": "UI/Angular/Title-Strategy-Service.md"
}
]
},
Expand Down
17 changes: 10 additions & 7 deletions npm/ng-packs/packages/core/src/lib/core.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { ToInjectorPipe } from './pipes/to-injector.pipe';
import { CookieLanguageProvider } from './providers/cookie-language.provider';
import { LocaleProvider } from './providers/locale.provider';
import { LocalizationService } from './services/localization.service';
import { OTHERS_GROUP } from './tokens';
import { DISABLE_PROJECT_NAME, OTHERS_GROUP } from './tokens';
import { localizationContributor, LOCALIZATIONS } from './tokens/localization.token';
import { CORE_OPTIONS, coreOptionsFactory } from './tokens/options.token';
import { TENANT_KEY } from './tokens/tenant-key.token';
Expand All @@ -40,12 +40,11 @@ import { DefaultQueueManager } from './utils/queue';
import { IncludeLocalizationResourcesProvider } from './providers/include-localization-resources.provider';
import { SORT_COMPARE_FUNC, compareFuncFactory } from './tokens/compare-func.token';
import { AuthErrorFilterService } from './abstracts';
import { DYNAMIC_LAYOUTS_TOKEN } from "./tokens/dynamic-layout.token";
import { DEFAULT_DYNAMIC_LAYOUTS } from "./constants";
import { DYNAMIC_LAYOUTS_TOKEN } from './tokens/dynamic-layout.token';
import { DEFAULT_DYNAMIC_LAYOUTS } from './constants';
import { AbpTitleStrategy } from './services/title-strategy.service';
import { LocalStorageListenerService } from './services/local-storage-listener.service';


const standaloneDirectives = [
AutofocusDirective,
InputEventDebounceDirective,
Expand Down Expand Up @@ -201,12 +200,16 @@ export class CoreModule {
IncludeLocalizationResourcesProvider,
{
provide: DYNAMIC_LAYOUTS_TOKEN,
useValue: options.dynamicLayouts || DEFAULT_DYNAMIC_LAYOUTS
useValue: options.dynamicLayouts || DEFAULT_DYNAMIC_LAYOUTS,
},
{
provide: TitleStrategy,
useExisting: AbpTitleStrategy
}
useExisting: AbpTitleStrategy,
},
{
provide: DISABLE_PROJECT_NAME,
useValue: options.disableProjectNameInTitle || false,
},
],
};
}
Expand Down
1 change: 1 addition & 0 deletions npm/ng-packs/packages/core/src/lib/models/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export namespace ABP {
localizations?: Localization[];
othersGroup?: string;
dynamicLayouts?: Map<string, string>;
disableProjectNameInTitle?: boolean;
}

export interface Child {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,18 @@ import { Injectable, effect, inject } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
import { TitleStrategy, RouterStateSnapshot } from '@angular/router';
import { Title } from '@angular/platform-browser';
import { ConfigStateService } from './config-state.service';
import { LocalizationService } from './localization.service';
import { DISABLE_PROJECT_NAME } from '../tokens';

@Injectable({
providedIn: 'root',
})
export class AbpTitleStrategy extends TitleStrategy {
protected readonly title = inject(Title);
protected readonly configState = inject(ConfigStateService);
protected readonly localizationService = inject(LocalizationService);
protected readonly disableProjectName = inject(DISABLE_PROJECT_NAME, { optional: true });
protected routerState: RouterStateSnapshot;

projectName = toSignal(this.configState.getDeep$('localization.defaultResourceName'), {
initialValue: 'MyProjectName',
});
langugageChange = toSignal(this.localizationService.languageChange$);

constructor() {
Expand All @@ -30,14 +27,22 @@ export class AbpTitleStrategy extends TitleStrategy {

override updateTitle(routerState: RouterStateSnapshot) {
this.routerState = routerState;
let title = this.buildTitle(routerState);
const title = this.buildTitle(routerState);

const projectName = this.localizationService.instant({
key: '::AppName',
defaultValue: 'MyProjectName',
});

if (!title) {
this.title.setTitle(this.projectName());
return;
return this.title.setTitle(projectName);
}

let localizedText = this.localizationService.instant({ key: title, defaultValue: title });
if (!this.disableProjectName) {
localizedText += ` | ${projectName}`;
}

const localizedTitle = this.localizationService.instant({ key: title, defaultValue: title });
this.title.setTitle(`${localizedTitle} | ${this.projectName()}`);
this.title.setTitle(localizedText);
}
}
3 changes: 2 additions & 1 deletion npm/ng-packs/packages/core/src/lib/tokens/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ export * from './check-authentication-state';
export * from './http-context.token';
export * from './others-group.token';
export * from './tenant-not-found-by-name';
export * from './compare-func.token'
export * from './compare-func.token';
export * from './title-strategy-disable-project-name.token';
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { InjectionToken } from '@angular/core';

export const DISABLE_PROJECT_NAME = new InjectionToken<boolean>('DISABLE_APP_NAME');
22 changes: 11 additions & 11 deletions templates/module/angular/projects/dev-app/src/index.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>DevApp</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
<head>
<meta charset="utf-8" />
<title>MyProjectName</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
</head>
<body>
<app-root></app-root>
</body>
</html>

0 comments on commit 45531b3

Please sign in to comment.