edwindj / whisker

{{mustache}} for R

Home Page:https://mustache.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

It's not clear how to use whisker to iteratively generate text

francisbarton opened this issue · comments

I am new to whisker but my assumption with a template is that its main purpose is to be used when iterating over a vector or list. (If you just want output of length 1 you'd just write the output directly).

But I can't work out how to feed a set of lists (eg a tibble) as the environment for whisker - the documentation isn't clear enough for me. Here's a reprex of what I'm trying. I've used purrr::pmap to show what I want, and then tried to achieve the equivalent with whisker.

suppressPackageStartupMessages(library(dplyr))
suppressPackageStartupMessages(library(stringr))
suppressPackageStartupMessages(library(purrr))
suppressPackageStartupMessages(library(whisker))

df <- tibble(
  name = c("Adam", "Barbara", "Chris"),
  home = c("Aylesbury", "Blackburn", "Coxwold"),
  url = c("adamsapples.co.uk", "barbsberries.co.uk", "coxwoldcherries.co.uk")
)

# with purrr and stringr
purrr::pmap_chr(df, ~ stringr::str_glue(
  "<li><a href=\"{..3}\">{..1} from {..2}</a></li>")) %>% 
  str_c(collapse = "\n") %>% 
  str_c("<ul>\n", ., "\n</ul>")
#> [1] "<ul>\n<li><a href=\"adamsapples.co.uk\">Adam from Aylesbury</a></li>\n<li><a href=\"barbsberries.co.uk\">Barbara from Blackburn</a></li>\n<li><a href=\"coxwoldcherries.co.uk\">Chris from Coxwold</a></li>\n</ul>"
# writeLines(output, "output.html")

# with whisker
templ <- "<li>
<a href=\"{{url}}\">{{name}} from {{home}}</a>
</li>"

# expected this to work but doesn't
whisker::whisker.render(templ, df)
#> [1] "<li>\n<a href=\"adamsapples.co.uk,barbsberries.co.uk,coxwoldcherries.co.uk\">Adam,Barbara,Chris from Aylesbury,Blackburn,Coxwold</a>\n</li>"

# trying with pmap instead - gives error
purrr::pmap_chr(df, ~ whisker::whisker.render(templ, .))
#> Error in value[[key]]: subscript out of bounds

Created on 2020-03-20 by the reprex package (v0.3.0)

Thanks for trying whisker!
One way to render what you want with whisker is:

library(whisker)
library(tibble)

df <- tibble(
  name = c("Adam", "Barbara", "Chris"),
  home = c("Aylesbury", "Blackburn", "Coxwold"),
  url = c("https://github.com/edwindj/whisker/issues/adamsapples.co.uk" target="_blank" rel="nofollow", "barbsberries.co.uk", "coxwoldcherries.co.uk")
)

# split a data.frame in list of rows.
person <- rowSplit(df)

# create a mustache section
templ <- 
"{{#person}}
<li>
  <a href=\"{{url}}\">{{name}} from {{home}}</a>
</li>
{{/person}}"


txt <- whisker::whisker.render(templ, list(person = person))
cat(txt)
## <li>
##   <a href="adamsapples.co.uk">Adam from Aylesbury</a>
## </li>
## <li>
##   <a href="barbsberries.co.uk">Barbara from Blackburn</a>
## </li>
## <li>
##   <a href="coxwoldcherries.co.uk">Chris from Coxwold</a>
## </li>

Best,

Edwin

That's excellent - thank you Edwin. I want to come back to this and try to understand it better (I'm wondering whether rowwise() might be relevant) but for now I'm just going to post this to says thanks for the explanation/solution.