From 06bd9581778ad435e9f39c20ed54af9d9be4a8ec Mon Sep 17 00:00:00 2001 From: Taras Date: Thu, 15 Sep 2022 15:08:56 -0400 Subject: [PATCH] Add some minimal documentation on how to use the PlaceholderProcessor Signed-off-by: Taras --- .../software-templates/writing-templates.md | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/docs/features/software-templates/writing-templates.md b/docs/features/software-templates/writing-templates.md index a1cd50f271..2ce7c27bc1 100644 --- a/docs/features/software-templates/writing-templates.md +++ b/docs/features/software-templates/writing-templates.md @@ -581,3 +581,96 @@ 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 + } + } + }, + );` +```