john
john

Reputation: 1036

lapply in three dots construct in function

I am trying to implement lapply over 3 dots construct of user defined function. Somehow it is not working.

banner <- function(maintext,..., subtext = NULL) {
  
  if(length(list(...)) > 0) {
    
    dots <- lapply(X = list(...), FUN = function(x) tags$div(x))
    } else {
      dots <-  ''
    }
  
  HTML(paste0(
    
    "<div class='bannerbackground'> <h2>", maintext, "</h2>", 
              
  # If subtext specified
  ifelse(!is.null(subtext), paste0("<span>", subtext, "</span>", dots, "</div>"), paste0(dots, "</div>"))
              
  ))

}

banner('T1', 'T2', 'T3', subtext = 'T4')

Output I am expecting

<div class='bannerbackground'> <h2>T1</h2><span>T4</span>
<div>T2</div>
<div>T3</div>
</div>

Upvotes: 1

Views: 133

Answers (1)

Allan Cameron
Allan Cameron

Reputation: 173793

There's nothing wrong with your use of dots. Your problem is in trying to pass a list of html tags into a paste function. Since you are ultimately building a string, these need to be converted to character and pasted in as a vector, not a list. Therefore you want sapply instead of lapply:

banner <- function(maintext,..., subtext) {

  dots <- if(length(list(...))) sapply(list(...), function(x) as.character(tags$div(x)))
          else character()
  dots <- paste0("    ", dots, "\n", collapse = "")

  subtext <- if(!missing(subtext)) paste0("    <span>", subtext, "</span>\n") else ""
  
  HTML(paste0("<div class='bannerbackground'>\n  <h2>", 
              maintext, 
              "</h2>\n", 
              subtext, 
              dots, 
              "</div>\n")
      )
}

Which gives a nicely formatted output:

banner('T1', 'T2', 'T3', subtext = 'T4')
#> <div class='bannerbackground'>
#>   <h2>T1</h2>
#>     <span>T4</span>
#>     <div>T2</div>
#>     <div>T3</div>
#> </div>

Incidentally, note I have changed is.null to missing

Upvotes: 2

Related Questions