(This isn't strictly speaking a shiny question, just seemed like the closest thing).
We want to build an htmlwidget foo
, which works on the basis of already prepared HTML.
This HTML is prepared at "compile" time (say, rmarkdown::render_...()
, or even shinyapps::deploy...()
), and will never need to change dynamically.
We prepare this HTML via htmltools, and it's an htmltools::tagList()
.
At runtime (be that shiny, or just a static html from rmarkdown), we do want the usual htmlwidget bells and whistles, say, some js action on some element, and this action should be programmatically defined by our foo
htmlwidget. (So we're thinking this really is an htmlwidget use case).
The problem is that we can't seem to find a good way to pass the HTML on to our foo
widget, on which the js can then work.
From perusing the docs, we find a couple of alternatives, most of which seem not to apply here:
-
foo.yaml
dependencies:
accepts arbitrary HTML in viahtmltools::htmlDependency()
, but this is static throughout any release of the package, so cannot be altered at compile time (of an rmarkdown document). -
htmlwidgets::createWidget(..., dependencies = , ...)
(also viahtmltools::htmlDependency()
) can be altered at compile time, but being limited tohtmltools::htmlDependency(..., head =, ...)
it only allows us to place HTML into the document head (or, apparently, the beginning of the body), which is nonsensical. - Then there's the "magically named"
foo_html.R
(for anyfoo
htmlwidget), but upon inspection of the source does not pass on...
arguments, and so we can't "reach" it with any compile-time arguments. It seems like a hack-fix anyway, and is clearly meant for a different, simpler purpose (replacing the widget parent, say<span>
for<div>
). -
htmlwidget::prependContent()
can, well, prepend/append content to a widget, but a) pre/append position isn't really what we're looking for and b) the docs warn that this wouldn't work from inside shiny (which is a deal-breaker). - I guess that, theoretically, we could pass HTML as a string (
htmltools::doRender()
) of ourhtmltools::tagList()
result) tohtmlwidget::createWidget(x = list(foo_string = foo_string), ...)
, have that transformed to JSON, and then write it out again via some simple JS. We haven't tried this, but this sounds kind of gross. - Obviously, we could do it the way of most JS libraries which are wrapped by htmlwidgets and just write our custom HTML in JavaScript, and pass any necessary arguments to
htmlwidgets::createWidget(x = list(...), ...)
, but we're not great in js, and have our coolhtmltools::tagList()
already.
We've tried 1-3 (and failed).
4 is too limited.
5 seems weird.
6 would duplicate existing work.
The concrete use case here is a custom table (including hex tesselation and other special sauce), to which we'd like to add some JS interaction.
How are we doing this wrong?