---
title: "Project Starter"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Project Starter}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
library(dplyr)
```

## Introduction

This vignette will walk you through the `create_project()` function.
The function creates a new directory or populates an existing project directory with essential files needed for a new analysis project.
Existing files in the directory will not be overwritten, unless the user specifically requests to overwrite them. 

By default the directory is populated with customized `README.md`, `.gitignore`, and `<name>.Rproj` files.
Users can also create a personalized project templates. Instructions for creating your own template is detailed in the [custom templates section](#custom_template). 

## Default Template

Let's create a new project and inspect the results.
The new project will be created in a the folder called `"My Project Folder"`.

```{r proj-setup, message=FALSE}
# loading packages
library(starter)

# specifying project folder location (folder does not yet exist)
project_path <- fs::path(tempdir(), "My Project Folder")
```

Let's set up our new project. 

```{r proj-create}
create_project(
  path = project_path,
  open = FALSE # don't open project in new RStudio session
)
```

The directory was created, files added, a git repository was initialised in the folder, and the reproducible environment was constructed with the renv package.

### **`README.md`**

The following is the `README.md` file added the project directory.
It's pre-filled with information specific to this project.
The first line of the file is the project folder name, followed by a R code for creating a symbolic link from the project folder to the secure data folder.

```{r readme, comment = "", echo=FALSE}
readr::read_file(fs::path(project_path, "README.md")) %>% cat()
```

### **`.gitignore`**

The `.gitignore` file is populated with various R files, data file types, and miscellaneous files typically not wanted in a Git repository.

```{r gitignore, comment = "", echo=FALSE}
readr::read_file(fs::path(project_path, ".gitignore")) %>% cat()
```

## Custom Template {#custom_template}

While the default template is useful, it can of course, be useful to create a custom template for yourself or your team.
To create a custom template, you'll need two things: 

1. Template files

1. Meta data for each template file (e.g. location of template file, file name, etc.)

### Template Files

There are two kinds of template files.
The first are static files that a merely copied into the new project folder.
The `.gitignore` file described above in the default template is an example of a file static file.

The second type of template file contain data or information specific to the new project.
In the default template described above, the `README.md` file is an example of these dynamic template files.
The `README.md` file is populated with the project name, and the project-specific code for creating a symbolic link to the secure data folder.
The following fields are available to include in the dynamic templates.

    {{folder_name}}          project folder name
    {{folder_first_word}}    first word of folder name
    {{symbolic_link}}        code for establishing symbolic link to data folder
    {{foo()}}                any R function, e.g. `Sys.Date()`

Each of these fields are accessible via standard `glue::glue()` syntax, with the exception that double curly brackets are needed rather than single (e.g. `glue::glue(., .open = "{{", .close = "}}")`).

Below is an example of the dynamic `README.md` template from the default template.

```{r, comment = "", echo=FALSE}
readr::read_file(system.file("project_templates/default_readme.md", package = 'starter')) %>% cat()
```

### Metadata

In order to create a template, you must add a metadata object that stores information about each template file.
The metadata is stored as a named list: one element in the list per file in the template.

The list elements may be named any proper name within R.
However, the names must be unique and we recommend short names.
These do not need to match/reference any other text in the template file.

```{r my_template}
my_template <-
  list(
    gitignore = list(),
    readme = list(),
    rproj = list()
  )
```

Each element of the list is itself a list.
The lists contain three important pieces of information about each template file.

1. The template path and file name.

1. The name of the file after it's been copied to the new project folder.

1. A logical argument indicating whether the file is a straight copy, or a dynamic file (described above).

The metadata for the `README.md` file in the default template looks like this:

```{r lst-readme, eval=FALSE}
readme <- 
  list(
    template_filename = system.file("project_templates/default_readme.md", package = "starter"), 
    filename = "README.md", 
    glue = TRUE
  )
```

Note that in this case, the location of the template file is pointing to a file location where the {starter} package is installed.
If you are not saving your template in an R package, your `template_file` path will likely point to a folder in your machine, e.g. `"C:/project_templates/default_readme.md"`

As another example, here's the metadata for the `*.Rproj` file from the default template.
Note that the file name can be dynamic (the use of `glue::glue()`), while the underlying file is not dynamic (`glue = FALSE`).
The list is stored as an expression so the template meta data is not evaluated until you call the `create_project()` function, allowing files to be dynamically named and template files to be saved within a package.

```{r rproj, eval=FALSE}
rproj <- 
  rlang::expr(list(
    template_filename = system.file("project_templates/default_rproj.Rproj", package = "starter"), 
    filename = glue::glue("{folder_name}.Rproj"), 
    glue = FALSE
  ))
```

Below is an example of a simple custom template.

```{r full-template}
my_template <- 
  list(
    readme = rlang::expr(list(
      template_filename = system.file("project_templates/default_readme.md", package = "starter"), 
      filename = "README.md",
      glue = TRUE
    )),
    rproj = rlang::expr(list(
      template_filename = system.file("project_templates/default_rproj.Rproj", package = "starter"), 
      filename = glue::glue("{folder_name}.Rproj"),
      glue = FALSE
    )),
    gitignore = rlang::expr(list(
      template_filename = system.file("project_templates/default_gitignore.txt", package = "starter"), 
      filename = ".gitignore", 
      glue = TRUE
    ))
  )
```

Note that you are able to put files into subfolders by including the subfolder name in the `filename` argument.  This can be done for any type of file. 
Here's an example of what the metadata could look like if the user has a static Rmarkdown template called `template_analysis.Rmd` that they want to copy into a project subfolder called `scripts`.

```{r analysis, eval = FALSE}
analysis <- 
  list(
    template_filename = "C:/project_templates/template_analysis.Rmd", 
    filename = "scripts/analysis.Rmd", 
    glue = FALSE
  )
```

### Advanced Features

You may also `source()` an R script by adding the path to the file as a template attribute.
The script will be sourced after project template has been placed.
This feature is often used when you'd like to add an empty folder to your project.

```r
attr(my_template, "script_path") <- "<path to file>"
```

Wrap the path to the script in an expression if you need to delay the evaluation of the path string.

You can also override the `create_project()` arguments by adding an attribute with a named list of the argument values you'd like the template to use.
For example, if you always want to initialize the git repo and never use renv, attach this list `list(git = TRUE, renv = FALSE)` as an attribute called `"arg_override"`.

There is one last step---give your template a label.
The label will be displayed each time the template is called in either `create_project()` or `use_project_file()`.

```{r label}
attr(my_template, "label") <- "My 1st Project Template"
```

It is recommended you create the list elements named `'readme'` and `'gitignore'`. 
The `'readme'` element is used in the in the `use_project_readme()` function and `'gitignore'` is in the `use_project_gitignore()` function---without these elements, these useful functions will return errors.

### Implement Custom Template

Now that you have a folder with your template files stored and you have created a metadata list object, you can use them to create a new project folder with your custom template.
The following code will get you started.

```{r unlink, include=FALSE, echo=FALSE}
unlink(project_path, recursive = TRUE)
```

```{r create_project}
create_project(
  path = project_path,
  template = my_template # metadata list created above
)
```
