Skip to main content

Prompting

What is a prompt

❯ tps react-component Nav
? Would you like to include unit tests? (true)

Prompting is a useful feature that allows you to obtain data from the user. By displaying a message on the command line, we can request a response from the user. Additionally, prompts can be answered by providing a flag via the command line or through the node module package, which is particularly helpful when users already know their desired input. The options for prompts can vary in various formats.

In our system, we utilize the inquirer library for prompting. This enables you to use any property available in inquirer when creating prompts. For more information on the available properties in inquirer, you can refer to the documentation here.

How to make a Prompt

To add prompts to your template, simply add a prompts property to your settings file, which should be an array consisting of the prompts you wish to present to the user. Each prompt will be represented as an object, with varying properties depending on the type of prompt.

settings.json
{
"prompts": [
/* prompts ... */
]
}
tip

Don't remember what the setting file is? Refresh your memory in the settings files guide

Now lets go over some of the basics. To get a full list of properties check out the Prompts API documentation

Name

Let's start with the name field. This field is essential for enabling prompting functionality. All of your prompt answers will be conveniently stored under the tps.answers object property.

settings.json
{
"prompts": [
{
"name": "<some-name>"
// ...
}
]
}

The name you provide to the prompt will be used in order to access the users answer.

{{= tps.answers["<name-of-prompt>"]}}
Example
settings.json
{
"prompts": [
{
"name": "age"
// ...
}
]
}

you can access the users answer with:

{{= tps.answers.age }}

Message

The second property is message. This property will tell inquirer what to ask the user when they are rendering a new instance.

settings.json
{
"prompts": [
{
"message": "<some-message>"
// ...
}
]
}
Example
settings.json
{
"prompts": [
{
"name": "unit",
"message": "Would you like to include unit tests?"
}
]
}

When the user renders a new instance they will see the message added in your prompt

❯ tps react-component Nav
? Would you like to include unit tests?

Type

The next property is type. This property will tell inquirer what type of prompting you would like to use. You can see more about this property in the inquirer question docs.

settings.json
{
"prompts": [
{
"type": "confirm | input | checkbox | list | rawlist | password"
// ...
}
]
}
Example
settings.json
{
"prompts": [
{
"name": "over18",
"type": "confirm",
"message": "Are you over the age of 18?"
}
]
}

Produces

❯ tps react-component Nav
? Are you over the age of 18?

Tps Type

The next field is tpsType. This field tells tps how it should process the users answer. There are two options package or data.

note

If you don't specify a tpsType field. Tps will use package by default.

package

settings.json
{
"prompts": [
{
"tpsType": "package"
// ...
}
]
}

When you have package as the tpsType, tps will try to use the users value to render a package that is in your template. Different values passed in will have different behaviors.

boolean

In the case where a prompt's answer is a boolean and its value is true, Tps will utilize the name of the prompt to search for a package with the same name. If such a package is found, tps will include it during the rendering process of the new instance. When the value is false, tps will disregard the prompt and do nothing.

important

Prompts of type confirm will return their answers as booleans.

Example

Say were rendering a new express-app instance and we have a prompt like so

settings.json
{
"prompts": [
{
"name": "unit",
"tpsType": "package",
"type": "confirm",
"message": "Do you want to include unit tests?"
}
]
}

since this is declared as a package type, this needs a corresponding package in the template

| - .tps/
| - express-app/
| settings.json
| - default/
| - server.js
| - unit/ <-- matches name of prompt
| - server.test.js

When the user is rendering a new template, the prompt will be displayed and they can answer.

❯ tps express-app newApp
? Would you like to include unit tests?

Depending on what the user answers depends on what will happen:

If user answers yes, then the unit package will be included in the rendering process so a server.test.js will be added

| - newApp/
| - server.js
| - server.test.js
string

When a prompt's answer is a string, word or name, tps will take that answer and attempt to find a package that corresponds to it. If one is found then tps will include it in the rendering process.

important

Prompts of type list and input will return their answers as strings.

Example

Say were rendering a new express-app instance and we have a prompt like so

settings.json
{
"prompts": [
{
"name": "framework",
"tpsType": "package",
"message": "What type of frontend framework would you like to use?",
"type": "list", // <--- makes prompt accept strings
"choices": ["react", "angular"]
}
]
}

since this is declared as a package type, the choices to the question must match a package in our template.

| - .tps/
| - express-app/
| settings.json
| - default/
| - server.js
| - react/
| - react.js
| - angular/
| - angular.js

When the user is rendering a new instance, the prompt will be displayed and the user can answer.

❯ tps express-app newApp
? What type of framework would you like to use?
> react
angular

With the choice the user selects, tps will then include a package that matches the answer

If user answers react, then the react package will be included in the rendering process so a react.js will be added

| - newApp/
| - server.js
| - react.js
list

If a prompt's answer consists of a list of strings, tps will consider each individual answer and locate the corresponding packages associated with them. These packages will then be included during the rendering process.

important

Prompts of type checkbox will return their answer as list of strings.

Example

Say were rendering a new express-app instance and we have a prompt like so

settings.json
{
"prompts": [
{
"name": "extras",
"message": "Would you like to include any other features?",
"tpsType": "package",
"type": "checkbox", // <--- makes prompt accept list of strings
"choices": ["metrics", "unit", "e2e", "api"]
}
]
}

since this is declared as a package type, the choices to the question must match a package in our template.

| - .tps/
| - express-app/
| settings.json
| - default/
| - server.js
| - metrics/
| - metrics.js
| - unit/
| - server.test.js
| - e2e/
| - website.test.js
| - api/
| - api.js

When the user renders a new template. tps will ask for an list of inputs. Whatever the user answers, tps will take all of the values and try to find a packages that matches the answers.

If the user answers metrics and unit then both packages will be included in the rendering process

| - newApp/
| - metrics.js
| - server.test.js
| - server.js

data

{
"prompts": [
{
"tpsType": "data"
// ...
}
]
}

When the tpsType is set to data, tps will leave the data untouched. This data type is designed to allow you to retrieve additional information from the user, which you can then process according to your specific needs. One common use case for this is to conditionally render specific code within the file based on the user's response to a certain question. Any inquirer type can be used.

Example

Say were rendering a new express-app instance and we have a prompt like so

settings.json
{
"prompts": [
{
"name": "security",
"message": "Would you like to include common express security packages?",
"tpsType": "data",
"type": "confirm" // <--- makes prompt accept boolean
}
]
}

When the user is rendering a new instance, the prompt will be displayed and the user can answer. Whatever the user answers will now be available for use in your dynamic files.

Dot Template
const express = require("express");
{{{? tps.answers.security }}}
const helmet = require("helmet");
{{{?}}}

const app = express();

{{{? tps.answers.security }}}
app.use(helmet());

{{{?}}}
/* node code ... */
Result
null

Aliases

The aliases option allows you to give aliases to your prompts. These aliases can be used when answer prompts either through the command line, node, or a configuration file which we will cover more in detail in how to answer prompts.

settings.json
{
"prompts": [
{
"name": "some-name",
/* ... */
"aliases": ["<alias-name>"]
}
]
}
tip

On the command line, single letter aliases should be answered with a single dash - and other names should be answered with two dashes --

settings.json
{
"prompts": [
{
"name": "name",
"type": "input",
/* ... */
"aliases": ["n", "realName"]
}
]
}

Now I can answer this prompt with one of the following

tps some-template test --name lino

# or

tps some-template test -n lino

# or

tps some-template test --realName lino
Example

If we were rendering a new instance using the express-app template and had this settings file

settings.json
{
"prompts": [
{
"name": "framework",
"choices": ["react", "vue", "angular"],
/* ... */
"aliases": ["f"]
}
]
}

Now we can answer the prompt question with the alias

tps express-app app -f react

Hidden

templates@>=v1.1.1

The hidden option makes the prompt a hidden prompt. Hidden prompts do not get prompted by default. This is useful when you want to add more customizable logic in your template but dont want to overwhelm users with a tons of prompt questions.

{
"prompts": [
{
"hidden": true
// ...
}
]
}
Example

Lets say we had a template named hidden-prompt-test that had these two prompts, one being a hidden prompt and the not.

settings.json
{
"prompts": [
{
"name": "prompt1",
"message": "Would you like to include prompt1",
"tpsType": "data",
"type": "confirm"
},
{
"name": "prompt2",
"message": "Would you like to include prompt2",
"tpsType": "data",
"type": "confirm",
"hidden": true
}
]
}

when users generate a new instance by default, hidden prompts wont be prompted so only prompt1 will be prompted to the user.

tps hidden-prompt-test test
? Would you like to include prompt1 (n/Y)

Hidden prompts can still be answered and prompted.

Prompting all hidden prompts

Use can use the hidden option to prompt all hidden prompts.

tps hidden-prompt-test test --hidden
Example

Lets say we had a template named hidden-prompt-test that had these two prompts, one being a hidden prompt and the not.

settings.json
{
"prompts": [
{
"name": "prompt1",
"message": "Would you like to include prompt1",
"tpsType": "data",
"type": "confirm"
},
{
"name": "prompt2",
"message": "Would you like to include prompt2",
"tpsType": "data",
"type": "confirm",
"hidden": true
}
]
}

If we wanted to get prompted hidden prompts, we can use the hidden option and all hidden prompts will now be prompted to you

tps hidden-prompt-test test --hidden
? Would you like to include prompt1 (n/Y)
? Would you like to include prompt2 (n/Y)

Answering hidden prompts

You can also answer hidden prompt just like any normal prompt which we will cover in the next section

tps hidden-prompt-test test --hiddenPrompt
Example

Lets say we had a template named hidden-prompt-test that had these two prompts, one being a hidden prompt and the not.

settings.json
{
"prompts": [
{
"name": "prompt1",
"message": "Would you like to include prompt1",
"tpsType": "data",
"type": "confirm"
},
{
"name": "prompt2",
"message": "Would you like to include prompt2",
"tpsType": "data",
"type": "confirm",
"hidden": true
}
]
}

If we wanted to answer prompt2 without being prompted we can pass in the prompt2 flag.

tps hidden-prompt-test test --prompt2
? Would you like to include prompt1 (n/Y)

How to answer prompts

Interactive

The primary method of answering prompts is through interactive prompts. When you generate a new instance of a template, tps will prompt the user to provide answers until all the prompts are completed. This interactive mode is also the default way to respond to prompts.

Flags

Tps also supports answering prompt questions through command line flags. This feature enables users to obtain their desired results directly without having to go through all the prompts interactively. The flag's name will correspond to the prompt's name specified in your settings file.

tps some-template app --some-flag <some-value>
Example

If we were rendering a new instance using the express-app template and had this settings file

settings.json
{
"prompts": [
{
"name": "unit",
"message": "Would you like to include unit tests?",
"tpsType": "package",
"type": "confirm"
}
]
}

The user can answer this prompts questions by adding a unit command line flag

tps express-app app --unit

Now lets go over how to answer different types of prompts

boolean

When dealing with boolean values, such as those from a confirm prompt, you have the option to answer the prompt using a flag with the same name as the prompt. To answer with true, simply use:

--unit

On the other hand, if you want to provide a false value, add no- before the flag name:

--no-unit
Example

If we were rendering a new instance using the express-app template and had this settings file

settings.json
{
"prompts": [
{
"name": "unit",
"message": "Would you like to include unit tests?",
"tpsType": "package",
"type": "confirm"
}
]
}

The user can answer this prompts questions by adding a unit command line flag

tps express-app app --unit
string

When dealing with string values, such as those from a input or list prompts, add the value right after your flag

--cssType less

# or if you need a number

--age 23

# if your value has spaces then you need to do this

--message "hey there everyone"
Example

If we were rendering a new instance using the express-app template and had this settings file

settings.json
{
"prompts": [
{
"name": "framework",
"message": "What frontend package would you like to include",
"tpsType": "package",
"type": "list",
"choices": ["react", "angular", "vue"]
}
]
}

The user can answer this prompts questions by adding a framework command line flag and adding the value after the flag named

tps express-app app --framework react
list

If the value type is an list then you end up with something like this.

--ages 23 45 65

# or strings

--numbers ten nine five
Example

If we were rendering a new instance using the express-app template and had this settings file

settings.json
{
"prompts": [
{
"name": "extras",
"message": "Would you like to include any other features?",
"tpsType": "package",
"type": "checkbox", // <--- makes prompt accept list of strings
"choices": ["metrics", "unit", "e2e", "api"]
}
]
}

The user can answer this prompts questions by adding a extras flag and putting the values after the flag name

tps express-app app --extras metrics unit e2e
note

Using list types can be difficult when using multiple flags etc. yargs is used for its command line parser. You can refer how to pass in list of arguments here

When using lists on the command line it is recommended to add the flag after all required fields:

when using lists on the command line before all required params, you have to add a extra -- after the list flag so yargs can parse the require params correctly

tps express-app --extras metrics api unit -- app

Configuration File

Templates also supports answering prompts in our configuration file aka (tpsrc file). When adding an answer to your config file, templates will use this answer when generating a new instance and will no longer be prompt you the prompted you answered.

You can read more about how to use our configuration file in our configuration guide

.tpsrc
{
"<template-name>": {
"answers": {
"<prompt-name>": "<prompt-answer>"
}
}
}
Example

If I had a template named hello-world and a prompt named age:

settings.json
{
"prompts": [
{
"name": "age"
// ...
}
]
}

Then I can set the answer to the prompt in our .tpsrc file with:

.tpsrc
{
"hello-world": {
"answers": {
"age": 23
}
}
}

Now you will no longer be prompted the age prompt and templates will use the answer 23 for ever instance you render.

node

To answer prompts in javascript using the module. Use the setAnswers function.

const Templates = require('tps');

const tps = new Templates('react-component');

/**
* Just like the command line passing in data supports strings, numbers, and arrays
* @example string
* const data = '23';
* @example number
* const data = 23;
* @example boolean
* const data = true;
* @example array
* const data = [23, 45, 65];
*/
const age = 23;

tps.setAnswers({ age });

Examples

View can view more detailed examples in our prompt api docs