@@ -581,96 +581,3 @@ output things. You can grab that output using `steps.$stepId.output.$property`.
|
||||
You can read more about all the `inputs` and `outputs` defined in the actions in
|
||||
code part of the `JSONSchema`, or you can read more about our
|
||||
[built in actions](./builtin-actions.md).
|
||||
|
||||
## Creating reusable templates
|
||||
|
||||
We can use the PlaceholderProcessor to create reusable portions of a template. A placeholder is a property on an entity object that starts with `$`. Backstage has some built in placeholders including `$text`, `$json` and `$yaml`. Each placeholder has a resolver. A resolver is an asyncronous function that receives the value assigned to the placeholder. A resolver is expected to return a promise that resolves to a value. The resolved value will replace the object where the placeholder was defined.
|
||||
|
||||
Let's say we want to reuse a portion of the template that asks user to specify a host name and we want to be able to add other fields to that form step.
|
||||
|
||||
```yaml
|
||||
apiVersion: scaffolder.backstage.io/v1beta3
|
||||
kind: Template
|
||||
metadata:
|
||||
name: v1beta3-demo
|
||||
title: Microservice example
|
||||
description: scaffolder v1beta3 template demo
|
||||
spec:
|
||||
owner: backstage/techdocs-core
|
||||
type: service
|
||||
parameters:
|
||||
- title: Specify a host
|
||||
parameters:
|
||||
name:
|
||||
title: Hostname
|
||||
type: string
|
||||
description: Specify host name
|
||||
```
|
||||
|
||||
Our placeholder is going to be called `$specifyHostname`. We'd use it like this,
|
||||
|
||||
```yaml
|
||||
apiVersion: scaffolder.backstage.io/v1beta3
|
||||
kind: Template
|
||||
metadata:
|
||||
name: v1beta3-demo
|
||||
title: Microservice example
|
||||
description: scaffolder v1beta3 template demo
|
||||
spec:
|
||||
owner: backstage/techdocs-core
|
||||
type: service
|
||||
parameters:
|
||||
- $specifyHostname:
|
||||
domainExt:
|
||||
name: Domain extension
|
||||
type: string
|
||||
description: Specify domain extension like .com, .ca, .co.uk or something else.
|
||||
```
|
||||
|
||||
The result after the placeholder is applied will look like this,
|
||||
|
||||
```yaml
|
||||
apiVersion: scaffolder.backstage.io/v1beta3
|
||||
kind: Template
|
||||
metadata:
|
||||
name: v1beta3-demo
|
||||
title: Microservice example
|
||||
description: scaffolder v1beta3 template demo
|
||||
spec:
|
||||
owner: backstage/techdocs-core
|
||||
type: service
|
||||
parameters:
|
||||
- title: Specify a host
|
||||
parameters:
|
||||
name:
|
||||
title: Hostname
|
||||
type: string
|
||||
description: Specify host name
|
||||
domainExt:
|
||||
name: Domain extension
|
||||
type: string
|
||||
description: Specify domain extension like .com, .ca, .co.uk or something else.
|
||||
```
|
||||
|
||||
To implement this, you have to modify the catalog plugin to create a `specifyHostname` resolver. In `/packages/backend/src/plugins/catalog.ts`. Add the following code,
|
||||
|
||||
```ts
|
||||
const builder = await CatalogBuilder.create(env);
|
||||
|
||||
builder.setPlaceholderResolver(
|
||||
'specifyHostname',
|
||||
async specifyHostnameResolver({ value }) => {
|
||||
return {
|
||||
"title": "Specify a host",
|
||||
"parameters": {
|
||||
"name": {
|
||||
"title": "Hostname",
|
||||
"type": "string",
|
||||
"description": "Specify host name"
|
||||
},
|
||||
...value
|
||||
}
|
||||
}
|
||||
},
|
||||
);`
|
||||
```
|
||||
|
||||
@@ -119,11 +119,6 @@ export class PlaceholderProcessor implements CatalogProcessor {
|
||||
return [data, false];
|
||||
}
|
||||
|
||||
// if (typeof resolverValue !== 'string') {
|
||||
// treat it as an argument to resolver function
|
||||
// TODO: make this recursive, but it should resolve from bottom up
|
||||
// }
|
||||
|
||||
const read = async (url: string): Promise<Buffer> => {
|
||||
if (this.options.reader.readUrl) {
|
||||
const response = await this.options.reader.readUrl(url);
|
||||
|
||||
Reference in New Issue
Block a user