Specific twitter timeline uiOutput to be reactive in r Shiny

212 views Asked by At

I read all the threads about dynamic ui within the Shiny framework, but I did not find anything that work. I want to display a twitter timeline. This chunk of code works really well :

library(shiny)
library(shinydashboard)

runApp(list(ui = fluidPage(
  tags$head(tags$script('!function(d,s,id){var js,fjs=d.getElementsByTagName(s)    [0],p=/^http:/.test(d.location)?\'http\':\'https\';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");')),
  titlePanel(""),
  sidebarLayout(
    sidebarPanel()
    , mainPanel(
      a("Tweets by Andrew Ng",
        class="twitter-timeline",
        href = "https://twitter.com/AndrewYNg"
      )
    )
  )
)
, server = function(input, output, session){

}
)
)

But when, I try to make it reactive, I only got a link to the twitter timeline:

library(shiny)
library(shinydashboard)
runApp(list(ui = fluidPage(
  tags$head(tags$script('!function(d,s,id){var js,fjs=d.getElementsByTagName(s)    [0],p=/^http:/.test(d.location)?\'http\':\'https\';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");')),
  titlePanel(""),
  sidebarLayout(
    sidebarPanel()
    , mainPanel(
      uiOutput("mytimeline")
    )
  )
)
, server = function(input, output, session){

  output$mytimeline <- renderUI({
    a("Tweets by Andrew Ng",
      class="twitter-timeline",
      href = "https://twitter.com/AndrewYNg"
    )
  })



}
)
)
1

There are 1 answers

2
greg L On

The Twitter script only loads embedded content when it runs the first time. Since the script is in static UI but the timeline is in dynamic UI, the script will always run before the timeline is inserted.

The Twitter docs have a section about this: https://dev.twitter.com/web/javascript/initialization

You can run twttr.widgets.load() to scan the page for newly added embedded content.

One way to run execute this when inserting embedded content would be to include it in a script tag:

library(shiny)

twitterTimeline <- function(href, ...) {
  tagList(
    tags$a(class = "twitter-timeline", href = href, ...),
    tags$script("twttr.widgets.load()")
  )
}

runApp(list(ui = fluidPage(
  tags$head(tags$script('!function(d,s,id){var js,fjs=d.getElementsByTagName(s)    [0],p=/^http:/.test(d.location)?\'http\':\'https\';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");')),
  titlePanel(""),
  sidebarLayout(
    sidebarPanel()
    , mainPanel(
      uiOutput("mytimeline")
    )
  )
)
,
server = function(input, output, session) {

  output$mytimeline <- renderUI({
    twitterTimeline("https://twitter.com/AndrewYNg", "Tweets by Andrew Ng")
  })
}
))

See How to enable syntax highlighting in R Shiny app with htmlOutput for a similar issue with more details