5
5
# ' @usage Dash
6
6
# '
7
7
# ' @section Constructor: Dash$new(
8
- # ' name = "dash" ,
8
+ # ' name = NULL ,
9
9
# ' server = fiery::Fire$new(),
10
10
# ' assets_folder = 'assets',
11
11
# ' assets_url_path = '/assets',
24
24
# ' @section Arguments:
25
25
# ' \tabular{lll}{
26
26
# ' `name` \tab \tab Character. The name of the Dash application (placed in the `<title>`
27
- # ' of the HTML page).\cr
27
+ # ' of the HTML page). DEPRECATED; please use `index_string()` or `interpolate_index()` instead. \cr
28
28
# ' `server` \tab \tab The web server used to power the application.
29
29
# ' Must be a [fiery::Fire] object.\cr
30
30
# ' `assets_folder` \tab \tab Character. A path, relative to the current working directory,
100
100
# ' from the Dash backend. The latter may offer improved performance relative
101
101
# ' to callbacks written in R.
102
102
# ' }
103
+ # ' \item{`title("dash")`}{
104
+ # ' The title of the app. If no title is supplied, Dash for R will use 'dash'.
105
+ # ' }
103
106
# ' \item{`callback_context()`}{
104
107
# ' The `callback_context` method permits retrieving the inputs which triggered
105
108
# ' the firing of a given callback, and allows introspection of the input/state
114
117
# ' present a warning and return `NULL` if the Dash app was not loaded via `source()`
115
118
# ' if the `DASH_APP_PATH` environment variable is undefined.
116
119
# ' }
117
- # ' \item{`run_server(host = Sys.getenv('HOST', "127.0.0.1"),
120
+ # ' \item{`index_string(string)`}{
121
+ # ' The `index_string` method allows the specification of a custom index by changing
122
+ # ' the default `HTML` template that is generated by the Dash UI. Meta tags, CSS, Javascript,
123
+ # ' are some examples of features that can be modified.
124
+ # ' This method will present a warning if your HTML template is missing any necessary elements
125
+ # ' and return an error if a valid index is not defined. The following interpolation keys are
126
+ # ' currently supported:
127
+ # ' \describe{
128
+ # ' \item{`{%metas%}`}{Optional - The registered meta tags.}
129
+ # ' \item{`{%favicon%}`}{Optional - A favicon link tag if found in assets.}
130
+ # ' \item{`{%css%}`}{Optional - Link tags to css resources.}
131
+ # ' \item{`{%config%}`}{Required - Config generated by dash for the renderer.}
132
+ # ' \item{`{%app_entry%}`}{Required - The container where dash react components are rendered.}
133
+ # ' \item{`{%scripts%}`}{Required - Collected dependencies scripts tags.}
134
+ # ' }
135
+ # ' \describe{
136
+ # ' \item{Example of a basic HTML index string:}{
137
+ # ' \preformatted{
138
+ # ' "<!DOCTYPE html>
139
+ # ' <html>
140
+ # ' <head>
141
+ # ' \{\%meta_tags\%\}
142
+ # ' <title>\{\{%css\%\}\}</title>
143
+ # ' \{\%favicon\%\}
144
+ # ' \{\%css_tags\%\}
145
+ # ' </head>
146
+ # ' <body>
147
+ # ' \{\%app_entry\%\}
148
+ # ' <footer>
149
+ # ' \{\%config\%\}
150
+ # ' \{\%scripts\%\}
151
+ # ' </footer>
152
+ # ' </body>
153
+ # ' </html>"
154
+ # ' }
155
+ # ' }
156
+ # ' }
157
+ # ' }
158
+ # ' \item{`interpolate_index(template_index, ...)`}{
159
+ # ' With the `interpolate_index` method, we can pass a custom index with template string
160
+ # ' variables that are already evaluated. We can directly pass arguments to the `template_index`
161
+ # ' by assigning them to variables present in the template. This is similar to the `index_string` method
162
+ # ' but offers the ability to change the default components of the Dash index as seen in the example below:
163
+ # ' \preformatted{
164
+ # ' app$interpolate_index(
165
+ # ' template_index,
166
+ # ' metas = "<meta_charset='UTF-8'/>",
167
+ # ' renderer = renderer,
168
+ # ' config = config)
169
+ # ' }
170
+ # ' \describe{
171
+ # ' \item{template_index}{Character. A formatted string with the HTML index string. Defaults to the initial template}
172
+ # ' \item{...}{Named List. The unnamed arguments can be passed as individual named lists corresponding to the components
173
+ # ' of the Dash html index. These include the same arguments as those found in the `index_string()` template.}
174
+ # ' }
175
+ # ' }
176
+ # ' \item{`run_server(host = Sys.getenv('HOST', "127.0.0.1"),
118
177
# ' port = Sys.getenv('PORT', 8050), block = TRUE, showcase = FALSE, ...)`}{
119
178
# ' The `run_server` method has 13 formal arguments, several of which are optional:
120
179
# ' \describe{
@@ -174,7 +233,7 @@ Dash <- R6::R6Class(
174
233
config = list (),
175
234
176
235
# i.e., the Dash$new() method
177
- initialize = function (name = " dash " ,
236
+ initialize = function (name = NULL ,
178
237
server = fiery :: Fire $ new(),
179
238
assets_folder = ' assets' ,
180
239
assets_url_path = ' /assets' ,
@@ -191,13 +250,18 @@ Dash <- R6::R6Class(
191
250
suppress_callback_exceptions = FALSE ) {
192
251
193
252
# argument type checking
194
- assertthat :: assert_that(is.character(name ))
195
253
assertthat :: assert_that(inherits(server , " Fire" ))
196
254
assertthat :: assert_that(is.logical(serve_locally ))
197
255
assertthat :: assert_that(is.logical(suppress_callback_exceptions ))
198
256
199
257
# save relevant args as private fields
200
- private $ name <- name
258
+ if (! is.null(name )) {
259
+ warning(sprintf(
260
+ " The supplied application title, '%s', should be set using the title() method, or passed via index_string() or interpolate_index(); it has been ignored, and 'dash' will be used instead." ,
261
+ name ),
262
+ call. = FALSE
263
+ )
264
+ }
201
265
private $ serve_locally <- serve_locally
202
266
private $ eager_loading <- eager_loading
203
267
# remove leading and trailing slash(es) if present
@@ -763,11 +827,44 @@ Dash <- R6::R6Class(
763
827
sep = " /" )))
764
828
},
765
829
830
+ # ------------------------------------------------------------------------
831
+ # specify a custom index string
832
+ # ------------------------------------------------------------------------
833
+ index_string = function (string ) {
834
+ private $ custom_index <- validate_keys(string )
835
+ },
836
+
837
+ # ------------------------------------------------------------------------
838
+ # modify the templated variables by using the `interpolate_index` method.
839
+ # ------------------------------------------------------------------------
840
+ interpolate_index = function (template_index = private $ template_index [[1 ]], ... ) {
841
+ template = template_index
842
+ kwargs <- list (... )
843
+
844
+ for (name in names(kwargs )) {
845
+ key = paste0(' \\ {\\ %' , name , ' \\ %\\ }' )
846
+ template = sub(key , kwargs [[name ]], template )
847
+ }
848
+
849
+ invisible (validate_keys(names(kwargs )))
850
+
851
+ private $ template_index <- template
852
+ },
853
+
854
+ # ------------------------------------------------------------------------
855
+ # specify a custom title
856
+ # ------------------------------------------------------------------------
857
+ title = function (string = " dash" ) {
858
+ assertthat :: assert_that(is.character(string ))
859
+ private $ name <- string
860
+ },
861
+
766
862
# ------------------------------------------------------------------------
767
863
# convenient fiery wrappers
768
864
# ------------------------------------------------------------------------
769
865
run_server = function (host = Sys.getenv(' HOST' , " 127.0.0.1" ),
770
866
port = Sys.getenv(' PORT' , 8050 ),
867
+
771
868
block = TRUE ,
772
869
showcase = FALSE ,
773
870
use_viewer = FALSE ,
@@ -1266,6 +1363,24 @@ Dash <- R6::R6Class(
1266
1363
1267
1364
# akin to https://github.com/plotly/dash/blob/d2ebc837/dash/dash.py#L338
1268
1365
# note discussion here https://github.com/plotly/dash/blob/d2ebc837/dash/dash.py#L279-L284
1366
+ custom_index = NULL ,
1367
+ template_index = c(
1368
+ " <!DOCTYPE html>
1369
+ <html>
1370
+ <head>
1371
+ {%meta_tags%}
1372
+ <title>{%title%}</title>
1373
+ {%favicon%}
1374
+ {%css_tags%}
1375
+ </head>
1376
+ <body>
1377
+ {%app_entry%}
1378
+ <footer>
1379
+ {%config%}
1380
+ {%scripts%}
1381
+ </footer>
1382
+ </body>
1383
+ </html>" , NA ),
1269
1384
.index = NULL ,
1270
1385
1271
1386
generateReloadHash = function () {
@@ -1434,13 +1549,32 @@ Dash <- R6::R6Class(
1434
1549
css_tags <- all_tags [[" css_tags" ]]
1435
1550
1436
1551
# retrieve script tags for serving in the index
1437
- scripts_tags <- all_tags [[" scripts_tags" ]]
1552
+ scripts <- all_tags [[" scripts_tags" ]]
1438
1553
1439
1554
# insert meta tags if present
1440
1555
meta_tags <- all_tags [[" meta_tags" ]]
1556
+
1557
+ # define the react-entry-point
1558
+ app_entry <- " <div id='react-entry-point'><div class='_dash-loading'>Loading...</div></div>"
1559
+ # define the dash default config key
1560
+ config <- sprintf(" <script id='_dash-config' type='application/json'> %s </script>" , to_JSON(self $ config ))
1561
+
1562
+ if (is.null(private $ name ))
1563
+ private $ name <- ' dash'
1564
+
1565
+ if (! is.null(private $ custom_index )) {
1566
+ string_index <- glue :: glue(private $ custom_index , .open = " {%" , .close = " %}" )
1567
+
1568
+ private $ .index <- string_index
1569
+ }
1570
+
1571
+ else if (length(private $ template_index ) == 1 ) {
1572
+ private $ .index <- private $ template_index
1573
+ }
1441
1574
1442
- private $ .index <- sprintf(
1443
- ' <!DOCTYPE html>
1575
+ else {
1576
+ private $ .index <- sprintf(
1577
+ ' <!DOCTYPE html>
1444
1578
<html>
1445
1579
<head>
1446
1580
%s
@@ -1450,23 +1584,22 @@ Dash <- R6::R6Class(
1450
1584
</head>
1451
1585
1452
1586
<body>
1453
- <div id="react-entry-point">
1454
- <div class="_dash-loading">Loading...</div>
1455
- </div>
1456
-
1587
+ %s
1457
1588
<footer>
1458
- <script id="_dash-config" type="application/json"> %s </script>
1589
+ %s
1459
1590
%s
1460
1591
</footer>
1461
1592
</body>
1462
1593
</html>' ,
1463
- meta_tags ,
1464
- private $ name ,
1465
- favicon ,
1466
- css_tags ,
1467
- to_JSON(self $ config ),
1468
- scripts_tags
1469
- )
1594
+ meta_tags ,
1595
+ private $ name ,
1596
+ favicon ,
1597
+ css_tags ,
1598
+ app_entry ,
1599
+ config ,
1600
+ scripts
1601
+ )
1602
+ }
1470
1603
}
1471
1604
)
1472
1605
)
0 commit comments