This package is an Otter Framework Module.
This module provides a mechanism to retrieve media and data depending on the host or a server-specific url.
ng add @o3r/dynamic-content
[!WARNING] This module requires @o3r/core to be installed.
In order to get your content from a different location than where your application is hosted, you may use the O3rDynamicContentPipe
or DynamicContentService
from @o3r/dynamic-content
.
import {O3rDynamicContentPipe} from '@o3r/dynamic-content';
@Component({
...
imports: [O3rDynamicContentPipe, ...]
})
export class MyComponent {}
<img src="{{'assets-otter/imgs/logo.png' | o3rDynamicContent}}" /> or
<img [src]="'assets-otter/imgs/logo.png' | o3rDynamicContent" />
@Component({
/* ... */
})
export class MyComponent {
public readonly imgSrc = inject(DynamicContentService).getMediaPath('assets/assets-otter/imgs/logo.png');
}
<img [src]="imgSrc" />
In both examples above, the result will be the same.
By default, both the service and the pipe will concatenate the assets path with a root path injected in the application. By default, the application will try to find the value of the data tag data-dynamiccontentpath
in the body. Example:
<body data-dynamiccontentpath="/cdn/myApp/">
</body>
If no tag is present, it defaults to empty string ''
.
In order to change the default behavior, you can specify a configuration:
Example :import {provideDynamicContent, withBasePath} from '@o3r/dynamic-content';
export const appConfig: ApplicationConfig = {
providers: [
// ...
provideDynamicContent(withBasePath('a-different-path/'))
]
};
If you need an external dependency to get the rootpath, you may use need to provide a function.
Example :import {provideDynamicContent, withBasePath} from '@o3r/dynamic-content';
export function myContentPath() {
return 'a-different-path/';
}
export const appConfig: ApplicationConfig = {
providers: [
// ...
provideDynamicContent(withBasePath(myContentPath))
]
};
For non-media resources (ex: localization, configuration) one should refer to the getContentPath
method of the DynamicContentService
. Doing so will ensure the correct resource path is computed in any environment (e.g. when the data-dynamiccontentpath
tag is present in the body).
The content path is always related to the root of the application.
It also ignores any path overrides from the AssetPathOverrideStore
store, meaning that you will always get the same file.
import {from, type Observable} from 'rxjs';
import {shareReplay, switchMap} from 'rxjs/operators';
@Component({
/** */
})
export class MyComponent {
public dynamicConfig$: Observable<Response> = inject(DynamicContentService).getContentPathStream('global.config.post.json').pipe(
switchMap((filePath) => from(fetch(filePath))),
shareReplay({ bufferSize: 1, refCount: true })
);
}
This method allows to access all media resources: meaning any resource that is INSIDE the media folder. The assets path needs to be relative to the media folder. Example:
Example :@Component({
/** */
})
export class MyComponent {
private readonly dynamicContentService = inject(DynamicContentService);
async getDynamicConfig() {
const filePath = await firstValueFrom(this.service.getMediaPathStream('imgs/my-image.png'));
const fileContent = await fetch(filePath);
// ...
}
}
It also looks for overrides in the AssetPathOverrideStore
, so it will return the new value instead if an override is found.
A dedicated store is available in case you want to override any media path. This store contains a mapping between the current file path and the one that should be used instead.
This override ONLY WORKS for media resources.