# Usage

There are two commands in which the templates can be used:

1. `grund init`
    - Initiates a grund project in which one chooses what templates to use.
    - All options exposed by the templates might not be exposed to the user. It might require some fallbacks.
2. `grund create`
    - Generates one specific template.
    - All options available to the template are exposed to the user.

# Structure of all templates

We sort the templates into groups depending on their main functionality:

-   `auth` - Templates that adds authentication functionality.
-   `platforms` - Templates that adds a platform of any type (web, server, native).
-   `project` - Templates that adds functionality that is project-wide (mainly shared)
-   `workspace` - Templates that adds functionality of the workspace and project as a whole - we might move this to project as well?

# Structure of one template

Each template contains these components:

1. A `files` directory - contains all the files of the source files of the template.
2. A `grund.template.json` file - contains some metadata about the template.
3. In the future we might want to put in some dynamic rules that might be placed inside or beside the `grund.template.json` file.

There are a few cases of templates:

1. One or several packages?
    1. The template contains only one package.json (most likely a platform).
    2. The template contains several package.json's. Each one of these needs to be named uniquely since they will be a part of the workspace. The naming also needs a structure in order to be replaced in the generation process.
2. File structure
    1. The file structure may be static, i.e. will be directly copied to the template. The project.default is a good example of this.
    2. The file structure destination might be dynamic. It will probably depend on some variables that are inputted into the destination path.

# Naming strategy

We need a naming system for the name prop in the package.json's. This is because they will be replaced by some project specific name when creating/generating the template.

Some terms:

-   `TEMPLATE_GROUP` - The categorization of templates - used in the TEMPLATE_NAME.

    -   `workspace` - Templates responsible for setting up the monorepo. Currently only yarn is supported.
    -   `project` - Templates responsible for the shared files of project. Currently only a default one is supported.
    -   `platform` - Templates responsible for adding a certain platform. See PLATFORM_TYPE for more details.
    -   `auth` - Templates responsible for adding a certain authentication solution to the project.

-   `PLATFORM_TYPE` - The sub categorization of platform templates.

    -   `native` - Platforms for publishing to the app stores.
    -   `web` - Platforms to be run in the browser
    -   `server` - Platforms to be run on the server.

-   `TEMPLATE_NAME`
    -   The unique identifier of the template within the template group.
    -   Examples: `app`, `admin`, `api`
-   `TEMPLATE_ALIAS`

    -   The unique identifier for a template.
    -   Example:
        -   `{{ TEMPLATE_GROUP }}.{{ PLATFORM_TYPE? }}.{{ TEMPLATE_NAME }}`
        -   `platforms.web.app`

-   `TEMPLATE_FULL_ALIAS`

    -   The full name of the template - including the namespace `@template`
    -   Examples
        -   `@template/platforms.web.app--app`
        -   `@grund.template.{{ TEMPLATE_ALIAS }}`
        -   `@template/{{ TEMPLATE_GROUP }}.{{ PLATFORM_TYPE }}.{{ TEMPLATE_NAME }}`

-   `package name` - the name that is defined in a `package.json`.

All the names of the package.json's in template's files will be in the format of `{{ TEMPLATE_FULL_ALIAS }}--{{ PACKAGE_NAME }}`.
When the templates are generated they will replace the package name with `{{ TARGET_NAMESPACE }}/{{ PACKAGE_NAME }}`.
If `PACKAGE_NAME` is omitted then it will fall back to the `TEMPLATE_NAME`. Hence:

| Template                            | Generated            | Comment                               |
| ----------------------------------- | -------------------- | ------------------------------------- |
| `@template/workspace.default--root` | `@boiler/root`       | Takes the name from the template name |
| `@template/project.default--client` | `@boiler/client`     | Takes the name from the template name |
| `@template/platforms.web.app`       | `@boiler/web.app`    | No package name                       |
| `@template/platforms.native.app`    | `@boiler/native.app` |                                       |

# Variables

The next thing on the schedule is to be able to send in variables that the template can use to generate the project files. The listing of these variables should somehow be clear from the template config (grund.template.json). The sources of these variables could be several:

1. CLI - Command line arguments
2. Config - Template config (grund.template.json).
3. Project - The project itself (e.g. the name in the root package.json).
4. Questions - Asked to the user in the command line.

There are some variables that can be identified from the current structure and some different cases where they are needed.

-   `namespace`
    -   The namespace of the project (e.g. @grund).
    -   Will be required everytime we will generate a package.json.
    -   This could either be injected or, as a fallback, be taken from the root package.json.
-   `root`
    -   The root that the template files will be generated into.
    -   Works together with `directory` below to create the final path.
-   `directory`
    -   The parent directory the template files will be generated into.
-   `packageName`
    -   The name property in the root package.json of the files.
    -   Only applicable (probably) in the platform case.
    -   This should be injected by the cli with a fallback from the template config.

Then comes the question of how we should inject each variable into the template. For each template, this is the

| Initiator | Variable    | Default | Required | Override | Comment                                                  |
| --------- | ----------- | ------- | -------- | -------- | -------------------------------------------------------- |
| init      | namespace   | -       | Yes      | CLI      |                                                          |
| init      | root        | Config  | No       | CLI      |                                                          |
| init      | directory   | Config  | No       | CLI      |                                                          |
| init      | packageName | Project | No       | CLI      | Extracts the name from the name property in package.json |
| -         | -           | -       | -        | -        | -                                                        |
| create    | namespace   | Project | No       | CLI      |                                                          |
| create    | root        | Config  | No       | CLI      |                                                          |
| create    | directory   | Config  | No       | CLI      |                                                          |
| create    | packageName | Config  | Yes      | CLI      |                                                          |
