R Shiny:如何在图标函数中使用Fontawesome Pro版本?

8

我正在使用icon函数在我的Shiny应用程序中使用fontawesome图标。

我已经下载了fontawesome的专业版,并按照这里的说明shinydashboard some Font Awesome Icons Not Working替换了Shiny默认使用的免费版本(位于shiny\www\shared\font-awesome内)。这在本地非常有效,我的应用程序中显示了所有的专业版图标。

然而,当我部署到shinyapps.io时,似乎Shiny又回到了使用默认版本。我尝试将我的专业版目录包含在应用程序的/www/文件夹中,但没有成功。似乎没有办法告诉icon()函数查看本地版本的fontawesome,类似于icon(...,lib=local)icon(...,lib=path_to_fa)...

任何帮助都将非常受欢迎。

2个回答

7

最简单,也是最可靠的方法是:

  1. Put the font-awesome files in a subdirectory of the app, www/fontawesome/

  2. Add the following somewhere to the UI code:

     htmlDependency(
       name = "font-awesome", version = "99.0",
       src = "./www/fontawesome",
       stylesheet = "css/all.min.css"
     )
    

这是一个示例应用程序,说明:

shinyApp(
  ui = fluidPage(
    "This is a Font-Awesome Pro-only icon: ", icon("acorn"),
    htmlDependency(
      name = "font-awesome", version = "99.0",
      src = "./www/fontawesome", stylesheet = "css/all.min.css"
    )
  ),
  function(input, output, session) { }
)

另一种方法存在一个潜在问题,即如果ui组件包含对icon()的调用,并且然后有一些通过renderUI()uiOutput()动态呈现的UI,其中包含对my_icon()的调用,使用的是Font-Awesome Pro中唯一的图标,则该Pro图标将不会显示。我展示的方法将不会有这个问题。
原因在于另一种方法会出现这个问题:当应用程序的静态ui被呈现为HTML时,它会在ui中查找htmlDependency对象,对于给定名称(在这种情况下是“font-awesome”)的最新版本的htmlDependency“获胜”。因此,如果代码中只有对icon()的调用(没有对my_icon()的调用或我的示例中显式htmlDependency()),则获胜的Font-Awesome的htmlDependency是随Shiny一起提供的那个版本,截至本篇文章撰写时为5.13.0。浏览器将请求该版本的Font-Awesome。
稍后,如果renderUI()插入一个带有Pro图标的my_icon(),则该HTML将与Font-Awesome Pro的htmlDependency对象一起发送到浏览器。但是,此时浏览器已经加载了Font-Awesome,并且它不会知道加载这个更新的版本——Shiny目前无法将已加载的Font-Awesome版本替换为较新的版本。
将自定义的htmlDependency添加到静态ui对象中使得可以在初始页面呈现时解决该问题,浏览器从一开始就知道要加载更新的版本。我使用的版本是99.0,确保此自定义版本将“胜出”任何其他Font-AwesomehtmlDependency版本。

7
技巧在于,在icon()函数中的htmlDependency调用内,删除package = "shiny"并将"www/shared/fontawesome"替换为我的FA文件夹的绝对路径(我还更新了版本号)。
编辑:更精确地说,下面是(稍微)修改后的icon函数:
my_icon = function (name, class = NULL, lib = "font-awesome") {

prefixes <- list(`font-awesome` = "fa", glyphicon = "glyphicon")
  prefix <- prefixes[[lib]]
  if (is.null(prefix)) {
    stop("Unknown font library '", lib, "' specified. Must be one of ", 
         paste0("\"", names(prefixes), "\"", collapse = ", "))
  }
  iconClass <- ""
  if (!is.null(name)) {
    prefix_class <- prefix
    #if (prefix_class == "fa" && name %in% font_awesome_brands) {
    #  prefix_class <- "fab"
    #}
    iconClass <- paste0(prefix_class, " ", prefix, "-", name)
  }
  if (!is.null(class)) 
    iconClass <- paste(iconClass, class)
  iconTag <- tags$i(class = iconClass)
  if (lib == "font-awesome") {
    htmlDependencies(iconTag) <- htmlDependency("font-awesome", 
                                                "5.7.2", "./www/shared/fontawesome/", 
                                                stylesheet = c("css/all.min.css"))
  }
  htmltools::browsable(iconTag)
}

除了注释掉一些行,我改变的唯一部分是htmlDependency调用。在原始函数中,它是这样的:
htmlDependency("font-awesome", "5.3.1", "www/shared/fontawesome", package = "shiny",
               stylesheet = c("css/all.min.css", "css/v4-shims.min.css")

你是否对Shiny CSS进行了任何更改以表明你正在使用Font Awesome Pro?我按照你在原始问题中发布的链接中描述的步骤,以及你所描述的htmlDependency步骤,但是我的应用程序中只显示免费图标。我查看了我下载的Font Awesome中的all.min.css文件,其中包含专业图标。有什么想法吗? - zack
不行。您确定使用并引用了修改后的 icon() 函数吗? 你将 pro 目录复制到 your_app\www\shared\fontawesome 了吗? - Antoine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接