├── .Rbuildignore
├── .gitignore
├── CODE_OF_CONDUCT.md
├── DESCRIPTION
├── NAMESPACE
├── NEWS.md
├── R
├── app_server.R
├── app_ui.R
├── golem_utils_server.R
├── golem_utils_ui.R
├── mod_my_fifth_module.R
├── mod_my_first_module.R
├── mod_my_fourth_module.R
├── mod_my_other_module.R
├── mod_my_third_module.R
└── run_app.R
├── README.Rmd
├── README.md
├── data-raw
└── dataset.R
├── data
├── dataset.rda
└── plop.rda
├── dev
├── 01_start.R
├── 02_dev.R
├── 03_deploy.R
└── run_dev.R
├── golemexample.Rproj
├── inst
└── app
│ └── www
│ ├── alertme.js
│ ├── custom.css
│ ├── guit.jpg
│ ├── handlers.js
│ └── plop.md
├── man
├── mod_my_first_module.Rd
├── mod_my_fourth_module.Rd
├── mod_my_other_module.Rd
├── mod_my_third_module.Rd
└── run_app.Rd
└── tests
├── testthat.R
└── testthat
└── test-golem-recommended.R
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^.*\.Rproj$
2 | ^\.Rproj\.user$
3 | ^data-raw$
4 | dev_history.R
5 | ^dev$
6 | $run_dev.*
7 | ^README\.Rmd$
8 | ^CODE_OF_CONDUCT\.md$
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .Rproj.user
2 | .Rhistory
3 | .RData
4 | .Ruserdata
5 | inst/doc
6 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Code of Conduct
2 |
3 | As contributors and maintainers of this project, we pledge to respect all people who
4 | contribute through reporting issues, posting feature requests, updating documentation,
5 | submitting pull requests or patches, and other activities.
6 |
7 | We are committed to making participation in this project a harassment-free experience for
8 | everyone, regardless of level of experience, gender, gender identity and expression,
9 | sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
10 |
11 | Examples of unacceptable behavior by participants include the use of sexual language or
12 | imagery, derogatory comments or personal attacks, trolling, public or private harassment,
13 | insults, or other unprofessional conduct.
14 |
15 | Project maintainers have the right and responsibility to remove, edit, or reject comments,
16 | commits, code, wiki edits, issues, and other contributions that are not aligned to this
17 | Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed
18 | from the project team.
19 |
20 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by
21 | opening an issue or contacting one or more of the project maintainers.
22 |
23 | This Code of Conduct is adapted from the Contributor Covenant
24 | (https://www.contributor-covenant.org), version 1.0.0, available at
25 | https://contributor-covenant.org/version/1/0/0/.
26 |
--------------------------------------------------------------------------------
/DESCRIPTION:
--------------------------------------------------------------------------------
1 | Package: golemexample
2 | Title: Golem Example
3 | Version: 0.0.0.9000
4 | Authors@R: person('Colin', 'Fay', email = 'contact@colinfay.me', role = c('cre', 'aut'))
5 | Description: A Package to show the basics of a golem.
6 | License: What license is it under?
7 | Encoding: UTF-8
8 | LazyData: true
9 | Imports:
10 | shiny,
11 | golem,
12 | processx,
13 | attempt,
14 | DT,
15 | glue,
16 | htmltools
17 | Remotes:
18 | Thinkr-open/golem
19 | RoxygenNote: 6.1.1
20 | URL: https://github.com/colinfay/golemexample
21 | BugReports: https://github.com/colinfay/golemexample/issues
22 | Suggests:
23 | testthat
24 |
--------------------------------------------------------------------------------
/NAMESPACE:
--------------------------------------------------------------------------------
1 | # Generated by roxygen2: do not edit by hand
2 |
3 | export(mod_my_first_module_server)
4 | export(mod_my_first_module_ui)
5 | export(mod_my_fourth_module_server)
6 | export(mod_my_fourth_module_ui)
7 | export(mod_my_other_module_server)
8 | export(mod_my_other_module_ui)
9 | export(mod_my_third_module_server)
10 | export(mod_my_third_module_ui)
11 | export(run_app)
12 | import(golem)
13 | import(shiny)
14 | importFrom(glue,glue)
15 | importFrom(golem,with_golem_options)
16 | importFrom(htmltools,HTML)
17 | importFrom(htmltools,tagAppendAttributes)
18 | importFrom(htmltools,tagList)
19 | importFrom(htmltools,tags)
20 | importFrom(shiny,NS)
21 | importFrom(shiny,column)
22 | importFrom(shiny,shinyApp)
23 | importFrom(shiny,tagList)
24 |
--------------------------------------------------------------------------------
/NEWS.md:
--------------------------------------------------------------------------------
1 | # golemexample 0.0.0.9000
2 |
3 | * Added a `NEWS.md` file to track changes to the package.
4 |
--------------------------------------------------------------------------------
/R/app_server.R:
--------------------------------------------------------------------------------
1 | #' @import shiny
2 | #' @import golem
3 | app_server <- function(input, output,session) {
4 | # List the first level callModules here
5 | print(get_golem_options("time"))
6 | r <- reactiveValues()
7 | callModule(mod_my_first_module_server, "my_first_module_ui_1")
8 | callModule(mod_my_other_module_server, "my_other_module_ui_1", r)
9 | callModule(mod_my_third_module_server, "my_third_module_ui_1", r)
10 | callModule(mod_my_fourth_module_server, "my_fourth_module_ui_1")
11 | }
12 |
--------------------------------------------------------------------------------
/R/app_ui.R:
--------------------------------------------------------------------------------
1 | #' @import shiny
2 | app_ui <- function() {
3 | tagList(
4 | # Leave this function for adding external resources
5 | golem_add_external_resources(),
6 | # List the first level UI elements here
7 | fluidPage(
8 | h1(get_golem_options("name")),
9 | mod_my_first_module_ui("my_first_module_ui_1"),
10 | col_12(
11 | br()
12 | ),
13 | col_6(
14 | mod_my_other_module_ui("my_other_module_ui_1") %>% div(align = "center")
15 | ),
16 | col_6(
17 | mod_my_third_module_ui("my_third_module_ui_1") %>% div(align = "center")
18 | ),
19 | col_6(
20 | mod_my_fourth_module_ui("my_fourth_module_ui_1") %>% div(align = "center")
21 | ),
22 | col_6(
23 | mod_my_fifth_module_ui("my_fifth_module_ui_1") %>% div(align = "left")
24 | )
25 | )
26 | )
27 | }
28 |
29 | #' @import shiny
30 | golem_add_external_resources <- function(){
31 |
32 | addResourcePath(
33 | 'www', system.file('app/www', package = 'golemexample')
34 | )
35 |
36 | tags$head(
37 | golem::activate_js(),
38 | golem::favicon(),
39 | # Add here all the external resources
40 | # If you have a custom.css in the inst/app/www
41 | # Or for example, you can add shinyalert::useShinyalert() here
42 | tags$link(rel="stylesheet", type="text/css", href="www/custom.css"),
43 | tags$script(src="www/alertme.js"),
44 | tags$script(src="www/handlers.js")
45 | )
46 | }
47 |
--------------------------------------------------------------------------------
/R/golem_utils_server.R:
--------------------------------------------------------------------------------
1 | # Inverted versions of in, is.null and is.na
2 | `%not_in%` <- Negate(`%in%`)
3 |
4 | not_null <- Negate(is.null)
5 |
6 | not_na <- Negate(is.na)
7 |
8 | # Removes the null from a vector
9 | drop_nulls <- function(x){
10 | x[!sapply(x, is.null)]
11 | }
12 |
13 | # If x is null, return y, otherwise return x
14 | "%||%" <- function(x, y){
15 | if (is.null(x)) {
16 | y
17 | } else {
18 | x
19 | }
20 | }
21 | # If x is NA, return y, otherwise return x
22 | "%|NA|%" <- function(x, y){
23 | if (is.na(x)) {
24 | y
25 | } else {
26 | x
27 | }
28 | }
29 |
30 | # typing reactiveValues is too long
31 | rv <- shiny::reactiveValues
32 | rvtl <- shiny::reactiveValuesToList
--------------------------------------------------------------------------------
/R/golem_utils_ui.R:
--------------------------------------------------------------------------------
1 | # Turn an R list into an HTML list
2 | #
3 | # @param list An R list
4 | # @param class a class for the list
5 | # @return an HTML list
6 | # @examples
7 | # list_to_li(c("a","b"))
8 | #
9 | #' @importFrom htmltools tags tagAppendAttributes tagList
10 | list_to_li <- function(list, class = NULL){
11 | if (is.null(class)){
12 | tagList(lapply(list, tags$li))
13 | } else {
14 | res <- lapply(list, tags$li)
15 | res <- lapply(res, function(x) tagAppendAttributes(x, class = class))
16 | tagList(res)
17 | }
18 |
19 | }
20 |
21 | #' @importFrom htmltools tags tagAppendAttributes tagList
22 | list_to_p <- function(list, class = NULL){
23 | if (is.null(class)){
24 | tagList(lapply(list, tags$p))
25 | } else {
26 | res <- lapply(list, tags$p)
27 | res <- lapply(res, function(x) tagAppendAttributes(x, class = class))
28 | tagList(res)
29 | }
30 |
31 | }
32 |
33 | #' @importFrom glue glue
34 | #' @importFrom htmltools tags tagAppendAttributes tagList
35 | named_to_li <- function(list, class = NULL){
36 | if(is.null(class)){
37 | res <- mapply(
38 | function(x, y){
39 | tags$li(HTML(glue("{y}: {x}")))
40 | },
41 | list, names(list), SIMPLIFY = FALSE)
42 | #res <- lapply(res, HTML)
43 | tagList(res)
44 | } else {
45 | res <- mapply(
46 | function(x, y){
47 | tags$li(HTML(glue("{y}: {x}")))
48 | },
49 | list, names(list), SIMPLIFY = FALSE)
50 | res <- lapply(res, function(x) tagAppendAttributes(x, class = class))
51 | tagList(res)
52 | }
53 | }
54 |
55 | # Remove a tag attribute
56 | #
57 | # @param tag the tag
58 | # @param ... the attributes to remove
59 | #
60 | # @return a new tag
61 | # @export
62 | #
63 | # @examples
64 | # a <- shiny::tags$p(src = "plop", "pouet")
65 | # tagRemoveAttributes(a, "src")
66 | tagRemoveAttributes <- function(tag, ...) {
67 | attrs <- as.character(list(...))
68 | for (i in seq_along(attrs)) {
69 | tag$attribs[[ attrs[i] ]] <- NULL
70 | }
71 | tag
72 | }
73 |
74 | # Hide or display a tag
75 | # @param tag the tag
76 | # @return a tag
77 | # @examples
78 | # ## Hide
79 | # a <- shiny::tags$p(src = "plop", "pouet")
80 | # undisplay(a)
81 | # b <- shiny::actionButton("go_filter", "go")
82 | # undisplay(b)
83 |
84 | #' @importFrom htmltools tagList
85 | undisplay <- function(tag) {
86 | # if not already hidden
87 | if (!is.null(tag$attribs$style) && !grepl("display:\\s+none", tag$attribs$style)) {
88 | tag$attribs$style <- paste("display: none;", tag$attribs$style)
89 | } else {
90 | tag$attribs$style <- "display: none;"
91 | }
92 | tag
93 | }
94 |
95 | #' @importFrom htmltools tagList
96 | display <- function(tag) {
97 | if (!is.null(tag$attribs$style) && grepl("display:\\s+none", tag$attribs$style)) {
98 | tag$attribs$style <- gsub("(\\s)*display:(\\s)*none(\\s)*(;)*(\\s)*", "", tag$attribs$style)
99 | }
100 | tag
101 | }
102 |
103 | # Hide an elements by calling jquery hide on it
104 | #' @importFrom htmltools tags
105 | jq_hide <- function(id) {
106 | tags$script(sprintf("$('#%s').hide()", id))
107 | }
108 |
109 | # Add a red star at the end of the text
110 | #
111 | # Adds a red star at the end of the text
112 | # (for example for indicating mandatory fields).
113 | #
114 | # @param text the HTLM text to put before the red star
115 | #
116 | # @return an html element
117 | #
118 | # @examples
119 | # with_red_star("Enter your name here")
120 | #
121 | #' @importFrom htmltools tags HTML
122 | with_red_star <- function(text) {
123 | htmltools::tags$span(
124 | HTML(
125 | paste0(
126 | text,
127 | htmltools::tags$span(
128 | style = "color:red", "*"
129 | )
130 | )
131 | )
132 | )
133 | }
134 |
135 |
136 |
137 | # Repeat tags$br
138 | #
139 | # @param times the number of br to return
140 | #
141 | # @return the number of br specified in times
142 | # @export
143 | #
144 | # @examples
145 | # rep_br(5)
146 | #
147 | #' @importFrom htmltools HTML
148 | rep_br <- function(times = 1) {
149 | HTML(rep("
", times = times))
150 | }
151 |
152 | # Create an url
153 | #
154 | # @param url the URL
155 | # @param text the text to display
156 | #
157 | # @return an a tag
158 | # @export
159 | #
160 | # @examples
161 | # enurl("https://www.thinkr.fr", "ThinkR")
162 | enurl <- function(url, text){
163 | tags$a(href = url, text)
164 | }
165 |
166 |
167 | # Columns 12, 6 and 4
168 | #
169 | # Most shiny columns are 12, 6 or 4 of width.
170 | # These are convenient wrappers around
171 | # `column(12, ...)`, `column(6, ...)` and `column(4, ...)`.
172 | #
173 | # @export
174 | # @rdname columns
175 | #' @importFrom shiny column
176 | col_12 <- function(...){
177 | column(12, ...)
178 | }
179 |
180 | #' @importFrom shiny column
181 | col_6 <- function(...){
182 | column(6, ...)
183 | }
184 |
185 | #' @importFrom shiny column
186 | col_4 <- function(...){
187 | column(4, ...)
188 | }
189 |
--------------------------------------------------------------------------------
/R/mod_my_fifth_module.R:
--------------------------------------------------------------------------------
1 | # Module UI
2 |
3 | #' @title mod_my_fifth_module_ui and mod_my_fifth_module_server
4 | #' @description A shiny Module.
5 | #'
6 | #' @param id shiny id
7 | #' @param input internal
8 | #' @param output internal
9 | #' @param session internal
10 | #'
11 | #' @rdname mod_my_fifth_module
12 | #'
13 | #' @keywords internal
14 | #' @export
15 | #' @importFrom shiny NS tagList
16 | mod_my_fifth_module_ui <- function(id){
17 | ns <- NS(id)
18 | tagList(
19 | includeMarkdown(
20 | system.file("app/www/plop.md", package = "golemexample")
21 | )
22 | )
23 | }
24 |
25 | # Module Server
26 |
27 | #' @rdname mod_my_fifth_module
28 | #' @export
29 | #' @keywords internal
30 |
31 | mod_my_fifth_module_server <- function(input, output, session){
32 | ns <- session$ns
33 | }
34 |
35 | ## To be copied in the UI
36 | #
37 |
38 | ## To be copied in the server
39 | # callModule(mod_my_fifth_module_server, "my_fifth_module_ui_1")
40 |
41 |
--------------------------------------------------------------------------------
/R/mod_my_first_module.R:
--------------------------------------------------------------------------------
1 | # Module UI
2 |
3 | #' @title mod_my_first_module_ui and mod_my_first_module_server
4 | #' @description A shiny Module.
5 | #'
6 | #' @param id shiny id
7 | #' @param input internal
8 | #' @param output internal
9 | #' @param session internal
10 | #'
11 | #' @rdname mod_my_first_module
12 | #'
13 | #' @keywords internal
14 | #' @export
15 | #' @importFrom shiny NS tagList
16 | mod_my_first_module_ui <- function(id){
17 | ns <- NS(id)
18 | tagList(
19 | col_6(
20 | tags$div(
21 | align = "center",
22 | tags$img(
23 | src = "www/guit.jpg", width = "50%", align = "center"
24 | )
25 | )
26 | ),
27 | col_6(
28 | tableOutput(ns("df"))
29 | ),
30 | col_6(
31 | tags$div(
32 | align = "center",
33 | tags$button("Alert!", onclick = "alertme();")
34 | )
35 | ),
36 | col_6(
37 | tags$div(
38 | align = "center",
39 | actionButton(ns("go"), "Go!")
40 | )
41 | )
42 | )
43 | }
44 |
45 | # Module Server
46 |
47 | #' @rdname mod_my_first_module
48 | #' @export
49 | #' @keywords internal
50 |
51 | mod_my_first_module_server <- function(input, output, session, r){
52 | ns <- session$ns
53 | output$df <- renderTable({
54 | dataset
55 | })
56 |
57 | observeEvent( input$go , {
58 | golem::invoke_js("alertarg", "12")
59 | })
60 |
61 | }
62 |
63 |
--------------------------------------------------------------------------------
/R/mod_my_fourth_module.R:
--------------------------------------------------------------------------------
1 | # Module UI
2 |
3 | #' @title mod_my_fourth_module_ui and mod_my_fourth_module_server
4 | #' @description A shiny Module.
5 | #'
6 | #' @param id shiny id
7 | #' @param input internal
8 | #' @param output internal
9 | #' @param session internal
10 | #'
11 | #' @rdname mod_my_fourth_module
12 | #'
13 | #' @keywords internal
14 | #' @export
15 | #' @importFrom shiny NS tagList
16 | mod_my_fourth_module_ui <- function(id){
17 | #browser()
18 | ns <- NS(id)
19 | tagList(
20 | h2(
21 | names(plop)
22 | ),
23 | verbatimTextOutput(ns("fruits"))
24 | )
25 | }
26 |
27 | # Module Server
28 |
29 | #' @rdname mod_my_fourth_module
30 | #' @export
31 | #' @keywords internal
32 |
33 | mod_my_fourth_module_server <- function(input, output, session){
34 | ns <- session$ns
35 | output$fruits <- renderPrint({
36 | plop
37 | })
38 | }
39 |
40 | ## To be copied in the UI
41 | #
42 |
43 | ## To be copied in the server
44 | #
45 |
46 |
--------------------------------------------------------------------------------
/R/mod_my_other_module.R:
--------------------------------------------------------------------------------
1 | # Module UI
2 |
3 | #' @title mod_my_other_module_ui and mod_my_other_module_server
4 | #' @description A shiny Module.
5 | #'
6 | #' @param id shiny id
7 | #' @param input internal
8 | #' @param output internal
9 | #' @param session internal
10 | #'
11 | #' @rdname mod_my_other_module
12 | #'
13 | #' @keywords internal
14 | #' @export
15 | #' @importFrom shiny NS tagList
16 | mod_my_other_module_ui <- function(id){
17 | ns <- NS(id)
18 | tagList(
19 | col_12(
20 | h3("Collecting value here in r"),
21 | selectInput(ns("which"), "Which ?", c("iris", "mtcars", "airquality"))
22 | )
23 | )
24 | }
25 |
26 | # Module Server
27 |
28 | #' @rdname mod_my_other_module
29 | #' @export
30 | #' @keywords internal
31 |
32 | mod_my_other_module_server <- function(input, output, session, r){
33 | ns <- session$ns
34 |
35 | r$my_other_module <- reactiveValues()
36 |
37 | observeEvent( input$which , {
38 | r$my_other_module$which <- input$which
39 | })
40 |
41 |
42 | }
43 |
44 | ## To be copied in the UI
45 | #
46 |
47 | ## To be copied in the server
48 | #
49 |
50 |
--------------------------------------------------------------------------------
/R/mod_my_third_module.R:
--------------------------------------------------------------------------------
1 | # Module UI
2 |
3 | #' @title mod_my_third_module_ui and mod_my_third_module_server
4 | #' @description A shiny Module.
5 | #'
6 | #' @param id shiny id
7 | #' @param input internal
8 | #' @param output internal
9 | #' @param session internal
10 | #'
11 | #' @rdname mod_my_third_module
12 | #'
13 | #' @keywords internal
14 | #' @export
15 | #' @importFrom shiny NS tagList
16 | mod_my_third_module_ui <- function(id){
17 | ns <- NS(id)
18 | tagList(
19 | tableOutput(ns("df"))
20 | )
21 | }
22 |
23 | # Module Server
24 |
25 | #' @rdname mod_my_third_module
26 | #' @export
27 | #' @keywords internal
28 |
29 | mod_my_third_module_server <- function(input, output, session, r){
30 | ns <- session$ns
31 | output$df <- renderTable({
32 | print(r$my_other_module$which)
33 | head(get(r$my_other_module$which), 10)
34 | })
35 | }
36 |
37 | ## To be copied in the UI
38 | #
39 |
40 | ## To be copied in the server
41 | #
42 |
43 |
--------------------------------------------------------------------------------
/R/run_app.R:
--------------------------------------------------------------------------------
1 | #' Run the Shiny Application
2 | #'
3 | #' @export
4 | #' @importFrom shiny shinyApp
5 | #' @importFrom golem with_golem_options
6 | run_app <- function(
7 | name = "example",
8 | time = Sys.time(),
9 | port = 2811
10 | ) {
11 | with_golem_options(
12 | app = shinyApp(ui = app_ui,
13 | server = app_server,
14 | options = list(port = port)),
15 | golem_opts = list(name = name, time = time)
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/README.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | output: github_document
3 | ---
4 |
5 |
6 |
7 | ```{r, include = FALSE}
8 | knitr::opts_chunk$set(
9 | collapse = TRUE,
10 | comment = "#>",
11 | fig.path = "man/figures/README-",
12 | out.width = "100%"
13 | )
14 | ```
15 | # golemexample
16 |
17 |
18 | [](https://www.tidyverse.org/lifecycle/#experimental)
19 |
20 |
21 | The goal of golemexample is to provide some examples for the inner configuration of a `{golem}` app.
22 |
23 | ## Share value across modules
24 |
25 | + Add a top level reactiveValue
26 |
27 | + Add a nested level inside modules
28 |
29 | + Share this across modules
30 |
31 | ## Change Shiny Options
32 |
33 |
34 |
35 | ## Adding external files
36 |
37 | ### CSS
38 |
39 | + Added with `dev/02_dev.R#29`
40 |
41 | + Personnalized in `inst/app/www/custom.css`
42 |
43 | + Linked to the app at `R/app_ui.R#27`
44 |
45 | ### JS
46 |
47 | #### Classic
48 |
49 | __A simple JS can be used from UI.__
50 |
51 | + Added with `dev/02_dev.R#27`
52 |
53 | + Personnalized in `inst/app/www/alertme.js`
54 |
55 | + Linked to the app at `R/app_ui.R#28`
56 |
57 | + Called with `tags$button("Alert!", onclick = "alertme();")` at `R/mod_my_first_module.R#33`
58 |
59 | #### Handlers
60 |
61 | __A handler JS can be used from server side with `golem::invoke_js()`.__
62 |
63 | + Added with `dev/02_dev.R#28`
64 |
65 | + Personnalized in `inst/app/www/handler.js`
66 |
67 | + Linked to the app at `R/app_ui.R#29`
68 |
69 | + Called with `golem::invoke_js("alertarg", "12")` at `R/mod_my_first_module.R#58`
70 |
71 | ### Image
72 |
73 | + Downloaded at `inst/app/www/guit.jpg`
74 |
75 | + Linked with `tags$img(src = "www/guit.jpg")` at `R/mod_my_first_module.R#23`
76 |
77 | ## Passing arguments to `run_app`
78 |
79 | + `run_app`
80 |
81 | + Read in UI at `R/app_ui.R#8`
82 |
83 | + Read in server at `R/app_server.R#5`
84 |
85 | ## Using datasets inside your app
86 |
87 | + Register your dataset as a package data
88 | which is turned into
89 |
90 | + Use your data object wherever you need it (in your UI or server)
91 |
92 | ## Using shiny::includeXXX
93 |
94 | + Add elements in `inst/app/www`
95 |
96 | + Use `system.file("app/www/plop.md", package = "golemexample")`
97 |
98 |
99 |
100 | Please note that the 'golemexample' project is released with a
101 | [Contributor Code of Conduct](CODE_OF_CONDUCT.md).
102 | By contributing to this project, you agree to abide by its terms.
103 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # golemexample
5 |
6 |
7 |
8 | [](https://www.tidyverse.org/lifecycle/#experimental)
10 |
11 |
12 | The goal of golemexample is to provide some examples for the inner
13 | configuration of a `{golem}` app.
14 |
15 | ## Share value across modules
16 |
17 | - Add a top level reactiveValue
18 |
19 |
20 | - Add a nested level inside modules
21 |
22 |
23 | - Share this across modules
24 |
25 |
26 | ## Change Shiny Options
27 |
28 |
29 |
30 | ## Adding external files
31 |
32 | ### CSS
33 |
34 | - Added with `dev/02_dev.R#29`
35 |
36 |
37 | - Personnalized in `inst/app/www/custom.css`
38 |
39 |
40 | - Linked to the app at `R/app_ui.R#27`
41 |
42 |
43 | ### JS
44 |
45 | #### Classic
46 |
47 | **A simple JS can be used from UI.**
48 |
49 | - Added with `dev/02_dev.R#27`
50 |
51 |
52 | - Personnalized in `inst/app/www/alertme.js`
53 |
54 |
55 | - Linked to the app at `R/app_ui.R#28`
56 |
57 |
58 | - Called with `tags$button("Alert!", onclick = "alertme();")` at
59 | `R/mod_my_first_module.R#33`
60 |
61 |
62 | #### Handlers
63 |
64 | **A handler JS can be used from server side with `golem::invoke_js()`.**
65 |
66 | - Added with `dev/02_dev.R#28`
67 |
68 |
69 | - Personnalized in `inst/app/www/handler.js`
70 |
71 |
72 | - Linked to the app at `R/app_ui.R#29`
73 |
74 |
75 | - Called with `golem::invoke_js("alertarg", "12")` at
76 | `R/mod_my_first_module.R#58`
77 |
78 |
79 | ### Image
80 |
81 | - Downloaded at `inst/app/www/guit.jpg`
82 |
83 |
84 | - Linked with `tags$img(src = "www/guit.jpg")` at
85 | `R/mod_my_first_module.R#23`
86 |
87 |
88 | ## Passing arguments to `run_app`
89 |
90 | - `run_app`
91 |
92 |
93 | - Read in UI at `R/app_ui.R#8`
94 |
95 |
96 | - Read in server at `R/app_server.R#5`
97 |
98 |
99 | ## Using datasets inside your app
100 |
101 | - Register your dataset as a package data
102 |
103 | which is turned into
104 |
105 |
106 | - Use your data object wherever you need it (in your UI or server)
107 |
108 | ## Using shiny::includeXXX
109 |
110 | - Add elements in `inst/app/www`
111 |
112 |
113 | - Use `system.file("app/www/plop.md", package = "golemexample")`
114 |
115 |
116 |
117 |
118 | Please note that the ‘golemexample’ project is released with a
119 | [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By contributing to
120 | this project, you agree to abide by its terms.
121 |
--------------------------------------------------------------------------------
/data-raw/dataset.R:
--------------------------------------------------------------------------------
1 | ## code to prepare `dataset` dataset goes here
2 |
3 | dataset <- head(mtcars)
4 | usethis::use_data(dataset)
5 |
6 | plop <- list(
7 | fruits = stringr::fruit
8 | )
9 |
10 | usethis::use_data(plop)
11 |
--------------------------------------------------------------------------------
/data/dataset.rda:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ColinFay/golemexample/5fd5f72b74aa35bac78acc8f31e4a4fb150c17c6/data/dataset.rda
--------------------------------------------------------------------------------
/data/plop.rda:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ColinFay/golemexample/5fd5f72b74aa35bac78acc8f31e4a4fb150c17c6/data/plop.rda
--------------------------------------------------------------------------------
/dev/01_start.R:
--------------------------------------------------------------------------------
1 | # Building a Prod-Ready, Robust Shiny Application.
2 | #
3 | # Each step is optional.
4 | #
5 | # 1 - On init
6 | #
7 | ## 1.1 - Fill the descripion & set options
8 | ##
9 | ## Add information about the package that will contain your app
10 |
11 | golem::fill_desc(
12 | pkg_name = "golemexample", # The Name of the package containing the App
13 | pkg_title = "Golem Example", # The Title of the package containing the App
14 | pkg_description = "A Package to show the basics of a golem.", # The Description of the package containing the App
15 | author_first_name = "Colin", # Your First Name
16 | author_last_name = "Fay", # Your Last Name
17 | author_email = "contact@colinfay.me", # Your Email
18 | repo_url = "https://github.com/colinfay/golemexample" # The (optional) URL of the GitHub Repo
19 | )
20 |
21 | ## Use this desc to set {golem} options
22 |
23 | golem::set_golem_options()
24 |
25 | ## 1.2 - Set common Files
26 | ##
27 | ## If you want to use the MIT licence, README, code of conduct, lifecycle badge, and news
28 |
29 | usethis::use_mit_license( name = "Colin Fay" ) # You can set another licence here
30 | usethis::use_readme_rmd( open = FALSE )
31 | usethis::use_code_of_conduct()
32 | usethis::use_lifecycle_badge( "Experimental" )
33 |
34 | usethis::use_news_md( open = FALSE )
35 | usethis::use_git()
36 |
37 | ## 1.3 - Add a data-raw folder
38 | ##
39 | ## If you have data in your package
40 | usethis::use_data_raw( name = "dataset", open = FALSE ) # Change "my_dataset"
41 |
42 | ## 1.4 - Init Tests
43 | ##
44 | ## Create a template for tests
45 |
46 | golem::use_recommended_tests()
47 |
48 | ## 1.5 : Use Recommended Package
49 |
50 | golem::use_recommended_deps()
51 |
52 | ## 1.6 Add various tools
53 |
54 | # If you want to change the favicon (default is golem's one)
55 | golem::remove_favicon()
56 | golem::use_favicon("") # path = "path/to/ico". Can be an online file.
57 |
58 | # Add helper functions
59 | golem::use_utils_ui()
60 | golem::use_utils_server()
61 |
62 | # You're now set!
63 | # go to dev/02_dev.R
64 | rstudioapi::navigateToFile( "dev/02_dev.R" )
65 |
66 |
--------------------------------------------------------------------------------
/dev/02_dev.R:
--------------------------------------------------------------------------------
1 | # Building a Prod-Ready, Robust Shiny Application.
2 | #
3 | # Each step is optional.
4 | #
5 |
6 | # 2. All along your project
7 |
8 | ## 2.1 Add modules
9 | ##
10 | golem::add_module( name = "my_first_module" ) # Name of the module
11 | golem::add_module( name = "my_other_module" ) # Name of the module
12 | golem::add_module( name = "my_third_module" ) # Name of the module
13 | golem::add_module( name = "my_fourth_module" ) # Name of the module
14 |
15 | ## 2.2 Add dependencies
16 |
17 | usethis::use_package( "thinkr" ) # To call each time you need a new package
18 |
19 | ## 2.3 Add tests
20 |
21 | usethis::use_test( "app" )
22 |
23 | ## 2.4 Add a browser button
24 |
25 | golem::browser_button()
26 |
27 | ## 2.5 Add external files
28 |
29 | golem::add_js_file( "alertme" )
30 | golem::add_js_handler( "handlers" )
31 | golem::add_css_file( "custom" )
32 |
33 | # 3. Documentation
34 |
35 | ## 3.1 Vignette
36 | usethis::use_vignette("golemexample")
37 | devtools::build_vignettes()
38 |
39 | ## 3.2 Code coverage
40 | ## You'll need GitHub there
41 | usethis::use_github()
42 | usethis::use_travis()
43 | usethis::use_appveyor()
44 |
45 | # You're now set!
46 | # go to dev/03_deploy.R
47 | rstudioapi::navigateToFile("dev/03_deploy.R")
48 |
--------------------------------------------------------------------------------
/dev/03_deploy.R:
--------------------------------------------------------------------------------
1 | # Deploy a Prod-Ready, Robust Shiny Application.
2 | #
3 | # 4. Test my package
4 |
5 | devtools::test()
6 | rhub::check_for_cran()
7 |
8 | # 5. Deployment elements
9 |
10 | ## 5.1 If you want to deploy on RStudio related platforms
11 | golem::add_rstudioconnect_file()
12 | golem::add_shinyappsio_file()
13 | golem::add_shinyserver_file()
14 |
15 | ## 5.2 If you want to deploy via a generic Dockerfile
16 | golem::add_dockerfile()
17 |
18 | ## 5.2 If you want to deploy to ShinyProxy
19 | golem::add_dockerfile_shinyproxy()
20 |
21 | ## 5.2 If you want to deploy to Heroku
22 | golem::add_dockerfile_heroku()
23 |
--------------------------------------------------------------------------------
/dev/run_dev.R:
--------------------------------------------------------------------------------
1 | # Set options here
2 | options(golem.app.prod = FALSE) # TRUE = production mode, FALSE = development mode
3 |
4 | # Detach all loaded packages and clean your environment
5 | golem::detach_all_attached()
6 | # rm(list=ls(all.names = TRUE))
7 |
8 | # Document and reload your package
9 | golem::document_and_reload()
10 |
11 | # Run the application
12 | run_app()
13 |
--------------------------------------------------------------------------------
/golemexample.Rproj:
--------------------------------------------------------------------------------
1 | Version: 1.0
2 |
3 | RestoreWorkspace: Default
4 | SaveWorkspace: Default
5 | AlwaysSaveHistory: Default
6 |
7 | EnableCodeIndexing: Yes
8 | UseSpacesForTab: Yes
9 | NumSpacesForTab: 2
10 | Encoding: UTF-8
11 |
12 | RnwWeave: Sweave
13 | LaTeX: pdfLaTeX
14 |
15 | BuildType: Package
16 | PackageUseDevtools: Yes
17 | PackageInstallArgs: --no-multiarch --with-keep.source
18 |
--------------------------------------------------------------------------------
/inst/app/www/alertme.js:
--------------------------------------------------------------------------------
1 | alertme = function(){
2 | alert("simple js!");
3 | }
--------------------------------------------------------------------------------
/inst/app/www/custom.css:
--------------------------------------------------------------------------------
1 | h1 {
2 | color: pink;
3 | }
--------------------------------------------------------------------------------
/inst/app/www/guit.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ColinFay/golemexample/5fd5f72b74aa35bac78acc8f31e4a4fb150c17c6/inst/app/www/guit.jpg
--------------------------------------------------------------------------------
/inst/app/www/handlers.js:
--------------------------------------------------------------------------------
1 | $( document ).ready(function() {
2 | Shiny.addCustomMessageHandler('alertarg', function(arg) {
3 | alert(arg);
4 | })
5 | });
6 |
--------------------------------------------------------------------------------
/inst/app/www/plop.md:
--------------------------------------------------------------------------------
1 | ## An example of an included markdown
2 |
3 | Note that external markdown can be put in inst/app/www/ or anywhere inst/.
4 |
5 | `addResourcePath()` adds a link __available at runtime__, i.e while your app is served in your browser.
6 |
7 | Including an external JS or HTML is to be done like this:
8 |
9 | ``` r
10 | includeMarkdown(
11 | system.file("app/www/plop.md", package = "golemexample")
12 | )
13 | ```
--------------------------------------------------------------------------------
/man/mod_my_first_module.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/mod_my_first_module.R
3 | \name{mod_my_first_module_ui}
4 | \alias{mod_my_first_module_ui}
5 | \alias{mod_my_first_module_server}
6 | \title{mod_my_first_module_ui and mod_my_first_module_server}
7 | \usage{
8 | mod_my_first_module_ui(id)
9 |
10 | mod_my_first_module_server(input, output, session, r)
11 | }
12 | \arguments{
13 | \item{id}{shiny id}
14 |
15 | \item{input}{internal}
16 |
17 | \item{output}{internal}
18 |
19 | \item{session}{internal}
20 | }
21 | \description{
22 | A shiny Module.
23 | }
24 | \keyword{internal}
25 |
--------------------------------------------------------------------------------
/man/mod_my_fourth_module.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/mod_my_fourth_module.R
3 | \name{mod_my_fourth_module_ui}
4 | \alias{mod_my_fourth_module_ui}
5 | \alias{mod_my_fourth_module_server}
6 | \title{mod_my_fourth_module_ui and mod_my_fourth_module_server}
7 | \usage{
8 | mod_my_fourth_module_ui(id)
9 |
10 | mod_my_fourth_module_server(input, output, session)
11 | }
12 | \arguments{
13 | \item{id}{shiny id}
14 |
15 | \item{input}{internal}
16 |
17 | \item{output}{internal}
18 |
19 | \item{session}{internal}
20 | }
21 | \description{
22 | A shiny Module.
23 | }
24 | \keyword{internal}
25 |
--------------------------------------------------------------------------------
/man/mod_my_other_module.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/mod_my_other_module.R
3 | \name{mod_my_other_module_ui}
4 | \alias{mod_my_other_module_ui}
5 | \alias{mod_my_other_module_server}
6 | \title{mod_my_other_module_ui and mod_my_other_module_server}
7 | \usage{
8 | mod_my_other_module_ui(id)
9 |
10 | mod_my_other_module_server(input, output, session, r)
11 | }
12 | \arguments{
13 | \item{id}{shiny id}
14 |
15 | \item{input}{internal}
16 |
17 | \item{output}{internal}
18 |
19 | \item{session}{internal}
20 | }
21 | \description{
22 | A shiny Module.
23 | }
24 | \keyword{internal}
25 |
--------------------------------------------------------------------------------
/man/mod_my_third_module.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/mod_my_third_module.R
3 | \name{mod_my_third_module_ui}
4 | \alias{mod_my_third_module_ui}
5 | \alias{mod_my_third_module_server}
6 | \title{mod_my_third_module_ui and mod_my_third_module_server}
7 | \usage{
8 | mod_my_third_module_ui(id)
9 |
10 | mod_my_third_module_server(input, output, session, r)
11 | }
12 | \arguments{
13 | \item{id}{shiny id}
14 |
15 | \item{input}{internal}
16 |
17 | \item{output}{internal}
18 |
19 | \item{session}{internal}
20 | }
21 | \description{
22 | A shiny Module.
23 | }
24 | \keyword{internal}
25 |
--------------------------------------------------------------------------------
/man/run_app.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/run_app.R
3 | \name{run_app}
4 | \alias{run_app}
5 | \title{Run the Shiny Application}
6 | \usage{
7 | run_app(name = "example", time = Sys.time(), port = 2811)
8 | }
9 | \description{
10 | Run the Shiny Application
11 | }
12 |
--------------------------------------------------------------------------------
/tests/testthat.R:
--------------------------------------------------------------------------------
1 | library(testthat)
2 | library(golemexample)
3 |
4 | test_check("golemexample")
5 |
--------------------------------------------------------------------------------
/tests/testthat/test-golem-recommended.R:
--------------------------------------------------------------------------------
1 | context("golem tests")
2 |
3 | library(golem)
4 |
5 | test_that("app ui", {
6 | ui <- app_ui()
7 | expect_shinytaglist(ui)
8 | })
9 |
10 | test_that("app server", {
11 | server <- app_server
12 | expect_is(server, "function")
13 | })
14 |
15 | # Configure this test to fit your need
16 | test_that(
17 | "app launches",{
18 | skip_on_cran()
19 | skip_on_travis()
20 | skip_on_appveyor()
21 | x <- processx::process$new(
22 | "R",
23 | c(
24 | "-e",
25 | "setwd('../../'); pkgload::load_all();run_app()"
26 | )
27 | )
28 | Sys.sleep(5)
29 | expect_true(x$is_alive())
30 | x$kill()
31 | }
32 | )
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------