Generating an Instance
Generating an instance of a template involves creating a new entity based on the template's contents. During this process, Templates takes the files and folders defined in the template and renders them to your build path(s).
What is a Build Path
The build path is a combination of a name and an optional location that you provide to Templates. Templates uses this build path to determine where to render your instance.
The name
represents the instance identifier. Templates creates a new directory
based on the supplied name—unless told not to—and generates all template
contents into that directory. This name
may also be used internally by the
template in areas requiring a unique identifier.
The location
specifies where Templates should place the new instance. This is
useful if you don't want the instance generated in your current directory.
The build path follows a Linux-style file path pattern, and there are four main variations you can use
- Short build path
- Long build path
- Multiple build paths
- No build path
Short build path
A short build path is a build path that only contains a name
.
my-food-app
|__________|
^ Build path and instance name
Like mentioned earlier, Templates creates a new directory with this name
in
your cwd. It then renders the template’s contents into that directory and
assigns the name as the instance’s identifier.
Some examples of this could be:
- The name of a react component
- The name of your new express app and name in package json
- etc, etc
Example
If we were generating a new instance of a template name node-server
and we
have the build path of my-food-app
then Templates will create a new directory
called my-food-app
and render all the templates contents inside of it
| - my-food-app/
| - <node-server contents...>
Long build path
A long build path is a build path that contains a location
and name
.
projects/my-food-app
|______| |_________|
^ location ^ instance name
|___________________|
^ build path
Templates still follows all the rules of a single build path. However, the
directory thats created based on the name
is created inside the location
directory. If the location
directory doesnt exist it will be created. In case
above, my-food-app
instance will be created in the projects
directory.
Example
If we were generating a new instance of a template named node-server
and we
have the build path code/projects/my-food-app
then Templates will create a new
directory called my-food-app
inside of <cwd>/code/projects
and render all
the templates contents inside.
|- code
|- projects
| - my-food-app/
| - <node-server contents...>
Multiple build paths
Multiple build paths are a way to create multiple instances of a template in a single process. When defining multiple build paths, you can use a mix of short and long builds paths:
projects/my-food-app projects/my-gas-app my-food-app-2
|__________________| |_________________| |____________|
^ build path 1 ^ build path 2 ^ build path 3
Templates generates an instance for every build path. Each instance is independant and follows the same process as if you were just generating the single instance. Generating multiple instances may not be ideal for every template, but it's especially useful for templates that create sections or pieces of an existing app—such as new React components, API routes, background job files, and more.
Example
If we were generating a new instance of a template named node-server
and we
have the build paths projects/my-food-app
& projects/my-gas-app
then
emplates will create both instances in the projects
directory.
|- projects
| - my-food-app/
| - <node-server contents...>
| - my-gas-app/
| - <node-server contents...>
No Build path
Some template's dont need a build path to generate a new instance. This is because they dont need a new folder or any unique instance name to generate your content. However, you will only be able to generate this instance in the directory you are located in. Some examples of this can be a eslint configuration file, jest configuration file, or anything in this similar vain.
Always refer to the template's documention page to see how they want you to use their template
Example
If we were generating a new instance of a template named eslint
and we didnt
specific a build path, it could create something like the following:
|- <cwd>
| - <eslint contents...>
Templates allow you to provide a build path to a template that doesn't require one. Currently, Templates have no way of determining whether a build path is required for a given template. However, this behavior may change in future versions. Always refer to the template's documentation for the recommended usage
How to generate a new instance
Our CLI is our primary way to generate new instances of a template. You can
access the CLI after installation with the tps
command:
tps <template-name> [build-paths...]
Replace <template-name>
with the name of the template you want to use and add
any build paths afterward.
# Short build path
tps my-template buildPath1
# Long build path
tps my-template path/to/dir/buildPath1
# Multiple build paths
tps my-template buildPath1 path/to/dir/buildPath2
# No build path
tps my-template
Use the list command to see what templates are available.
tps list
Example
If you wanted to use our react-component
template you would replace <template-name>
with react-component
and then the
component you want to create afterwards (E.g.
build path). For this demo, well be creating a Nav
component:
tps react-component Nav
This will then generate something similar to the follow:
| - <cwd>
| - Nav/
| - <react-component contents...>
You can use a long build path if you want to place this instance in a sub directory.
Example, its common for some components like a nav to live in a
src/components/
directory so using the same
react-component
template and component
Nav
, you can use the following to generate the Nav
instance in
src/components/
:
tps react-component src/components/Nav
If you want to generate multiple instances at the same time you can use something similar to the following:
tps react-component src/components/Nav src/components/Footer
Using a Template's Options
Template's can define options to make their template more dynamic. Templates allows you to use these options in 4 main ways:
- Interactive
- CLI
- Config file
- Aliases
Hidden options are a special type of option that we will cover in the hidden options section.
Interactive
The primary method of answering options is through interactive prompts. When you generate a new instance of a template, Templates will prompt you in the terminal all non hidden options then generate your instance.
tps react-component Nav
? Would you like to use typescript (y/N)
If you press Enter
without typing anything, Templates will use the option's
default value as the answer. You can also cancel the process by sending an
interrupt signal (E.g ctrl + c
).
CLI
Templates supports using options directly on the command line, allowing you to
quickly provide answers without going through all the prompts interactively. The
command-line flag for each option corresponds to its name, prefixed with --
.
For example, if an option is named hey
, the corresponding CLI flag would be
--hey
. When you provide an answer using a CLI flag, Templates will skip
prompting for that option.
tps some-template instance1 --optionName [value]
We recommend adding all options after your build path(s) in order to prevent
needing a CLI separator --
.
- Recommended
- Not Recommended
tps my-template app --option1 value1 --option2 value2 value3
tps my-template --option1 value1 --option2 value2 value3 -- app
Example
To use the extension
option from
react-component
, you can add a
--extension
flag to the CLI command:
tps express-app my-app --extension jsx
Now lets go over how to answer different types of prompts:
Boolean
When dealing with options that accept boolean values, specify the option name on
the CLI without any value. To use a true
value, simply use the option name as
shown below:
--typescript
To use a false
value, add the no-
prefix in front of the option name:
--no-typescript
Example
To use the typescript
option from
react-component
, you can do the following:
tps react-component Nav --typescript
If you don't want to use typescript
, then you can do the following:
tps react-component Nav --no-typescript
Single values
When dealing with options that accept a single value, specify the option name and value afterwards:
--cssType less
# or a number
--age 23
# or with =
--type=something
# if your value has spaces, wrap it with quotes
--message "hey there everyone"
Example
To use the cssExtension
option from
react-component
, you can do the following:
tps express-app app --cssExtension react
List
When dealing with options that accept a list of values, specify the option name and all values afterwards:
--ages 23 45 65
# or strings
--numbers ten nine five "forty five"
Example
To use the extras
option from a template named my-template
, you can do the
following:
tps my-template app --extras metrics unit e2e
Configuration file
Templates also support answering options in our configuration file. When adding an answer to our config file, Templates will use this answer when generating a new instance, and you will no longer be prompted for the option.
To answer a template's option, you need to first specify the template name. Then
you can add your answer to the answers
object, which takes a key/value pair of
optionName/optionAnswer.
{
"<template-name>": {
"answers": {
"<option-name>": "<option-answer>"
}
}
}
You can read more about how to use our configuration file in our configuration guide.
Example
To use the typescript
option from
react-component
, you can add true
for the
typescript
option in your config file like the following:
{
"react-component": {
"answers": {
"typescript": true
}
}
}
Afterward, you will no longer be prompted if you want to use TypeScript, and your React components will always be generated in TypeScript.
Aliases
Some Templates option's have aliases that you can use to answer the option. You
can find these in the aliases
column for your template's options. You can use
these aliases just like any normal option name. The only exeption is single
charater aliases which can be used on the CLI with only one -
and then the
single charater.
tps my-template app -t
Example
To use the typescript
option alias, t
, from
react-component
, you can do the following:
tps react-component Nav -t
If you dont want to use typescript
, then you can do the following:
tps react-component Nav --no-typescript
Hidden Options
Hidden options are options that don't get prompted by default. These options
usually allow for more fine modifications that are too cumbersome to ask every
time. You can answer hidden options just like normal prompts (e.g., CLI, config
file) with the exception of being asked interactively. In order to have hidden
options get prompted, you can use the hidden
option on the command line when
generating a new instance.
tps my-template app --hidden
Core Options
Below will show you how to use some of Template's core options. You can find a full list of these options in the Templates API docs. All core options can be specified on the CLI or in our config file.
To use core options on the CLI, use the option name as a flag similar to how you would with template's options.
tps my-template app --optionName optionValue
To use core options in our config file, add them to the opts
object for the template you want the options to have effect on.
{
"my-template": {
"opts": {
"optionName": "optionValue"
}
}
}
Defining options in our config file is only allowed at the template level. We don't support defining options that affect all templates. However, this may change in the future.
Default
By default, Templates will prompt you for every non-hidden option that does not
have a defined value. To skip all these interactive prompts, you can use the
default
option which will have Templates use default values for each option.
tps my-template app --default
You can use this in conjunction with options on the CLI and in your config file:
tps my-template app --default --option1 value1 --option2
Wipe
By default, Templates will throw an error if the directory it needs to create is
already created or if any of the files it needs to create are already created.
To force the creation of this instance, you can use the wipe
option. The
wipe
option will delete any directories or files that Templates need to create
first, then render your instance.
tps my-template app --wipe
This is very useful when you want to render a new instance of an instance you just created but with different options.
Example
Let's say you have the following directory structure:
| - app
| - .tps/
| - ...
| - src/
| - Home/
| - ...
If you were trying to render a new instance of the react-component
template
and called this Home
, tps would error out because a Home
directory already
exists. However, if you add the --wipe
flag, tps will delete this directory
first, then render your new instance in its place.
tps react-component src/Home --wipe
This will produce:
| - app
| - .tps/
| - ...
| - src/
| - Home/
| - <react-component template files ...>
Force
Very similar to the wipe
command, the force
option will force the
creation of any files that already exist. The main difference between these
commands is that wipe
deletes folders and files while force
only overrides
any files that have conflicts.
tps my-template app --force
This is useful when you created an instance and added additional files and folders in your instance but you want to regenerate the instance with different options without losing your additional work.
Example
Let's say you have the following directory structure:
| - app
| - .tps/
| - ...
| - src/
| - Home/
| - some-file.js
If you were trying to render a new instance of the react-component
template
and called this Home
, tps would error out because a Home
directory already
exists. However, if you add the --force
flag, tps will force the creation of
your instance but will only overwrite conflicting files.
tps react-component src/Home --force
- No conflicts
- Conflicting file
If the react-component
template doesn't create a some-file.js
, then the
original file will be left in place and not touched.
| - app
| - .tps/
| - ...
| - src/
| - Home/
| - some-file.js
| - <react-component template files ...>
If the react-component
template was going to render a some-file.js
, then the
file will be overridden by the template's some-file.js
.
| - app
| - .tps/
| - ...
| - src/
| - Home/
| - some-file.js <--- from react-component
| - <react-component template files ...>
Extending Directory
Templates extendDest
option allows you to extend each build path with a
additional path. This additional path is added to the front of your build path
and can be used in conjunction with a long build path.
Build Path(s) | extendDest | Result |
---|---|---|
app | myPath/ | myPath/app |
subPath/app | myPath/ | myPath/subPath/app |
app app2 | myPath/ | myPath/app myPath/app2 |
This option is very useful when you know your instances will be generated in a paticular directory every time and you dont want to type this out every time.
- Config File
- CLI Option
You can add the extendDest
to the opts
object in your config file to always append a
path to every instance you create.
{
"my-template": {
"opts": {
"extendDest": "path/to/directory",
}
}
}
Sorry, not supported yet! Coming soon...