infuser is a simple and very basic templating engine for R
R
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
R
inst/extdata
man
tests
vignettes
.Rbuildignore
.gitignore
.travis.yml
DESCRIPTION
LICENSE
NAMESPACE
README.Rmd
README.md
infuser.Rproj

README.md

Travis Build Status Coverage Status CRAN_Status_Badge Downloads

infuser is a simple and very basic templating engine for R. It replaces parameters within templates with specified values. Templates can be either contained in a string or in a file.

Installation

install.packages("infuser")

If you want to use the most up-to-date version, install using devtools::install_github.

devtools::install_github("Bart6114/infuser")

Hello World

A simple Hello World example that makes use of the magrittr piping workflow.

library(magrittr)
library(infuser)

"Hello {{var1}}!" %>%
  infuse(var1="world")

## Hello world!

Usage

Working with character strings as templates

Let's have a look at an example string.

my_sql<-"SELECT * FROM Customers
WHERE Year = {{year}}
AND Month = {{month|3}};"

Here the variable parameters are enclosed by {{ and }} characters. See ?infuse to use your own specification.

From now on, we suppose the character string my_sql is our template. To show the parameters requested by the template you can run the following.

library(infuser)
variables_requested(my_sql, verbose = TRUE)

## Variables requested by template:

## >> year

## >> month (default = 3)

To fill in the template simply provide the requested parameters.

  infuse(my_sql, year=2016, month=8)

## SELECT * FROM Customers
## WHERE Year = 2016
## AND Month = 8;

You can also provide a named list with the requested parameters.

my_list<- 
  list(year=2016,
       month=8)

infuse(my_sql, my_list)

## SELECT * FROM Customers
## WHERE Year = 2016
## AND Month = 8;

If a default value is available in the template, it will be used if the parameter is not specified.

infuse(my_sql, year=2016)

## SELECT * FROM Customers
## WHERE Year = 2016
## AND Month = 3;

Working with text files as templates

Just like we're using a string here, a text file can be used. An example text file can be found in the package as follows:

example_file<-
  system.file("extdata", "sql1.sql", package="infuser")

example_file

## [1] "/Library/Frameworks/R.framework/Versions/3.3/Resources/library/infuser/extdata/sql1.sql"

Again, we can check which parameters are requested by the template.

variables_requested(example_file, verbose = TRUE)

## Variables requested by template:

## >> month (default = 3)

## >> year

And provide their values.

infuse(example_file, year = 2016, month = 12)

## SELECT LAT_N, CITY, TEMP_F
## FROM STATS, STATION
## WHERE MONTH = 12
## AND YEAR = 2016
## AND STATS.ID = STATION.ID
## ORDER BY TEMP_F;

Infusing vectors

It is quite easy to infuse a vector.

years <- c(2013,2014,2015)
sql_string <- "SELECT * FROM T1 WHERE Year IN ({{years}})"

infuse(sql_string, years=years)

## SELECT * FROM T1 WHERE Year IN (2013,2014,2015)

You can also specify the collapse character.

infuse(sql_string, years=years, collapse_char = ";")

## SELECT * FROM T1 WHERE Year IN (2013;2014;2015)

Processing / transforming your inputs

A transform_function can be specified in the infuse command. This allows for pre-processing of the parameter values before inserting them in the template.

What we don't want to happen is the following:

sql<-"INSERT INTO Students (Name) VALUES ({{name}})"
name <- "Robert'); DROP TABLE Students;--"

infuse(sql, name = name)

## INSERT INTO Students (Name) VALUES (Robert'); DROP TABLE Students;--)

Yikes! A way to solve this is to specify your own custom transform function.

my_transform_function<-function(v){
  # replace single quotes with double quotes
  v<-gsub("'", "''", v)
  # encloses the string in single quotes
  v<-paste0("'",v,"'")
  
  return(v)
}

infuse(sql, name = name, transform_function = my_transform_function)

## INSERT INTO Students (Name) VALUES ('Robert''); DROP TABLE Students;--')

Of course you can also use functions from other packages. Specifically for SQL I advise you to take a look at the dbplyr::build_sql function.

infuse(sql, name = name, transform_function = dbplyr::build_sql)

## Warning: Installed Rcpp (0.12.12) different from Rcpp used to build dplyr (0.12.11).
## Please reinstall dplyr to avoid random crashes or undefined behavior.

## INSERT INTO Students (Name) VALUES ('Robert''); DROP TABLE Students;--')

Issues / questions

Simply create a new issue at this GitHub repository.

Changes

v.0.2.8

  • added strict parameter to infuser, if set to TRUE will stop processing in case of incomplete set of supplied template parameters

v.0.2.7

  • change dpyr::build_sql to dbplyr::build_sql

v.0.2.6

  • set readLines's warn parameter to FALSE

v.0.2.5

  • fixed bug/typo related to #10

v.0.2.4

  • fixed testing to adhere to new testthat standards

v.0.2.2

  • dropped key_value_list parameter (will be interpreted automatically)
  • fixed passing of the variable_identifier
  • ability to make variable_identifier persistent

v.0.2.1

  • fixed: incorrect replacement of parameters with same prefix

v.0.2.0

  • consolidating adjustments and releasing version on CRAN

v.0.1.4

  • updated print function for output of infuse (uses cat for now on)

v0.1.3

  • added optional collapse_char argument to infuse command

v0.1.2

  • added optional key_value_list argument to infuse command

v0.1.1

  • added optional transform_function argument to infuse command