Masalah
Ketika secara dinamis membuat elemen ui ( shiny.tag
,, shiny.tag.list
...), saya sering merasa sulit untuk memisahkannya dari logika kode saya dan biasanya berakhir dengan kekacauan bersarang tags$div(...)
, dicampur dengan loop dan pernyataan kondisional. Meskipun menjengkelkan dan jelek untuk dilihat, itu juga rawan kesalahan, misalnya ketika membuat perubahan ke html-templates.
Contoh yang bisa direproduksi
Katakanlah saya memiliki struktur data berikut:
my_data <- list(
container_a = list(
color = "orange",
height = 100,
content = list(
vec_a = c(type = "p", value = "impeach"),
vec_b = c(type = "h1", value = "orange")
)
),
container_b = list(
color = "yellow",
height = 50,
content = list(
vec_a = c(type = "p", value = "tool")
)
)
)
Jika sekarang saya ingin mendorong struktur ini menjadi ui-tag, saya biasanya berakhir dengan sesuatu seperti:
library(shiny)
my_ui <- tagList(
tags$div(
style = "height: 400px; background-color: lightblue;",
lapply(my_data, function(x){
tags$div(
style = paste0("height: ", x$height, "px; background-color: ", x$color, ";"),
lapply(x$content, function(y){
if (y[["type"]] == "h1") {
tags$h1(y[["value"]])
} else if (y[["type"]] == "p") {
tags$p(y[["value"]])
}
})
)
})
)
)
server <- function(input, output) {}
shinyApp(my_ui, server)
Seperti yang Anda lihat, ini sudah sangat berantakan dan masih tidak seberapa dibandingkan dengan contoh nyata saya.
Solusi yang diinginkan
Saya berharap menemukan sesuatu yang dekat dengan mesin templating untuk R, yang akan memungkinkan untuk mendefinisikan template dan data secara terpisah :
# syntax, borrowed from handlebars.js
my_template <- tagList(
tags$div(
style = "height: 400px; background-color: lightblue;",
"{{#each my_data}}",
tags$div(
style = "height: {{this.height}}px; background-color: {{this.color}};",
"{{#each this.content}}",
"{{#if this.content.type.h1}}",
tags$h1("this.content.type.h1.value"),
"{{else}}",
tags$p(("this.content.type.p.value")),
"{{/if}}",
"{{/each}}"
),
"{{/each}}"
)
)
Upaya sebelumnya
Pertama, saya pikir itu shiny::htmlTemplate()
bisa menawarkan solusi, tetapi ini hanya akan bekerja dengan file dan string teks, bukan shiny.tag
s. Saya juga telah melihat beberapa paket-r seperti kumis
, tetapi mereka tampaknya memiliki batasan yang sama dan tidak mendukung tag atau struktur daftar.
Terima kasih!
htmlTemplate()
akan memungkinkan untuk conditional dan loop ala setang, kumis, ranting ...
www
folder dan kemudian menerapkan style sheet?