2

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?

Amit Kohli
  • 2,860
  • 2
  • 24
  • 44

1 Answers1

2

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!

Florian
  • 24,425
  • 4
  • 49
  • 80