Search code examples
rshinynse

NSE on shiny.tag


A strange use case: I'm trying to allow the text specifier on a shiny tag to be changed, while remaining a shiny.tag.

So for example, this is the output I desire:

library(htmltools)
library(rlang)
tags$a("boom")
#> <a>boom</a>

Notice that this is a shiny tag:

class(tags$a("boom"))
#> [1] "shiny.tag"

What I want to do is be able to vary what HTML code gets assigned to the text (for example, assigning h2 rather than a. I would like to do this using NSE and need the output to stay a shiny.tag, not converted to character (so all the paste hacks are out).

This is how far I've gotten but can't seem to get it to work:

library(htmltools)
library(rlang)

textSorter <- function(c="a",text) {
  c=enquo(c)
  tags$p(UQE(c),text)
}

a <- textSorter(c = "h2",text="Success?")
a
#><p>
#>  h2
#>  Success?
#></p>

So that's close... at least I can get the tag into the output... but 2 problems, obviously, h2 is just text, not the wrapper function desired(p), and interestingly:

class(a)
#>Error in tags$UQE(c) : attempt to apply non-function

The output mysteriously has no class, but is still retaining it's NSE somehow?

Trying to push the text classifier directly into the tags$ argument yields:

textSorter <- function(c="a(",text) {
  c=enquo(c)
  tags$UQE(c)(text)
}

textSorter(c = "h2",text="Success?")
}
#> Error in textSorter(c = "h2", text = "Success?") : 
#>   attempt to apply non-function

Any tips?


Solution

  • I think you can use the tag function for this:

    textSorter <- function(c1="a",text) {
      tag(c1,text)
    }
    x=textSorter('h2','hello')
    

    Test if it works as expected:

    print(x)
    <h2>hello</h2>
    
    class(x)
    [1] "shiny.tag"
    

    With this information, it is also easy to change the tag of an existing shiny.tag:

    x = tags$a('hello!')
    changeTag <- function(x,y='a')
    {
      tag(y,x$children)
    }
    y <- changeTag(x,'p')
    

    And again, to verify:

    print(y)
    <p>hello!</p>
    class(y)
    [1] "shiny.tag"
    

    Hope this helps!