├── .github
├── .gitignore
└── workflows
│ ├── R-CMD-check.yaml
│ └── pkgdown.yaml
├── tests
├── testthat
│ ├── rmd
│ │ ├── .gitignore
│ │ ├── test-metathis.Rmd
│ │ └── test-not-self-contained.Rmd
│ ├── helper.R
│ ├── test-write.R
│ ├── test-geo.R
│ ├── test-viewport.R
│ ├── test-general.R
│ ├── test-apple.R
│ ├── test-blogdown.R
│ ├── test-rmd.R
│ ├── test-social.R
│ ├── test-meta.R
│ └── test-google_scholar.R
└── testthat.R
├── LICENSE
├── man
├── figures
│ ├── card.png
│ ├── logo.png
│ └── card.svg
├── pipe.Rd
├── metathis-package.Rd
├── include_meta.Rd
├── write_meta.Rd
├── meta_name.Rd
├── meta_tag.Rd
├── meta_apple_itunes_app.Rd
├── meta.Rd
├── meta_apple_web_app.Rd
├── meta_geo.Rd
├── meta_viewport.Rd
├── meta_general.Rd
├── meta_social.Rd
└── meta_google_scholar.Rd
├── pkgdown
├── favicon
│ ├── favicon.ico
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── apple-touch-icon.png
│ ├── apple-touch-icon-60x60.png
│ ├── apple-touch-icon-76x76.png
│ ├── apple-touch-icon-120x120.png
│ ├── apple-touch-icon-152x152.png
│ └── apple-touch-icon-180x180.png
└── _pkgdown.yml
├── man-roxygen
├── describe-meta.R
└── describe-meta-return.R
├── cran-comments.md
├── R
├── utils-pipe.R
├── metathis-package.R
├── utils.R
├── write.R
├── utils-meta.R
├── geo.R
├── viewport.R
├── general.R
├── apple.R
├── social.R
├── google_scholar.R
└── meta.R
├── .Rbuildignore
├── inst
└── WORDLIST
├── metathis.Rproj
├── NAMESPACE
├── DESCRIPTION
├── LICENSE.md
├── NEWS.md
├── .gitignore
├── README.Rmd
└── README.md
/.github/.gitignore:
--------------------------------------------------------------------------------
1 | *.html
2 |
--------------------------------------------------------------------------------
/tests/testthat/rmd/.gitignore:
--------------------------------------------------------------------------------
1 | *html
2 | *_files
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | YEAR: 2020
2 | COPYRIGHT HOLDER: Garrick Aden-Buie
3 |
--------------------------------------------------------------------------------
/tests/testthat.R:
--------------------------------------------------------------------------------
1 | library(testthat)
2 | library(metathis)
3 |
4 | test_check("metathis")
5 |
--------------------------------------------------------------------------------
/man/figures/card.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gadenbuie/metathis/HEAD/man/figures/card.png
--------------------------------------------------------------------------------
/man/figures/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gadenbuie/metathis/HEAD/man/figures/logo.png
--------------------------------------------------------------------------------
/pkgdown/favicon/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gadenbuie/metathis/HEAD/pkgdown/favicon/favicon.ico
--------------------------------------------------------------------------------
/pkgdown/favicon/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gadenbuie/metathis/HEAD/pkgdown/favicon/favicon-16x16.png
--------------------------------------------------------------------------------
/pkgdown/favicon/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gadenbuie/metathis/HEAD/pkgdown/favicon/favicon-32x32.png
--------------------------------------------------------------------------------
/pkgdown/favicon/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gadenbuie/metathis/HEAD/pkgdown/favicon/apple-touch-icon.png
--------------------------------------------------------------------------------
/tests/testthat/helper.R:
--------------------------------------------------------------------------------
1 | expect_equal_meta <- function(.meta, expected) {
2 | expect_equal(as.character(.meta), expected)
3 | }
4 |
--------------------------------------------------------------------------------
/pkgdown/favicon/apple-touch-icon-60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gadenbuie/metathis/HEAD/pkgdown/favicon/apple-touch-icon-60x60.png
--------------------------------------------------------------------------------
/pkgdown/favicon/apple-touch-icon-76x76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gadenbuie/metathis/HEAD/pkgdown/favicon/apple-touch-icon-76x76.png
--------------------------------------------------------------------------------
/pkgdown/favicon/apple-touch-icon-120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gadenbuie/metathis/HEAD/pkgdown/favicon/apple-touch-icon-120x120.png
--------------------------------------------------------------------------------
/pkgdown/favicon/apple-touch-icon-152x152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gadenbuie/metathis/HEAD/pkgdown/favicon/apple-touch-icon-152x152.png
--------------------------------------------------------------------------------
/pkgdown/favicon/apple-touch-icon-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gadenbuie/metathis/HEAD/pkgdown/favicon/apple-touch-icon-180x180.png
--------------------------------------------------------------------------------
/man-roxygen/describe-meta.R:
--------------------------------------------------------------------------------
1 | #' @param .meta A `meta` object created by [meta()] or [as_meta()], or returned
2 | #' by a `meta_*()` object.
3 | #'
4 | #' @md
5 |
--------------------------------------------------------------------------------
/cran-comments.md:
--------------------------------------------------------------------------------
1 | ## R CMD check results
2 |
3 | 0 errors | 0 warnings | 0 note
4 |
5 | This is a maintenance release to correct
6 | a numeric package version as requested by CRAN.
7 |
--------------------------------------------------------------------------------
/R/utils-pipe.R:
--------------------------------------------------------------------------------
1 | #' Pipe operator
2 | #'
3 | #' See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details.
4 | #'
5 | #' @name %>%
6 | #' @rdname pipe
7 | #' @keywords internal
8 | #' @export
9 | #' @importFrom magrittr %>%
10 | #' @usage lhs \%>\% rhs
11 | NULL
12 |
--------------------------------------------------------------------------------
/man-roxygen/describe-meta-return.R:
--------------------------------------------------------------------------------
1 | #' @return A `meta` object, or a set of `` HTML tags inside an HTML
2 | #' `
` tag. For use in [rmarkdown::html_document()], [shiny::runApp()],
3 | #' or other HTML locations.
4 | #'
5 | #' @family meta
6 | #'
7 | #' @md
8 |
--------------------------------------------------------------------------------
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^metathis\.Rproj$
2 | ^\.Rproj\.user$
3 | ^LICENSE\.md$
4 | ^README\.Rmd$
5 | ^man-roxygen$
6 | ^pkgdown$
7 | ^tests/manual$
8 | ^\.travis\.yml$
9 | ^appveyor\.yml$
10 | ^tic\.R$
11 | ^cran-comments\.md$
12 | ^CRAN-RELEASE$
13 | ^\.ccache$
14 | ^\.github$
15 | ^docs$
16 | ^CRAN-SUBMISSION$
17 |
--------------------------------------------------------------------------------
/man/pipe.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/utils-pipe.R
3 | \name{\%>\%}
4 | \alias{\%>\%}
5 | \title{Pipe operator}
6 | \usage{
7 | lhs \%>\% rhs
8 | }
9 | \description{
10 | See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details.
11 | }
12 | \keyword{internal}
13 |
--------------------------------------------------------------------------------
/R/metathis-package.R:
--------------------------------------------------------------------------------
1 | #' @importFrom knitr knit_print
2 | #' @keywords internal
3 | "_PACKAGE"
4 |
5 | METATHIS_VERSION <- "1.1.3"
6 |
7 | # The following block is used by usethis to automatically manage
8 | # roxygen namespace tags. Modify with care!
9 | ## usethis namespace: start
10 | ## usethis namespace: end
11 | NULL
12 |
--------------------------------------------------------------------------------
/inst/WORDLIST:
--------------------------------------------------------------------------------
1 | Barret
2 | blogdown
3 | bookdown
4 | Buchea
5 | Buie
6 | Dreamweaver
7 | flexdashboard
8 | geotagging
9 | Geotagging
10 | Github
11 | htmltools
12 | hugo
13 | Lifecycle
14 | MDN
15 | ORCID
16 | pagedown
17 | Pinterest
18 | pkgdown
19 | rmarkdown
20 | RStudio
21 | scalable
22 | travis
23 | UI
24 | Validator
25 | xaringan
26 | ymlthis
27 |
--------------------------------------------------------------------------------
/metathis.Rproj:
--------------------------------------------------------------------------------
1 | Version: 1.0
2 |
3 | RestoreWorkspace: No
4 | SaveWorkspace: No
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 | AutoAppendNewline: Yes
16 | StripTrailingWhitespace: Yes
17 |
18 | BuildType: Package
19 | PackageUseDevtools: Yes
20 | PackageInstallArgs: --no-multiarch --with-keep.source
21 | PackageRoxygenize: rd,collate,namespace
22 |
--------------------------------------------------------------------------------
/R/utils.R:
--------------------------------------------------------------------------------
1 | # nocov start
2 | has_package_version <- function(package, version) {
3 | pkg_v <- packageVersion(package)
4 | if (is.null(pkg_v)) {
5 | return(FALSE)
6 | }
7 | pkg_v >= package_version(version)
8 | }
9 |
10 | packageVersion <- function(package) {
11 | if (!requireNamespace(package, quietly = TRUE)) {
12 | return(NULL)
13 | }
14 | pkg_v <- read.dcf(
15 | system.file("DESCRIPTION", package = package),
16 | fields = "Version"
17 | )
18 | package_version(pkg_v[[1]])
19 | }
20 | # nocov end
21 |
--------------------------------------------------------------------------------
/tests/testthat/rmd/test-metathis.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "test-metathis-rmd"
3 | output: html_document_base
4 | ---
5 |
6 | ```{r setup, include=FALSE}
7 | knitr::opts_chunk$set(echo = TRUE)
8 | ```
9 |
10 | ```{r}
11 | knitr::opts_knit$get("out.format")
12 | knitr::opts_knit$get("rmarkdown.pandoc.to")
13 | ```
14 |
15 |
16 | ```{r metathis}
17 | library(metathis)
18 |
19 | meta() %>%
20 | meta_tag(method = "KNIT_PRINT")
21 | ```
22 |
23 | ```{r metathis-2}
24 | meta_tag(method = "knit_print(2)")
25 | ```
26 |
27 | ```{r}
28 | meta() %>%
29 | meta_tag(method = "INCLUDE_META()") %>%
30 | include_meta()
31 | ```
32 |
--------------------------------------------------------------------------------
/tests/testthat/test-write.R:
--------------------------------------------------------------------------------
1 | describe("write_meta()", {
2 |
3 | it("writes to a file", {
4 | meta <- meta_tag(method = "test") %>% meta_viewport()
5 | tmp <- tempfile(fileext = ".html")
6 | write_meta(meta, tmp)
7 | expect_equal(readLines(tmp), as.character(meta))
8 | })
9 |
10 | it("appends to a file", {
11 | tmp <- tempfile(fileext = ".html")
12 | meta1 <- meta_tag(method = "first") %>% write_meta(tmp)
13 | meta2 <- meta_tag(method = "second") %>% write_meta(tmp, append = TRUE)
14 | expect_equal(
15 | readLines(tmp),
16 | c(as.character(meta1), as.character(meta2))
17 | )
18 | })
19 |
20 | })
21 |
--------------------------------------------------------------------------------
/tests/testthat/rmd/test-not-self-contained.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "test-metathis-not-self-contained-rmd"
3 | output:
4 | html_document:
5 | self_contained: no
6 | ---
7 |
8 | ```{r setup, include=FALSE}
9 | knitr::opts_chunk$set(echo = TRUE)
10 | ```
11 |
12 | ```{r}
13 | knitr::opts_knit$get("out.format")
14 | knitr::opts_knit$get("rmarkdown.pandoc.to")
15 | ```
16 |
17 |
18 | ```{r metathis}
19 | library(metathis)
20 |
21 | meta() %>%
22 | meta_tag(method = "KNIT_PRINT")
23 | ```
24 |
25 | ```{r metathis-2}
26 | meta_tag(method = "knit_print(2)")
27 | ```
28 |
29 | ```{r}
30 | meta() %>%
31 | meta_tag(method = "INCLUDE_META()") %>%
32 | include_meta()
33 | ```
34 |
--------------------------------------------------------------------------------
/NAMESPACE:
--------------------------------------------------------------------------------
1 | # Generated by roxygen2: do not edit by hand
2 |
3 | S3method(as.character,meta)
4 | S3method(as_meta,data.frame)
5 | S3method(as_meta,default)
6 | S3method(as_meta,list)
7 | S3method(format,meta)
8 | S3method(knit_print,meta)
9 | S3method(print,meta)
10 | export("%>%")
11 | export(as_meta)
12 | export(include_meta)
13 | export(is_meta)
14 | export(meta)
15 | export(meta_apple_itunes_app)
16 | export(meta_apple_web_app)
17 | export(meta_description)
18 | export(meta_general)
19 | export(meta_geo)
20 | export(meta_google_scholar)
21 | export(meta_name)
22 | export(meta_referrer)
23 | export(meta_robots)
24 | export(meta_social)
25 | export(meta_subject)
26 | export(meta_tag)
27 | export(meta_theme_color)
28 | export(meta_viewport)
29 | export(write_meta)
30 | importFrom(knitr,knit_print)
31 | importFrom(magrittr,"%>%")
32 |
--------------------------------------------------------------------------------
/R/write.R:
--------------------------------------------------------------------------------
1 | #' Write Metadata Tags to a File
2 | #'
3 | #' Write your metadata tags to an HTML file that can be manually included in
4 | #' your page.
5 | #'
6 | #' @template describe-meta
7 | #' @param path The file to write into, defaults to `"meta.html"`.
8 | #' @inheritParams base::cat
9 | #'
10 | #' @return Returns `.meta` invisibly.
11 | #'
12 | #' @family meta_actions
13 | #'
14 | #' @examples
15 | #' meta_html_snippet <- tempfile("metathis_example", fileext = ".html")
16 | #'
17 | #' meta() %>%
18 | #' meta_name("package" = "metathis") %>%
19 | #' write_meta(meta_html_snippet)
20 | #'
21 | #' readLines(meta_html_snippet, warn = FALSE)
22 | #'
23 | #' @export
24 | write_meta <- function(.meta, path = "meta.html", append = FALSE) {
25 | .meta %>%
26 | as.character() %>%
27 | cat(file = path, sep = "\n", append = append)
28 |
29 | invisible(.meta)
30 | }
31 |
--------------------------------------------------------------------------------
/tests/testthat/test-geo.R:
--------------------------------------------------------------------------------
1 | test_that("meta_geo()", {
2 | exp_geo <- c(
3 | '',
4 | '',
5 | '',
6 | ''
7 | )
8 |
9 | expect_equal_meta(
10 | meta() %>%
11 | meta_geo(
12 | icbm = c(50.167958, -97.133185),
13 | geo_position = c(50.167958, -97.133185),
14 | geo_placename = "Manitoba, Canada",
15 | geo_region = "ca-mb"
16 | ),
17 | exp_geo
18 | )
19 |
20 | expect_equal(
21 | meta_geo(icbm = c(50.167958, -97.133185)),
22 | meta_geo(icbm = "50.167958, -97.133185")
23 | )
24 |
25 | expect_equal(
26 | meta_geo(geo_position = c(50.167958, -97.133185)),
27 | meta_geo(geo_position = "50.167958;-97.133185")
28 | )
29 |
30 | })
31 |
--------------------------------------------------------------------------------
/man/metathis-package.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/metathis-package.R
3 | \docType{package}
4 | \name{metathis-package}
5 | \alias{metathis}
6 | \alias{metathis-package}
7 | \title{metathis: HTML Metadata Tags for 'R Markdown' and 'Shiny'}
8 | \description{
9 | \if{html}{\figure{logo.png}{options: style='float: right' alt='logo' width='120'}}
10 |
11 | Create meta tags for 'R Markdown' HTML documents and 'Shiny' apps for customized social media cards, for accessibility, and quality search engine indexing. 'metathis' currently supports HTML documents created with 'rmarkdown', 'shiny', 'xaringan', 'pagedown', 'bookdown', and 'flexdashboard'.
12 | }
13 | \seealso{
14 | Useful links:
15 | \itemize{
16 | \item \url{https://pkg.garrickadenbuie.com/metathis/}
17 | \item \url{https://github.com/gadenbuie/metathis}
18 | \item Report bugs at \url{https://github.com/gadenbuie/metathis/issues}
19 | }
20 |
21 | }
22 | \author{
23 | \strong{Maintainer}: Garrick Aden-Buie \email{garrick@adenbuie.com} (\href{https://orcid.org/0000-0002-7111-0077}{ORCID})
24 |
25 | }
26 | \keyword{internal}
27 |
--------------------------------------------------------------------------------
/tests/testthat/test-viewport.R:
--------------------------------------------------------------------------------
1 | # test_that()
2 |
3 | describe("meta_viewport()", {
4 | default_viewport <- ''
5 | it("creates a viewport meta tag", {
6 | expect_equal_meta(meta_viewport(), default_viewport)
7 | })
8 |
9 | it("always comes first", {
10 | expect_equal_meta(
11 | meta() %>%
12 | meta_general(description = "defined first") %>%
13 | meta_viewport(),
14 | c(
15 | default_viewport,
16 | ''
17 | )
18 | )
19 | })
20 |
21 | it("errors if everything is NULL", {
22 | expect_error(meta_viewport(meta(), NULL, NULL, NULL))
23 | })
24 |
25 | it("warns if too many width or height arguments are set", {
26 | expect_warning(meta_viewport(width = "100px", min_width = "100px"))
27 | expect_warning(meta_viewport(width = "100px", max_width = "100px"))
28 | expect_warning(meta_viewport(height = "100px", min_height = "100px"))
29 | expect_warning(meta_viewport(height = "100px", max_height = "100px"))
30 | })
31 | })
32 |
--------------------------------------------------------------------------------
/DESCRIPTION:
--------------------------------------------------------------------------------
1 | Package: metathis
2 | Title: HTML Metadata Tags for 'R Markdown' and 'Shiny'
3 | Version: 1.1.4.9000
4 | Authors@R:
5 | person(given = "Garrick",
6 | family = "Aden-Buie",
7 | role = c("aut", "cre"),
8 | email = "garrick@adenbuie.com",
9 | comment = c(ORCID = "0000-0002-7111-0077"))
10 | Description: Create meta tags for 'R Markdown' HTML documents and 'Shiny'
11 | apps for customized social media cards, for accessibility, and quality
12 | search engine indexing. 'metathis' currently supports HTML documents
13 | created with 'rmarkdown', 'shiny', 'xaringan', 'pagedown', 'bookdown',
14 | and 'flexdashboard'.
15 | License: MIT + file LICENSE
16 | URL: https://pkg.garrickadenbuie.com/metathis/,
17 | https://github.com/gadenbuie/metathis
18 | BugReports: https://github.com/gadenbuie/metathis/issues
19 | Imports:
20 | htmltools,
21 | knitr,
22 | magrittr,
23 | purrr
24 | Suggests:
25 | rmarkdown,
26 | shiny,
27 | testthat (>= 2.1.0)
28 | Config/Needs/website: gadenbuie/grkgdown
29 | Encoding: UTF-8
30 | Roxygen: list(markdown = TRUE)
31 | RoxygenNote: 7.2.3
32 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # MIT License
2 |
3 | Copyright (c) 2019 Garrick Aden-Buie
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/man/include_meta.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/meta.R
3 | \name{include_meta}
4 | \alias{include_meta}
5 | \title{Include Metadata Tags in HTML Document}
6 | \usage{
7 | include_meta(.meta)
8 | }
9 | \arguments{
10 | \item{.meta}{A \code{meta} object created by \code{\link[=meta]{meta()}} or \code{\link[=as_meta]{as_meta()}}, or returned
11 | by a \verb{meta_*()} object.}
12 | }
13 | \value{
14 | An \code{\link[htmltools:htmlDependency]{htmltools::htmlDependency()}} containing the metadata tags to be
15 | included in the \verb{} of the HTML document.
16 | }
17 | \description{
18 | Use \code{include_meta()} to explicitly declare the \code{\link[=meta]{meta()}} tags as an HTML
19 | dependency. In general, this is not required when knitting to an HTML
20 | document. This function explicitly attaches an \code{\link[htmltools:htmlDependency]{htmltools::htmlDependency()}}
21 | and may work in some unusual cases.
22 | }
23 | \examples{
24 | meta() \%>\%
25 | meta_name("github-repo" = "gadenbuie/metathis") \%>\%
26 | include_meta()
27 |
28 | }
29 | \seealso{
30 | Other meta_actions:
31 | \code{\link{write_meta}()}
32 | }
33 | \concept{meta_actions}
34 |
--------------------------------------------------------------------------------
/tests/testthat/test-general.R:
--------------------------------------------------------------------------------
1 |
2 | test_that("meta_description()", {
3 | expect_equal_meta(
4 | meta() %>% meta_description("A cool app"),
5 | ''
6 | )
7 | })
8 |
9 |
10 | test_that("meta_subject()", {
11 | expect_equal_meta(
12 | meta() %>% meta_subject("hot topics"),
13 | ''
14 | )
15 | })
16 |
17 | test_that("meta_referrer()", {
18 | expect_equal_meta(
19 | meta() %>% meta_referrer("no-referrer"),
20 | ''
21 | )
22 | })
23 |
24 | test_that("meta_robots()", {
25 | expect_equal_meta(
26 | meta() %>% meta_robots("nofollow"),
27 | ''
28 | )
29 | expect_equal_meta(
30 | meta() %>% meta_robots(c("index", "follow")),
31 | ''
32 | )
33 | })
34 |
35 | test_that("meta_theme_color()", {
36 | expect_equal_meta(
37 | meta() %>% meta_theme_color("#123456"),
38 | ''
39 | )
40 | })
41 |
42 | test_that("meta_general() errors appropriately", {
43 | expect_error(meta_general(1))
44 | })
45 |
--------------------------------------------------------------------------------
/NEWS.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # metathis (development version)
4 |
5 |
6 | # metathis 1.1.4
7 |
8 | - Fixed a usage of numeric package version as requested by CRAN.
9 |
10 | - Removed a link in the docs to the now-defunct Twitter Card validator.
11 |
12 |
13 | # metathis 1.1.3
14 |
15 | - Fix S3 method signatures to resolve recent CRAN warnings (#30).
16 |
17 | # metathis 1.1.2
18 |
19 | * Fix link to `` tag docs on MDN (@IndrajeetPatil, #25)
20 |
21 | * Rebuild documentation for CRAN
22 |
23 | # metathis 1.1.1
24 |
25 | - Fixed an issue that caused metathis to fail for versions of rmarkdown <= 2.8
26 |
27 | # metathis 1.1.0
28 |
29 | - Fixed an issue with the Twitter image `` tag (thanks @llrs, #19).
30 |
31 | - Added `meta_google_scholar()` to help create the `` tags expected by
32 | [Google Scholar](https://scholar.google.com/intl/en/scholar/inclusion.html#indexing) (#5).
33 |
34 | - metathis no longer creates an empty folder in the directory where dependencies
35 | sourced via htmltools are saved when using non-stand-alone documents.
36 |
37 | # metathis 1.0.3
38 |
39 | - Fixed an issue with open graph social media `` tags (#10)
40 |
41 | # metathis 1.0.2
42 |
43 | _metathis_ package released!
44 |
--------------------------------------------------------------------------------
/man/write_meta.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/write.R
3 | \name{write_meta}
4 | \alias{write_meta}
5 | \title{Write Metadata Tags to a File}
6 | \usage{
7 | write_meta(.meta, path = "meta.html", append = FALSE)
8 | }
9 | \arguments{
10 | \item{.meta}{A \code{meta} object created by \code{\link[=meta]{meta()}} or \code{\link[=as_meta]{as_meta()}}, or returned
11 | by a \verb{meta_*()} object.}
12 |
13 | \item{path}{The file to write into, defaults to \code{"meta.html"}.}
14 |
15 | \item{append}{logical. Only used if the argument \code{file} is the
16 | name of file (and not a connection or \code{"|cmd"}).
17 | If \code{TRUE} output will be appended to
18 | \code{file}; otherwise, it will overwrite the contents of
19 | \code{file}.}
20 | }
21 | \value{
22 | Returns \code{.meta} invisibly.
23 | }
24 | \description{
25 | Write your metadata tags to an HTML file that can be manually included in
26 | your page.
27 | }
28 | \examples{
29 | meta_html_snippet <- tempfile("metathis_example", fileext = ".html")
30 |
31 | meta() \%>\%
32 | meta_name("package" = "metathis") \%>\%
33 | write_meta(meta_html_snippet)
34 |
35 | readLines(meta_html_snippet, warn = FALSE)
36 |
37 | }
38 | \seealso{
39 | Other meta_actions:
40 | \code{\link{include_meta}()}
41 | }
42 | \concept{meta_actions}
43 |
--------------------------------------------------------------------------------
/man/meta_name.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/meta.R
3 | \name{meta_name}
4 | \alias{meta_name}
5 | \title{Create name/content metadata tag pairs}
6 | \usage{
7 | meta_name(.meta = meta(), ...)
8 | }
9 | \arguments{
10 | \item{.meta}{A \code{meta} object created by \code{\link[=meta]{meta()}} or \code{\link[=as_meta]{as_meta()}}, or returned
11 | by a \verb{meta_*()} object.}
12 |
13 | \item{...}{Name (argument names) and content (argument value) pairs.}
14 | }
15 | \value{
16 | A \code{meta} object, or a set of \verb{} HTML tags inside an HTML
17 | \verb{} tag. For use in \code{\link[rmarkdown:html_document]{rmarkdown::html_document()}}, \code{\link[shiny:runApp]{shiny::runApp()}},
18 | or other HTML locations.
19 | }
20 | \description{
21 | Creates metadata tag pairs where the arguments are the name values and their
22 | values are content values.
23 | }
24 | \examples{
25 | meta() \%>\%
26 | meta_name("github-repo" = "hadley/r4ds")
27 |
28 | }
29 | \seealso{
30 | Other meta:
31 | \code{\link{meta_apple_itunes_app}()},
32 | \code{\link{meta_apple_web_app}()},
33 | \code{\link{meta_general}()},
34 | \code{\link{meta_geo}()},
35 | \code{\link{meta_google_scholar}()},
36 | \code{\link{meta_social}()},
37 | \code{\link{meta_tag}()},
38 | \code{\link{meta_viewport}()},
39 | \code{\link{meta}()}
40 | }
41 | \concept{meta}
42 |
--------------------------------------------------------------------------------
/tests/testthat/test-apple.R:
--------------------------------------------------------------------------------
1 | test_that("meta_apple_itunes_app()", {
2 | expected <- ''
3 | tested <- meta_apple_itunes_app(
4 | app_id = "APP_ID",
5 | affiliate_id = "AFFILIATE_ID",
6 | `app-argument` = "SOME_TEXT"
7 | )
8 |
9 | expect_equal(tested %>% paste(), expected)
10 |
11 | expect_equal(
12 | meta_apple_itunes_app(),
13 | meta()
14 | )
15 | })
16 |
17 | describe("meta_apple_web_app()", {
18 | it("generally works", {
19 | expected <- c(
20 | '',
21 | '',
22 | ''
23 | )
24 |
25 | expect_equal_meta(
26 | meta() %>% meta_apple_web_app(
27 | title = "App Title",
28 | capable = TRUE,
29 | status_bar_style = "black"
30 | ),
31 | expected
32 | )
33 |
34 | expect_equal_meta(
35 | meta() %>% meta_apple_web_app(capable = FALSE, status_bar_style = NULL),
36 | sub("yes", "no", expected[2], fixed = TRUE)
37 | )
38 | })
39 |
40 | it('errors when appropriate', {
41 | expect_error(meta_apple_web_app(status_bar_style = "white"))
42 | expect_error(meta_apple_web_app("a"))
43 | })
44 | })
45 |
--------------------------------------------------------------------------------
/tests/testthat/test-blogdown.R:
--------------------------------------------------------------------------------
1 | with_dir <- function(path, x) {
2 | owd <- setwd(path)
3 | on.exit(setwd(owd))
4 | eval(substitute(x))
5 | }
6 |
7 | test_that("blogdown is guessed correctly", {
8 | blogdown_dir <- file.path(tempdir(), "blogdown", "content", "post")
9 | dir.create(blogdown_dir, recursive = TRUE)
10 | on.exit(unlink(file.path(tempdir(), "blogdown"), recursive = TRUE))
11 |
12 | # setup fake blogdown folder structure
13 | dir.create(file.path(blogdown_dir, "..", "..", "layouts"))
14 | dir.create(file.path(blogdown_dir, "..", "..", "static"))
15 | cat('', file = file.path(blogdown_dir, "..", "..", "config.toml"))
16 |
17 | blogdown_exp <- normalizePath(file.path(tempdir(), "blogdown"))
18 | expect_equal(find_config(blogdown_dir), blogdown_exp)
19 | with_dir(blogdown_dir, expect_true(guess_blogdown()))
20 |
21 | cat('baseURL = "/"', file = file.path(blogdown_dir, "..", "..", "config.toml"))
22 | expect_equal(find_config(blogdown_dir), blogdown_exp)
23 | with_dir(blogdown_dir, expect_true(guess_blogdown()))
24 |
25 | expect_null(find_config(tempdir()))
26 | with_dir(tempdir(), expect_false(guess_blogdown()))
27 |
28 | # create config.toml outside of blogdown, should be detected as non-blogdown
29 | cat("", file = file.path(tempdir(), "config.toml"))
30 | on.exit(unlink(file.path(tempdir(), "config.toml")), add = TRUE)
31 | with_dir(tempdir(), expect_false(guess_blogdown()))
32 | })
33 |
--------------------------------------------------------------------------------
/man/meta_tag.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/meta.R
3 | \name{meta_tag}
4 | \alias{meta_tag}
5 | \title{Create a metadata tag for attribute/value pairs}
6 | \usage{
7 | meta_tag(.meta = meta(), ...)
8 | }
9 | \arguments{
10 | \item{.meta}{A \code{meta} object created by \code{\link[=meta]{meta()}} or \code{\link[=as_meta]{as_meta()}}, or returned
11 | by a \verb{meta_*()} object.}
12 |
13 | \item{...}{Attribute names and values as \code{attribute = value}. Values must be
14 | a single character string.}
15 | }
16 | \value{
17 | A \code{meta} object, or a set of \verb{} HTML tags inside an HTML
18 | \verb{} tag. For use in \code{\link[rmarkdown:html_document]{rmarkdown::html_document()}}, \code{\link[shiny:runApp]{shiny::runApp()}},
19 | or other HTML locations.
20 | }
21 | \description{
22 | Creates a \verb{} tag for attribute value pairs, where argument names
23 | correspond to attribute names.
24 | }
25 | \examples{
26 | meta() \%>\%
27 | meta_tag(
28 | "http-equiv" = "Content-Security-Policy",
29 | content = "default-src 'self'"
30 | )
31 |
32 | }
33 | \seealso{
34 | Other meta:
35 | \code{\link{meta_apple_itunes_app}()},
36 | \code{\link{meta_apple_web_app}()},
37 | \code{\link{meta_general}()},
38 | \code{\link{meta_geo}()},
39 | \code{\link{meta_google_scholar}()},
40 | \code{\link{meta_name}()},
41 | \code{\link{meta_social}()},
42 | \code{\link{meta_viewport}()},
43 | \code{\link{meta}()}
44 | }
45 | \concept{meta}
46 |
--------------------------------------------------------------------------------
/R/utils-meta.R:
--------------------------------------------------------------------------------
1 |
2 | `%||%` <- function(x, y) if (is.null(x)) y else x
3 |
4 | `%??%` <- function(x, y) if (!is.null(x)) y
5 |
6 | tag_meta <- function(...) htmltools::tag("meta", list(...))
7 |
8 | tag_meta_list <- function(.list) {
9 | .list %>%
10 | purrr::imap(~ tag_meta(name = .y, content = .x)) %>%
11 | unname()
12 | }
13 |
14 | collapse_single_string <- function(.list, sep = " ") {
15 | .list %>%
16 | purrr::compact() %>%
17 | vapply(collapse, "", sep = sep)
18 | }
19 |
20 | collapse <- function(x, sep = ", ") {
21 | paste(x, collapse = sep)
22 | }
23 |
24 | names_replace_underscore <- function(.list, replace = "-") {
25 | names(.list) <- gsub("_", replace, names(.list))
26 | .list
27 | }
28 |
29 | duplicate_vector_entries <- function(.list) {
30 | levels <- purrr::map_dbl(.list, purrr::vec_depth)
31 |
32 | if (!any(levels > 1)) {
33 | return(.list)
34 | }
35 |
36 | new_list <- list()
37 | for (i in seq_along(.list)) {
38 | if (levels[i] < 2) {
39 | new_list[[names(.list)[i]]] <- .list[[i]]
40 | next
41 | }
42 | flattened <- purrr::flatten(.list[i])
43 | names(flattened) <- rep(names(.list)[i], length(flattened))
44 | new_list <- c(new_list, flattened)
45 | }
46 | new_list
47 | }
48 |
49 | has_meta_with_property <- function(.meta, property = "name", value) {
50 | has_match <-
51 | .meta[[1]]$children %>%
52 | purrr::map("attribs") %>%
53 | purrr::map_lgl(~ {
54 | !is.null(.x[[property]]) && .x[[property]] == value
55 | })
56 |
57 | has_match
58 | }
59 |
--------------------------------------------------------------------------------
/man/meta_apple_itunes_app.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/apple.R
3 | \name{meta_apple_itunes_app}
4 | \alias{meta_apple_itunes_app}
5 | \title{Apple Smart Banner Meta Tag}
6 | \usage{
7 | meta_apple_itunes_app(.meta = meta(), app_id = NULL, affiliate_id = NULL, ...)
8 | }
9 | \arguments{
10 | \item{.meta}{A \code{meta} object created by \code{\link[=meta]{meta()}} or \code{\link[=as_meta]{as_meta()}}, or returned
11 | by a \verb{meta_*()} object.}
12 |
13 | \item{app_id}{Apple app ID}
14 |
15 | \item{affiliate_id}{Apple affiliate ID}
16 |
17 | \item{...}{Additional name=value pairs.}
18 | }
19 | \value{
20 | A \code{meta} object, or a set of \verb{} HTML tags inside an HTML
21 | \verb{} tag. For use in \code{\link[rmarkdown:html_document]{rmarkdown::html_document()}}, \code{\link[shiny:runApp]{shiny::runApp()}},
22 | or other HTML locations.
23 | }
24 | \description{
25 | Apple Smart Banner Meta Tag
26 | }
27 | \section{Example}{
28 |
29 |
30 | \if{html}{\out{}}\preformatted{#
31 |
32 | }\if{html}{\out{
}}
33 | }
34 |
35 | \seealso{
36 | Other meta:
37 | \code{\link{meta_apple_web_app}()},
38 | \code{\link{meta_general}()},
39 | \code{\link{meta_geo}()},
40 | \code{\link{meta_google_scholar}()},
41 | \code{\link{meta_name}()},
42 | \code{\link{meta_social}()},
43 | \code{\link{meta_tag}()},
44 | \code{\link{meta_viewport}()},
45 | \code{\link{meta}()}
46 | }
47 | \concept{meta}
48 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # ---- Default .gitignore From grkmisc ----
2 | .Rproj.user
3 | .Rhistory
4 | .RData
5 | .DS_Store
6 |
7 | # Directories that start with _
8 | _*/
9 |
10 | ## https://github.com/github/gitignore/blob/master/R.gitignore
11 | # History files
12 | .Rhistory
13 | .Rapp.history
14 |
15 | # Session Data files
16 | .RData
17 |
18 | # Example code in package build process
19 | *-Ex.R
20 |
21 | # Output files from R CMD build
22 | /*.tar.gz
23 |
24 | # Output files from R CMD check
25 | /*.Rcheck/
26 |
27 | # RStudio files
28 | .Rproj.user/
29 |
30 | # produced vignettes
31 | vignettes/*.html
32 | vignettes/*.pdf
33 |
34 | # OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3
35 | .httr-oauth
36 |
37 | # knitr and R markdown default cache directories
38 | /*_cache/
39 | /cache/
40 |
41 | # Temporary files created by R markdown
42 | *.utf8.md
43 | *.knit.md
44 |
45 | # Shiny token, see https://shiny.rstudio.com/articles/shinyapps.html
46 | rsconnect/
47 |
48 | ## https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
49 | # General
50 | .DS_Store
51 | .AppleDouble
52 | .LSOverride
53 |
54 | # Icon must end with two \r
55 | Icon
56 |
57 |
58 | # Thumbnails
59 | ._*
60 |
61 | # Files that might appear in the root of a volume
62 | .DocumentRevisions-V100
63 | .fseventsd
64 | .Spotlight-V100
65 | .TemporaryItems
66 | .Trashes
67 | .VolumeIcon.icns
68 | .com.apple.timemachine.donotpresent
69 |
70 | # Directories potentially created on remote AFP share
71 | .AppleDB
72 | .AppleDesktop
73 | Network Trash Folder
74 | Temporary Items
75 | .apdisk
76 | tests/manual
77 | docs/
78 |
--------------------------------------------------------------------------------
/man/meta.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/meta.R
3 | \name{meta}
4 | \alias{meta}
5 | \alias{is_meta}
6 | \alias{as_meta}
7 | \title{Initialize a List of HTML Metadata Tags}
8 | \usage{
9 | meta()
10 |
11 | is_meta(x)
12 |
13 | as_meta(x)
14 | }
15 | \arguments{
16 | \item{x}{A list or metathis object}
17 | }
18 | \value{
19 | A \code{meta} object, or a set of \verb{} HTML tags inside an HTML
20 | \verb{} tag. For use in \code{\link[rmarkdown:html_document]{rmarkdown::html_document()}}, \code{\link[shiny:runApp]{shiny::runApp()}},
21 | or other HTML locations.
22 | }
23 | \description{
24 | Initialize a \emph{metathis} object (i.e. a list of HTML metadata tags), test if
25 | an object is a \emph{metathis} object, or coerce a list of \code{meta} tags to be a
26 | \emph{metathis} object.
27 | }
28 | \section{Functions}{
29 | \itemize{
30 | \item \code{is_meta()}: Test if an objects is a \emph{metathis} object
31 |
32 | \item \code{as_meta()}: Convert a list of meta tags into a \emph{metathis} object.
33 |
34 | }}
35 | \examples{
36 | meta() \%>\%
37 | meta_viewport() \%>\%
38 | is_meta()
39 |
40 | list_of_meta_tags <- list(
41 | htmltools::tags$meta(github = "gadenbuie"),
42 | htmltools::tags$meta(twitter = "grrrck")
43 | )
44 |
45 | as_meta(list_of_meta_tags)
46 | }
47 | \seealso{
48 | Other meta:
49 | \code{\link{meta_apple_itunes_app}()},
50 | \code{\link{meta_apple_web_app}()},
51 | \code{\link{meta_general}()},
52 | \code{\link{meta_geo}()},
53 | \code{\link{meta_google_scholar}()},
54 | \code{\link{meta_name}()},
55 | \code{\link{meta_social}()},
56 | \code{\link{meta_tag}()},
57 | \code{\link{meta_viewport}()}
58 | }
59 | \concept{meta}
60 |
--------------------------------------------------------------------------------
/tests/testthat/test-rmd.R:
--------------------------------------------------------------------------------
1 | test_that("knit_print() and include_meta() work in Rmd", {
2 | skip_if_not(rmarkdown::pandoc_available("1.12.3"))
3 |
4 | temp_html <- tempfile("metathis-rmd", fileext = ".html")
5 | test_rmd <- test_path("rmd", "test-metathis.Rmd")
6 | rmarkdown::render(test_rmd, output_file = temp_html, quiet = TRUE)
7 | out <- readLines(temp_html)
8 |
9 | has_string <- function(str, n = 1L) {
10 | sum(grepl(str, out, fixed = TRUE)) == n
11 | }
12 |
13 | expect_true(has_string(''))
14 | expect_true(has_string(''))
15 | expect_true(has_string(''))
16 | })
17 |
18 | test_that("Doesn't create empty directory for non self-contained RMarkdown", {
19 | skip_if_not(rmarkdown::pandoc_available("1.12.3"))
20 |
21 | temp_dir <- tempfile("metathis-rmd")
22 | dir.create(temp_dir)
23 | on.exit(unlink(temp_dir))
24 |
25 | test_rmd_src <- test_path("rmd", "test-not-self-contained.Rmd")
26 | test_rmd <- file.path(temp_dir, "test.Rmd")
27 | file.copy(test_rmd_src, test_rmd)
28 | expect_silent(rmarkdown::render(test_rmd, quiet = TRUE))
29 | out <- readLines(file.path(temp_dir, "test.html"))
30 |
31 | has_string <- function(str, n = 1L) {
32 | sum(grepl(str, out, fixed = FALSE)) == n
33 | }
34 |
35 | skip_if_not(has_package_version("rmarkdown", "2.9"))
36 | expect_true(has_string(''))
37 | expect_true(has_string(''))
38 | expect_true(has_string(''))
39 |
40 | out_files <- dir(file.path(temp_dir, "test_files"))
41 | expect_false(any(grepl("^metathis", out_files)))
42 | })
43 |
--------------------------------------------------------------------------------
/.github/workflows/R-CMD-check.yaml:
--------------------------------------------------------------------------------
1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
3 | on:
4 | push:
5 | branches: [main, master]
6 | pull_request:
7 | branches: [main, master]
8 | schedule:
9 | # * is a special character in YAML so you have to quote this string
10 | - cron: "0 4 * * 1"
11 |
12 | name: R-CMD-check
13 |
14 | jobs:
15 | R-CMD-check:
16 | runs-on: ${{ matrix.config.os }}
17 |
18 | name: ${{ matrix.config.os }} (${{ matrix.config.r }})
19 |
20 | strategy:
21 | fail-fast: false
22 | matrix:
23 | config:
24 | - {os: macOS-latest, r: 'release'}
25 | - {os: windows-latest, r: 'release'}
26 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'}
27 | - {os: ubuntu-latest, r: 'release'}
28 | - {os: ubuntu-latest, r: 'oldrel-1'}
29 |
30 | env:
31 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
32 | R_KEEP_PKG_SOURCE: yes
33 |
34 | steps:
35 | - uses: actions/checkout@v2
36 |
37 | - uses: r-lib/actions/setup-pandoc@v2
38 |
39 | - uses: r-lib/actions/setup-r@v2
40 | with:
41 | r-version: ${{ matrix.config.r }}
42 | http-user-agent: ${{ matrix.config.http-user-agent }}
43 | use-public-rspm: true
44 |
45 | - uses: r-lib/actions/setup-r-dependencies@v2
46 | with:
47 | extra-packages: any::rcmdcheck
48 | needs: check
49 |
50 | - uses: r-lib/actions/check-r-package@v2
51 | with:
52 | upload-snapshots: true
53 |
54 | - name: Update status dashboard
55 | uses: gadenbuie/status/actions/status-update-rcmdcheck@main
56 | with:
57 | github-token-repo-scope: ${{ secrets.GADENBUIE_STATUS }}
58 | status-repo: gadenbuie/status
59 |
--------------------------------------------------------------------------------
/pkgdown/_pkgdown.yml:
--------------------------------------------------------------------------------
1 | url: https://pkg.garrickadenbuie.com/metathis/
2 |
3 | home:
4 | description: >
5 | Easy <meta> tags for social media cards, accessibility and quality search
6 | indexing in R Markdown and Shiny.
7 |
8 | template:
9 | package: grkgdown
10 | opengraph:
11 | image:
12 | src: man/figures/card.png
13 | twitter:
14 | creator: "@grrrck"
15 | card: summary_large_image
16 |
17 | authors:
18 | Garrick Aden-Buie:
19 | href: https://www.garrickadenbuie.com
20 |
21 | navbar:
22 | type: light
23 | structure:
24 | left:
25 | - home
26 | - intro
27 | - reference
28 | - articles
29 | - tutorials
30 | right:
31 | - news
32 | - github
33 | - twitter
34 | - garrick
35 | components:
36 | home:
37 | icon: ~
38 | text: Overview
39 | href: index.html
40 | reference:
41 | text: Reference
42 | href: reference/index.html
43 | news:
44 | icon: far fa-newspaper fa-lg
45 | href: news/index.html
46 | text: ""
47 | title: "Changelog"
48 | github:
49 | icon: fab fa-github fa-lg
50 | href: https://github.com/gadenbuie/metathis
51 | garrick:
52 | icon: fas fa-home fa-lg
53 | href: https://garrickadenbuie.com
54 | title: Garrick Aden-Buie
55 | twitter:
56 | icon: fab fa-twitter fa-lg
57 | href: https://twitter.com/grrrck
58 |
59 | reference:
60 | - title: Add meta tags
61 | desc: ~
62 | contents:
63 | - '`meta`'
64 | - '`include_meta`'
65 | - '`write_meta`'
66 | - title: Social media meta tags
67 | desc: ~
68 | contents:
69 | - '`meta_social`'
70 | - title: Scholarly literature and publications
71 | desc: ~
72 | contents:
73 | - '`meta_google_scholar`'
74 | - title: General meta tags
75 | desc: ~
76 | contents:
77 | - '`meta_name`'
78 | - '`meta_tag`'
79 | - '`meta_general`'
80 | - '`meta_viewport`'
81 | - title: Geotagging meta tags
82 | desc: ~
83 | contents:
84 | - '`meta_geo`'
85 | - title: Apple meta tags
86 | desc: ~
87 | contents:
88 | - '`meta_apple_web_app`'
89 | - '`meta_apple_itunes_app`'
90 |
--------------------------------------------------------------------------------
/tests/testthat/test-social.R:
--------------------------------------------------------------------------------
1 | test_that("meta_social()", expect_true(TRUE))
2 |
3 | describe("meta_social()", {
4 | it("finds description if already set", {
5 | .meta <- meta() %>%
6 | meta_description("test description") %>%
7 | meta_social(
8 | twitter_card_type = NULL,
9 | og_type = NULL,
10 | og_locale = NULL
11 | )
12 |
13 | expect_true(sum(grepl("description", paste(.meta))) == 3)
14 | })
15 |
16 | it("uses first description if already set", {
17 | expect_warning(
18 | .meta <- meta() %>%
19 | meta_description("abcdefg123456") %>%
20 | meta_description("not used for social") %>%
21 | meta_social(
22 | twitter_card_type = NULL,
23 | og_type = NULL,
24 | og_locale = NULL
25 | )
26 | )
27 |
28 | expect_true(sum(grepl("abcdefg123456", paste(.meta))) == 3)
29 | })
30 |
31 | it("disables pinterest", {
32 | .meta <- meta() %>%
33 | meta_social(disable_pinterest = TRUE)
34 |
35 | expect_true(
36 | any(grepl("pinterest.+nopin", paste(.meta)))
37 | )
38 | })
39 |
40 | it("duplicates vector entries", {
41 | .meta <- meta() %>%
42 | meta_social(
43 | og_author = c("Apple", "Banana")
44 | ) %>%
45 | paste()
46 |
47 | expect_true(sum(grepl("article:author", .meta)) == 2)
48 | expect_true(sum(grepl("Apple", .meta)) == 1)
49 | expect_true(sum(grepl("Banana", .meta)) == 1)
50 | })
51 |
52 | it("uses property for og: tags", {
53 | x <- meta_social(
54 | title = "R for Data Science",
55 | description = "This book with teach you how to do data science with R",
56 | url = "https://r4ds.had.co.nz",
57 | image = "https://r4ds.had.co.nz/cover.png",
58 | image_alt = "The cover of the R4DS book",
59 | og_type = "book",
60 | og_author = c("Garrett Grolemund", "Hadley Wickham"),
61 | twitter_card_type = "summary",
62 | twitter_creator = "@hadley"
63 | ) %>%
64 | as.character()
65 |
66 | x_og <- grep("og:", x, value = TRUE)
67 | expect_equal(sum(grepl("property=\"og:", x_og)), length(x_og))
68 | })
69 | })
70 |
--------------------------------------------------------------------------------
/R/geo.R:
--------------------------------------------------------------------------------
1 |
2 | #' Geotagging Metadata Tags
3 | #'
4 | #' @template describe-meta
5 | #' @param icbm Latitude and longitude of geographic positions specified as
6 | #' `"lat, long"`. Can optionally be a length-two vector, i.e. `c(lat, long)`.
7 | #' @param geo_position Latitude and longitude of geographic positions specified
8 | #' as `"lat;long"`. Can optionally be a length-two vector, i.e. `c(lat,
9 | #' long)`.
10 | #' @param geo_region Name of the geographic region related to the page content,
11 | #' specified using [ISO-3166](https://en.wikipedia.org/wiki/ISO_3166)
12 | #' 2-character country code and 2-character national subdivision. Example:
13 | #' `"US-NY"`.
14 | #' @param geo_placename Name of the geographic place related to the page
15 | #' content. Example: `"Atlanta, Georgia"`.
16 | #' @param ... Additional geotagging metadata keyword and value pairs, such as
17 | #' `geo.country`, `geo.a1`, ..., `geo.a3`, etc. Underscores in the keyword
18 | #' will be converted to periods, so you can also specify `geo_country` in
19 | #' place of `geo.country`.
20 | #'
21 | #' @references
22 | #' [ICBM on Wikipedia](https://en.wikipedia.org/wiki/ICBM_address#Modern_use),
23 | #' [Geotagging on Wikipedia](https://en.wikipedia.org/wiki/Geotagging#HTML_pages)
24 | #'
25 | #' @template describe-meta-return
26 | #' @examples
27 | #' meta() %>%
28 | #' meta_geo(
29 | #' icbm = c(50.167958, -97.133185),
30 | #' geo_position = c(50.167958, -97.133185),
31 | #' geo_placename = "Manitoba, Canada",
32 | #' geo_region = "ca-mb"
33 | #' )
34 | #'
35 | #' @export
36 | meta_geo <- function(
37 | .meta = meta(),
38 | icbm = NULL,
39 | geo_position = NULL,
40 | geo_region = NULL,
41 | geo_placename = NULL,
42 | ...
43 | ) {
44 | assert_is_meta(.meta)
45 |
46 | geo_values <- list(
47 | ICBM = icbm %??% collapse(icbm),
48 | "geo.position" = geo_position %??% collapse(geo_position, ";"),
49 | "geo.region" = geo_region,
50 | "geo.placename" = geo_placename,
51 | ...
52 | )
53 |
54 | meta_geo <-
55 | geo_values %>%
56 | names_replace_underscore(".") %>%
57 | collapse_single_string() %>%
58 | tag_meta_list()
59 |
60 | append_to_meta(.meta, meta_geo)
61 | }
62 |
--------------------------------------------------------------------------------
/tests/testthat/test-meta.R:
--------------------------------------------------------------------------------
1 | test_that("test-meta", expect_true(TRUE))
2 |
3 | describe("meta class", {
4 |
5 | it("has class meta", {
6 | expect_s3_class(meta(), "meta")
7 | expect_s3_class(meta(), "shiny.tag.list")
8 | })
9 |
10 | it("is_meta()", {
11 | expect_true(meta() %>% is_meta())
12 | expect_false(list() %>% is_meta())
13 | })
14 |
15 | it("assert_is_meta", {
16 | expect_true(assert_is_meta(meta()))
17 | expect_error(asser_is_meta(list()))
18 | })
19 |
20 | it("as_meta()", {
21 | list(name = "theme-color") %>%
22 | as_meta() %>%
23 | expect_s3_class("meta")
24 |
25 | expect_error(as_meta(3), "numeric")
26 | expect_error(data.frame(a = 1, b = 2) %>% as_meta(), "data.frame")
27 | })
28 |
29 | it("print.meta", {
30 | expect_equal(capture.output(print(meta_tag(a = "a"))), '')
31 | })
32 | })
33 |
34 | describe("meta_name()", {
35 | it("creates tags with name/content pairs", {
36 | exp <- ''
37 | expect_equal_meta(meta_name("github-repo" = "hadley/r4ds"), exp)
38 |
39 | exp2 <- c(
40 | "",
41 | ""
42 | )
43 | expect_equal_meta(meta_name("A" = "a", "B" = "b"), exp2)
44 | })
45 |
46 | it("concatenates if length(content) > 1", {
47 | exp <- ''
48 | expect_equal_meta(meta_name(value = c("a", "b")), exp)
49 | })
50 | })
51 |
52 | describe("meta_tag()", {
53 | it("creates tags with attribute = value pairs", {
54 | exp <- ''
55 | expect_equal_meta(meta_tag(A = "a", B = "b"), exp)
56 | })
57 |
58 | it("errors if length(value) > 1", {
59 | expect_error(meta_tag(A = c('a', 'b')))
60 | })
61 | })
62 |
63 | describe("meta_find_description()", {
64 | it("finds existing description", {
65 | expect_equal(
66 | meta() %>% meta_description("found me!") %>% meta_find_description(),
67 | "found me!"
68 | )
69 | })
70 |
71 | it("returns NULL if no description", {
72 | expect_null(meta() %>% meta_find_description())
73 |
74 | expect_null(meta() %>% meta_tag(a = '1') %>% meta_find_description())
75 | })
76 |
77 | })
78 |
--------------------------------------------------------------------------------
/man/meta_apple_web_app.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/apple.R
3 | \name{meta_apple_web_app}
4 | \alias{meta_apple_web_app}
5 | \title{Apple Web App Meta Tags}
6 | \usage{
7 | meta_apple_web_app(
8 | .meta = meta(),
9 | title = NULL,
10 | capable = NULL,
11 | status_bar_style = c("default", "black", "black-translucent")
12 | )
13 | }
14 | \arguments{
15 | \item{.meta}{A \code{meta} object created by \code{\link[=meta]{meta()}} or \code{\link[=as_meta]{as_meta()}}, or returned
16 | by a \verb{meta_*()} object.}
17 |
18 | \item{title}{Launch Icon Title}
19 |
20 | \item{capable}{Enables standalone (full-screen) mode if TRUE}
21 |
22 | \item{status_bar_style}{Status bar appearance. has no effect unless
23 | standalone more is enabled (see \code{capable}).
24 |
25 | "If content is set to default, the status bar appears normal. If set to
26 | black, the status bar has a black background. If set to black-translucent,
27 | the status bar is black and translucent. If set to default or black, the
28 | web content is displayed below the status bar. If set to black-translucent,
29 | the web content is displayed on the entire screen, partially obscured by
30 | the status bar. The default value is default."}
31 | }
32 | \value{
33 | A \code{meta} object, or a set of \verb{} HTML tags inside an HTML
34 | \verb{} tag. For use in \code{\link[rmarkdown:html_document]{rmarkdown::html_document()}}, \code{\link[shiny:runApp]{shiny::runApp()}},
35 | or other HTML locations.
36 | }
37 | \description{
38 | Apple Web App Meta Tags
39 | }
40 | \examples{
41 | meta() \%>\%
42 | meta_apple_web_app(
43 | title = "My Fancy App",
44 | capable = TRUE,
45 | status_bar_style = "black-translucent"
46 | )
47 | }
48 | \references{
49 | \url{https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html}
50 | }
51 | \seealso{
52 | Other meta:
53 | \code{\link{meta_apple_itunes_app}()},
54 | \code{\link{meta_general}()},
55 | \code{\link{meta_geo}()},
56 | \code{\link{meta_google_scholar}()},
57 | \code{\link{meta_name}()},
58 | \code{\link{meta_social}()},
59 | \code{\link{meta_tag}()},
60 | \code{\link{meta_viewport}()},
61 | \code{\link{meta}()}
62 | }
63 | \concept{meta}
64 |
--------------------------------------------------------------------------------
/tests/testthat/test-google_scholar.R:
--------------------------------------------------------------------------------
1 | test_that("meta_google_scholar()", {
2 | expected <- '
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | '
16 |
17 | meta <- meta_google_scholar(
18 | title = c(
19 | "The testis isoform of the phosphorylase kinase catalytic subunit (PhK-T)",
20 | "plays a critical role in regulation of glycogen mobilization in developing lung"
21 | ),
22 | author = c(
23 | "Liu, Li",
24 | "Rannels, Stephen R.",
25 | "Falconieri, Mary",
26 | "Phillips, Karen S.",
27 | "Wolpert, Ellen B.",
28 | "Weaver, Timothy E."
29 | ),
30 | publication_date = "1996/05/17",
31 | journal_title = "Journal of Biological Chemistry",
32 | volume = 271,
33 | issue = 20,
34 | firstpage = 11761,
35 | lastpage = 11766,
36 | pdf_url = "http://www.example.com/content/271/20/11761.full.pdf"
37 | )
38 |
39 | meta_chr <- gsub("/>", ">", format(meta))
40 | expect_equal(meta_chr, expected)
41 | })
42 |
43 | test_that("meta_google_scholar() catches common errors", {
44 | expect_error(meta_google_scholar(title = "foo"))
45 | expect_error(
46 | meta_google_scholar(title = "a", author = "b", publication_date = "2019-01-01"),
47 | "publication_date"
48 | )
49 | expect_error(
50 | meta_google_scholar(title = "a", author = "b", publication_date = c(1999, 2000)),
51 | "publication_date"
52 | )
53 | expect_error(
54 | meta_google_scholar(title = "a", author = "b", publication_date = 2000, online_date = "1/1/2021"),
55 | "online_date"
56 | )
57 | })
58 |
--------------------------------------------------------------------------------
/man/meta_geo.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/geo.R
3 | \name{meta_geo}
4 | \alias{meta_geo}
5 | \title{Geotagging Metadata Tags}
6 | \usage{
7 | meta_geo(
8 | .meta = meta(),
9 | icbm = NULL,
10 | geo_position = NULL,
11 | geo_region = NULL,
12 | geo_placename = NULL,
13 | ...
14 | )
15 | }
16 | \arguments{
17 | \item{.meta}{A \code{meta} object created by \code{\link[=meta]{meta()}} or \code{\link[=as_meta]{as_meta()}}, or returned
18 | by a \verb{meta_*()} object.}
19 |
20 | \item{icbm}{Latitude and longitude of geographic positions specified as
21 | \code{"lat, long"}. Can optionally be a length-two vector, i.e. \code{c(lat, long)}.}
22 |
23 | \item{geo_position}{Latitude and longitude of geographic positions specified
24 | as \code{"lat;long"}. Can optionally be a length-two vector, i.e. \code{c(lat, long)}.}
25 |
26 | \item{geo_region}{Name of the geographic region related to the page content,
27 | specified using \href{https://en.wikipedia.org/wiki/ISO_3166}{ISO-3166}
28 | 2-character country code and 2-character national subdivision. Example:
29 | \code{"US-NY"}.}
30 |
31 | \item{geo_placename}{Name of the geographic place related to the page
32 | content. Example: \code{"Atlanta, Georgia"}.}
33 |
34 | \item{...}{Additional geotagging metadata keyword and value pairs, such as
35 | \code{geo.country}, \code{geo.a1}, ..., \code{geo.a3}, etc. Underscores in the keyword
36 | will be converted to periods, so you can also specify \code{geo_country} in
37 | place of \code{geo.country}.}
38 | }
39 | \value{
40 | A \code{meta} object, or a set of \verb{} HTML tags inside an HTML
41 | \verb{} tag. For use in \code{\link[rmarkdown:html_document]{rmarkdown::html_document()}}, \code{\link[shiny:runApp]{shiny::runApp()}},
42 | or other HTML locations.
43 | }
44 | \description{
45 | Geotagging Metadata Tags
46 | }
47 | \examples{
48 | meta() \%>\%
49 | meta_geo(
50 | icbm = c(50.167958, -97.133185),
51 | geo_position = c(50.167958, -97.133185),
52 | geo_placename = "Manitoba, Canada",
53 | geo_region = "ca-mb"
54 | )
55 |
56 | }
57 | \references{
58 | \href{https://en.wikipedia.org/wiki/ICBM_address#Modern_use}{ICBM on Wikipedia},
59 | \href{https://en.wikipedia.org/wiki/Geotagging#HTML_pages}{Geotagging on Wikipedia}
60 | }
61 | \seealso{
62 | Other meta:
63 | \code{\link{meta_apple_itunes_app}()},
64 | \code{\link{meta_apple_web_app}()},
65 | \code{\link{meta_general}()},
66 | \code{\link{meta_google_scholar}()},
67 | \code{\link{meta_name}()},
68 | \code{\link{meta_social}()},
69 | \code{\link{meta_tag}()},
70 | \code{\link{meta_viewport}()},
71 | \code{\link{meta}()}
72 | }
73 | \concept{meta}
74 |
--------------------------------------------------------------------------------
/man/meta_viewport.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/viewport.R
3 | \name{meta_viewport}
4 | \alias{meta_viewport}
5 | \title{Viewport Meta Tag}
6 | \usage{
7 | meta_viewport(
8 | .meta = meta(),
9 | width = "device-width",
10 | initial_scale = "1",
11 | orientation = c("auto", "portrait", "landscape"),
12 | min_width = NULL,
13 | max_width = NULL,
14 | height = NULL,
15 | min_height = NULL,
16 | max_height = NULL,
17 | minimum_scale = NULL,
18 | maximum_scale = NULL,
19 | user_scalable = NULL,
20 | ...
21 | )
22 | }
23 | \arguments{
24 | \item{.meta}{A \code{meta} object created by \code{\link[=meta]{meta()}} or \code{\link[=as_meta]{as_meta()}}, or returned
25 | by a \verb{meta_*()} object.}
26 |
27 | \item{width}{Sets the width of initial viewport. \code{width} sets \code{min_width} and
28 | \code{max_width} and may contain two values; for example, the following are
29 | equivalent: \code{"300px 500px"} or \code{c("300px", "500px")}). The values may be
30 | a number with units, a percentage, or \code{"device-width"}. Pixels are assumed
31 | if no units are provided.}
32 |
33 | \item{initial_scale}{Initial scale}
34 |
35 | \item{orientation}{One of \code{"auto"}, \code{"portrait"}, \code{"landscape"}.}
36 |
37 | \item{min_width, max_width}{Minimum and maximum initial viewport width. See
38 | \code{width} for more information. \code{width} is ignored if \code{min_width} or
39 | \code{max_width} are set.}
40 |
41 | \item{height, min_height, max_height}{Sets height of initial viewport. Follows
42 | the same conventions as \code{width}, \code{min_width}, and \code{max_width}.}
43 |
44 | \item{minimum_scale}{Minimum scale}
45 |
46 | \item{maximum_scale}{Maximum scale}
47 |
48 | \item{user_scalable}{User scalable}
49 |
50 | \item{...}{Additional name/value pairs}
51 | }
52 | \value{
53 | A \code{meta} object, or a set of \verb{} HTML tags inside an HTML
54 | \verb{} tag. For use in \code{\link[rmarkdown:html_document]{rmarkdown::html_document()}}, \code{\link[shiny:runApp]{shiny::runApp()}},
55 | or other HTML locations.
56 | }
57 | \description{
58 | Create or add a viewport meta tag.
59 | }
60 | \examples{
61 | meta() \%>\%
62 | meta_viewport()
63 |
64 | meta() \%>\%
65 | meta_viewport(orientation = NULL)
66 |
67 | meta() \%>\%
68 | meta_viewport(maximum_scale = 1)
69 |
70 | }
71 | \references{
72 | \href{https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag}{MDN: Viewport Meta Tag},
73 | }
74 | \seealso{
75 | Other meta:
76 | \code{\link{meta_apple_itunes_app}()},
77 | \code{\link{meta_apple_web_app}()},
78 | \code{\link{meta_general}()},
79 | \code{\link{meta_geo}()},
80 | \code{\link{meta_google_scholar}()},
81 | \code{\link{meta_name}()},
82 | \code{\link{meta_social}()},
83 | \code{\link{meta_tag}()},
84 | \code{\link{meta}()}
85 | }
86 | \concept{meta}
87 |
--------------------------------------------------------------------------------
/R/viewport.R:
--------------------------------------------------------------------------------
1 | #' Viewport Meta Tag
2 | #'
3 | #' Create or add a viewport meta tag.
4 | #'
5 | #' @references
6 | #' [MDN: Viewport Meta Tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Viewport_meta_tag),
7 | #'
8 | #' @template describe-meta
9 | #' @param width Sets the width of initial viewport. `width` sets `min_width` and
10 | #' `max_width` and may contain two values; for example, the following are
11 | #' equivalent: `"300px 500px"` or `c("300px", "500px")`). The values may be
12 | #' a number with units, a percentage, or `"device-width"`. Pixels are assumed
13 | #' if no units are provided.
14 | #' @param min_width,max_width Minimum and maximum initial viewport width. See
15 | #' `width` for more information. `width` is ignored if `min_width` or
16 | #' `max_width` are set.
17 | #' @param height,min_height,max_height Sets height of initial viewport. Follows
18 | #' the same conventions as `width`, `min_width`, and `max_width`.
19 | #' @param initial_scale Initial scale
20 | #' @param orientation One of `"auto"`, `"portrait"`, `"landscape"`.
21 | #' @param minimum_scale Minimum scale
22 | #' @param maximum_scale Maximum scale
23 | #' @param user_scalable User scalable
24 | #' @param ... Additional name/value pairs
25 | #'
26 | #' @examples
27 | #' meta() %>%
28 | #' meta_viewport()
29 | #'
30 | #' meta() %>%
31 | #' meta_viewport(orientation = NULL)
32 | #'
33 | #' meta() %>%
34 | #' meta_viewport(maximum_scale = 1)
35 | #'
36 | #' @template describe-meta-return
37 | #' @export
38 | meta_viewport <- function(
39 | .meta = meta(),
40 | width = "device-width",
41 | initial_scale = "1",
42 | orientation = c("auto", "portrait", "landscape"),
43 | min_width = NULL,
44 | max_width = NULL,
45 | height = NULL,
46 | min_height = NULL,
47 | max_height = NULL,
48 | minimum_scale = NULL,
49 | maximum_scale = NULL,
50 | user_scalable = NULL,
51 | ...
52 | ) {
53 |
54 | assert_is_meta(.meta)
55 |
56 | has_minmax_width <- purrr::some(list(min_width, max_width), purrr::negate(is.null))
57 | has_minmax_height <- purrr::some(list(min_height, max_height), purrr::negate(is.null))
58 |
59 | if (has_minmax_width && !is.null(width)) {
60 | warning("Ignoring `width` because one of `min_width` or `max_width` was provided")
61 | width <- NULL
62 | }
63 |
64 | if (has_minmax_height && !is.null(height)) {
65 | warning("Ignoring `height` because one of `min_height` or `max_height` was provided")
66 | height <- NULL
67 | }
68 |
69 | orientation <- orientation %??% match.arg(orientation)
70 |
71 | content <- c(
72 | width = if (is.null(min_width) && is.null(max_width)) width,
73 | "initial-scale" = initial_scale,
74 | orientation = orientation,
75 | "minimum-scale" = minimum_scale,
76 | "maximum-scale" = maximum_scale,
77 | "user-scalable" = user_scalable,
78 | "min-width" = min_width,
79 | "max-width" = max_width,
80 | height = if (is.null(min_height) && is.null(max_height)) height,
81 | "min-height" = min_height,
82 | "max-height" = max_height,
83 | ...
84 | )
85 |
86 | content <- paste(names(content), content, sep = "=", collapse = ", ")
87 |
88 | if (!nzchar(content)) {
89 | stop("At least one argument must be provided")
90 | }
91 |
92 | # viewport tag has to come first in list of meta tags
93 | meta_new <- tag_meta(name = "viewport", content = content)
94 |
95 | prepend_to_meta(.meta, list(meta_new))
96 | }
97 |
--------------------------------------------------------------------------------
/man/meta_general.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/general.R
3 | \name{meta_general}
4 | \alias{meta_general}
5 | \alias{meta_description}
6 | \alias{meta_subject}
7 | \alias{meta_referrer}
8 | \alias{meta_robots}
9 | \alias{meta_theme_color}
10 | \title{General Metadata Tags}
11 | \usage{
12 | meta_general(
13 | .meta = meta(),
14 | application_name = NULL,
15 | theme_color = NULL,
16 | description = NULL,
17 | robots = NULL,
18 | generator = NULL,
19 | subject = NULL,
20 | rating = NULL,
21 | referrer = NULL
22 | )
23 |
24 | meta_description(.meta = meta(), description)
25 |
26 | meta_subject(.meta = meta(), subject)
27 |
28 | meta_referrer(.meta = meta(), referrer)
29 |
30 | meta_robots(.meta = meta(), robots)
31 |
32 | meta_theme_color(.meta = meta(), theme_color)
33 | }
34 | \arguments{
35 | \item{.meta}{A \code{meta} object created by \code{\link[=meta]{meta()}} or \code{\link[=as_meta]{as_meta()}}, or returned
36 | by a \verb{meta_*()} object.}
37 |
38 | \item{application_name}{Name of web application (only should be used if the
39 | website is used as an app).}
40 |
41 | \item{theme_color}{Theme Color for Chrome, Firefox OS and Opera, e.g.
42 | \code{"#00589a"}.}
43 |
44 | \item{description}{Short description of the document (limit to 150
45 | characters), This content \emph{may} be used as a part of search engine results.}
46 |
47 | \item{robots}{Control the behavior of search engine crawling and indexing,
48 | e.g. \code{"index,follow"}. Valid names are \code{"index"}, \code{"noindex"}, \code{"follow"},
49 | \code{"nofollow"}. May be a vector or a single string with comma-separated
50 | values.
51 |
52 | See \url{https://www.robotstxt.org/meta.html} for more information.}
53 |
54 | \item{generator}{Identify the software used to build the document (i.e. -
55 | WordPress, Dreamweaver).}
56 |
57 | \item{subject}{Short description of your document's subject.}
58 |
59 | \item{rating}{Gives a general age rating based on the document's content,
60 | e.g. \code{"General"}.}
61 |
62 | \item{referrer}{Allows control over how referrer information is passed, .e.g.
63 | \code{"no-referrer"}. Valid values include \code{"no-referrer"},
64 | \code{"no-referrer-when-downgrade"}, \code{"same-origin"}, \code{"origin"},
65 | \code{"strict-origin"}, \code{"origin-when-cross-origin"},
66 | \code{"strict-origin-when-cross-origin"}, or \code{"unsafe-url"}.}
67 | }
68 | \value{
69 | A \code{meta} object, or a set of \verb{} HTML tags inside an HTML
70 | \verb{} tag. For use in \code{\link[rmarkdown:html_document]{rmarkdown::html_document()}}, \code{\link[shiny:runApp]{shiny::runApp()}},
71 | or other HTML locations.
72 | }
73 | \description{
74 | Generate metadata tags for general website properties.
75 | }
76 | \examples{
77 | meta() \%>\%
78 | meta_general(
79 | application_name = "Application Name",
80 | theme_color = "#4285f4",
81 | description = "A description of this page",
82 | robots = "index,follow",
83 | generator = "R-Shiny",
84 | subject = "Awesome R projects",
85 | rating = "General",
86 | referrer = "no-referrer"
87 | )
88 |
89 | }
90 | \seealso{
91 | Other meta:
92 | \code{\link{meta_apple_itunes_app}()},
93 | \code{\link{meta_apple_web_app}()},
94 | \code{\link{meta_geo}()},
95 | \code{\link{meta_google_scholar}()},
96 | \code{\link{meta_name}()},
97 | \code{\link{meta_social}()},
98 | \code{\link{meta_tag}()},
99 | \code{\link{meta_viewport}()},
100 | \code{\link{meta}()}
101 | }
102 | \concept{meta}
103 |
--------------------------------------------------------------------------------
/R/general.R:
--------------------------------------------------------------------------------
1 |
2 | #' General Metadata Tags
3 | #'
4 | #' Generate metadata tags for general website properties.
5 | #'
6 | #' @template describe-meta
7 | #' @param application_name Name of web application (only should be used if the
8 | #' website is used as an app).
9 | #' @param theme_color Theme Color for Chrome, Firefox OS and Opera, e.g.
10 | #' `"#00589a"`.
11 | #' @param description Short description of the document (limit to 150
12 | #' characters), This content *may* be used as a part of search engine results.
13 | #' @param robots Control the behavior of search engine crawling and indexing,
14 | #' e.g. `"index,follow"`. Valid names are `"index"`, `"noindex"`, `"follow"`,
15 | #' `"nofollow"`. May be a vector or a single string with comma-separated
16 | #' values.
17 | #'
18 | #' See for more information.
19 | #' @param generator Identify the software used to build the document (i.e. -
20 | #' WordPress, Dreamweaver).
21 | #' @param subject Short description of your document's subject.
22 | #' @param rating Gives a general age rating based on the document's content,
23 | #' e.g. `"General"`.
24 | #' @param referrer Allows control over how referrer information is passed, .e.g.
25 | #' `"no-referrer"`. Valid values include `"no-referrer"`,
26 | #' `"no-referrer-when-downgrade"`, `"same-origin"`, `"origin"`,
27 | #' `"strict-origin"`, `"origin-when-cross-origin"`,
28 | #' `"strict-origin-when-cross-origin"`, or `"unsafe-url"`.
29 | #'
30 | #' @template describe-meta-return
31 | #' @examples
32 | #' meta() %>%
33 | #' meta_general(
34 | #' application_name = "Application Name",
35 | #' theme_color = "#4285f4",
36 | #' description = "A description of this page",
37 | #' robots = "index,follow",
38 | #' generator = "R-Shiny",
39 | #' subject = "Awesome R projects",
40 | #' rating = "General",
41 | #' referrer = "no-referrer"
42 | #' )
43 | #'
44 | #' @export
45 | meta_general <- function(
46 | .meta = meta(),
47 | application_name = NULL,
48 | theme_color = NULL,
49 | description = NULL,
50 | robots = NULL,
51 | generator = NULL,
52 | subject = NULL,
53 | rating = NULL,
54 | referrer = NULL
55 | ) {
56 | assert_is_meta(.meta)
57 |
58 | general <- list(
59 | application_name = application_name,
60 | theme_color = theme_color,
61 | description = description,
62 | robots = robots %??% collapse(robots, ","),
63 | generator = generator,
64 | subject = subject,
65 | rating = rating,
66 | referrer = referrer
67 | )
68 |
69 | meta_general <-
70 | general %>%
71 | names_replace_underscore("-") %>%
72 | collapse_single_string() %>%
73 | tag_meta_list()
74 |
75 | append_to_meta(.meta, meta_general)
76 | }
77 |
78 |
79 | #' @rdname meta_general
80 | #' @export
81 | meta_description <- function(.meta = meta(), description) {
82 | meta_general(.meta, description = description)
83 | }
84 |
85 | #' @rdname meta_general
86 | #' @export
87 | meta_subject <- function(.meta = meta(), subject) {
88 | meta_general(.meta, subject = subject)
89 | }
90 |
91 |
92 | #' @rdname meta_general
93 | #' @export
94 | meta_referrer <- function(.meta = meta(), referrer) {
95 | meta_general(.meta, referrer = referrer)
96 | }
97 |
98 | #' @rdname meta_general
99 | #' @export
100 | meta_robots <- function(.meta = meta(), robots) {
101 | meta_general(.meta, robots = robots)
102 | }
103 |
104 | #' @rdname meta_general
105 | #' @export
106 | meta_theme_color <- function(.meta = meta(), theme_color) {
107 | meta_general(.meta, theme_color = theme_color)
108 | }
109 |
--------------------------------------------------------------------------------
/R/apple.R:
--------------------------------------------------------------------------------
1 | ##
2 | ##
3 | ##
4 | ##
5 | ##
6 | ##
7 | ##
8 | ##
9 | ##
10 | ##
11 | ##
12 | ##
13 | ##
14 | ##
15 | ##
16 | ##
17 | ##
18 | ##
19 | ##
20 | ##
21 | ##
22 | ##
23 | ##
24 | ## [Configuring Web Applications](https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/ConfiguringWebApplications/ConfiguringWebApplications.html)
25 |
26 |
27 | #' Apple Web App Meta Tags
28 | #'
29 | #' @template describe-meta
30 | #' @template describe-meta-return
31 | #' @param title Launch Icon Title
32 | #' @param capable Enables standalone (full-screen) mode if TRUE
33 | #' @param status_bar_style Status bar appearance. has no effect unless
34 | #' standalone more is enabled (see `capable`).
35 | #'
36 | #' "If content is set to default, the status bar appears normal. If set to
37 | #' black, the status bar has a black background. If set to black-translucent,
38 | #' the status bar is black and translucent. If set to default or black, the
39 | #' web content is displayed below the status bar. If set to black-translucent,
40 | #' the web content is displayed on the entire screen, partially obscured by
41 | #' the status bar. The default value is default."
42 | #'
43 | #' @references
44 | #'
45 | #'
46 | #' @examples
47 | #' meta() %>%
48 | #' meta_apple_web_app(
49 | #' title = "My Fancy App",
50 | #' capable = TRUE,
51 | #' status_bar_style = "black-translucent"
52 | #' )
53 | #' @export
54 | meta_apple_web_app <- function(
55 | .meta = meta(),
56 | title = NULL,
57 | capable = NULL,
58 | status_bar_style = c("default", "black", "black-translucent")
59 | ) {
60 | assert_is_meta(.meta)
61 |
62 | apple <- list(
63 | title = title,
64 | capable = capable %??% ifelse(capable[[1]], "yes", "no"),
65 | status_bar_style = status_bar_style %??% match.arg(status_bar_style)
66 | )
67 |
68 | names(apple) <- paste0("apple-mobile-web-app-", names(apple))
69 |
70 | meta_apple <-
71 | apple %>%
72 | names_replace_underscore("-") %>%
73 | collapse_single_string() %>%
74 | tag_meta_list()
75 |
76 | append_to_meta(.meta, meta_apple)
77 | }
78 |
79 | #' Apple Smart Banner Meta Tag
80 | #'
81 | #' @template describe-meta
82 | #' @template describe-meta-return
83 | #' @param app_id Apple app ID
84 | #' @param affiliate_id Apple affiliate ID
85 | #' @param ... Additional name=value pairs.
86 | #'
87 | #' @section Example:
88 | #'
89 | #' ```
90 | #' #
91 | #'
92 | #' ```
93 | #'
94 | #' @export
95 | meta_apple_itunes_app <- function(
96 | .meta = meta(),
97 | app_id = NULL,
98 | affiliate_id = NULL,
99 | ...
100 | ) {
101 |
102 | assert_is_meta(.meta)
103 |
104 | args <- c(
105 | list(`app-id` = app_id, `affiliate-data` = affiliate_id),
106 | list(...)
107 | )
108 | args <- purrr::compact(args)
109 | if (!length(args)) {
110 | return(.meta)
111 | }
112 |
113 | content <- args %>%
114 | purrr::imap_chr(~ paste0(.y, "=", .x)) %>%
115 | collapse(",")
116 |
117 | meta_new <- tag_meta(name = "apple-itunes-app", content = content)
118 |
119 | append_to_meta(.meta, list(meta_new))
120 | }
121 |
--------------------------------------------------------------------------------
/man/meta_social.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/social.R
3 | \name{meta_social}
4 | \alias{meta_social}
5 | \title{Social Media Metadata}
6 | \usage{
7 | meta_social(
8 | .meta = meta(),
9 | title = NULL,
10 | url = NULL,
11 | image = NULL,
12 | image_alt = NULL,
13 | image_width = NULL,
14 | image_height = NULL,
15 | description = NULL,
16 | twitter_card_type = c("summary", "summary_large_image", "app", "player"),
17 | twitter_creator = NULL,
18 | twitter_site = twitter_creator,
19 | og_type = "website",
20 | og_locale = "en_US",
21 | og_author = NULL,
22 | og_site_name = NULL,
23 | facebook_app_id = NULL,
24 | disable_pinterest = FALSE
25 | )
26 | }
27 | \arguments{
28 | \item{.meta}{A \code{meta} object created by \code{\link[=meta]{meta()}} or \code{\link[=as_meta]{as_meta()}}, or returned
29 | by a \verb{meta_*()} object.}
30 |
31 | \item{title}{Content title}
32 |
33 | \item{url}{Content URL}
34 |
35 | \item{image}{Image url for card.}
36 |
37 | \item{image_alt}{A description of what's in the image (not a caption)}
38 |
39 | \item{image_width}{The width of the image in pixels}
40 |
41 | \item{image_height}{The height of the image in pixels}
42 |
43 | \item{description}{Content description. If you have already used
44 | \code{\link[=meta_general]{meta_general()}} to set the content's description, that description will
45 | automatically be used.}
46 |
47 | \item{twitter_card_type}{One of \code{"summary"}, \code{"summary_large_image"},
48 | \code{"app"}, or \code{"player"}.}
49 |
50 | \item{twitter_creator}{\verb{@username} for the content creator / author.}
51 |
52 | \item{twitter_site}{\verb{@username`` for the website used in the card footer. }twitter_creator` is used by default.}
53 |
54 | \item{og_type}{Open Graph card type, default is \code{"website"}. Other common
55 | options include \code{"article"}, \code{"book"}, or \code{"profile"}. The full list of
56 | valid options can be referenced at \url{https://ogp.me/}}
57 |
58 | \item{og_locale}{The locale these tags are marked up in. Of the format \code{language_TERRITORY}. Default is \code{"en_US"}.}
59 |
60 | \item{og_author}{Writers of the article. Multiple authors may be specified in
61 | a vector of character strings.}
62 |
63 | \item{og_site_name}{The name of the site hosting the content}
64 |
65 | \item{facebook_app_id}{The Facebook app ID. See the
66 | \href{https://developers.facebook.com/docs/sharing/webmasters#markup}{Facebook Open Graph Markup}
67 | page for more information.}
68 |
69 | \item{disable_pinterest}{If \code{TRUE}, adds a metadata tag disabling pins from
70 | your website. See the
71 | \href{https://help.pinterest.com/en/business/article/prevent-saves-to-pinterest-from-your-site}{Pinterest help center}
72 | for more information.}
73 | }
74 | \value{
75 | A \code{meta} object, or a set of \verb{} HTML tags inside an HTML
76 | \verb{} tag. For use in \code{\link[rmarkdown:html_document]{rmarkdown::html_document()}}, \code{\link[shiny:runApp]{shiny::runApp()}},
77 | or other HTML locations.
78 | }
79 | \description{
80 | Generate metadata tags for social media cards.
81 | }
82 | \examples{
83 | meta() \%>\%
84 | meta_social(
85 | title = "R for Data Science",
86 | description = "This book with teach you how to do data science with R",
87 | url = "https://r4ds.had.co.nz",
88 | image = "https://r4ds.had.co.nz/cover.png",
89 | image_alt = "The cover of the R4DS book",
90 | og_type = "book",
91 | og_author = c("Garrett Grolemund", "Hadley Wickham"),
92 | twitter_card_type = "summary",
93 | twitter_creator = "@hadley"
94 | )
95 |
96 | }
97 | \references{
98 | \itemize{
99 | \item \href{https://ogp.me/}{Open Graph}
100 | \item \href{https://search.google.com/structured-data/testing-tool}{Google Structured Data Testing Tool}
101 | \item \href{https://developers.facebook.com/tools/debug/}{Facebook Sharing Debugger}
102 | \item \href{https://developer.twitter.com/en/docs/twitter-for-websites/cards/guides/getting-started}{Twitter Card Documentation}
103 | }
104 | }
105 | \seealso{
106 | Other meta:
107 | \code{\link{meta_apple_itunes_app}()},
108 | \code{\link{meta_apple_web_app}()},
109 | \code{\link{meta_general}()},
110 | \code{\link{meta_geo}()},
111 | \code{\link{meta_google_scholar}()},
112 | \code{\link{meta_name}()},
113 | \code{\link{meta_tag}()},
114 | \code{\link{meta_viewport}()},
115 | \code{\link{meta}()}
116 | }
117 | \concept{meta}
118 |
--------------------------------------------------------------------------------
/.github/workflows/pkgdown.yaml:
--------------------------------------------------------------------------------
1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
3 | on:
4 | push:
5 | tags:
6 | - 'v[0-9]+.[0-9]+.[0-9]+' # build on version tags
7 | - '!v[0-9]+.[0-9]+.[0-9]+.[0-9]+' # but not if version involves a dev component
8 | branches:
9 | - main
10 | pull_request:
11 | branches:
12 | - main
13 | types:
14 | - opened
15 | - reopened
16 | - synchronize
17 | - closed
18 | paths:
19 | - 'man/**'
20 | - 'pkgdown/**'
21 | - 'vignettes/**'
22 | - 'NEWS.md'
23 | - 'README.md'
24 | workflow_dispatch:
25 |
26 | name: pkgdown
27 |
28 | jobs:
29 | pkgdown:
30 | if: ${{ !(github.event_name == 'pull_request' && github.event.action == 'closed') }}
31 | runs-on: ubuntu-latest
32 |
33 | # Only restrict concurrency for non-PR jobs
34 | concurrency:
35 | group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }}
36 |
37 | env:
38 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
39 |
40 | steps:
41 | - uses: actions/checkout@v2
42 |
43 | - uses: r-lib/actions/setup-pandoc@v2
44 |
45 | - uses: r-lib/actions/setup-r@v2
46 | with:
47 | use-public-rspm: true
48 |
49 | - uses: r-lib/actions/setup-r-dependencies@v2
50 | with:
51 | extra-packages: any::pkgdown, local::.
52 | needs: website
53 |
54 | - name: Build site
55 | shell: Rscript {0}
56 | run: |
57 | pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE)
58 | pkg <- pkgdown::as_pkgdown(".")
59 |
60 | # Report base site URL
61 | cat(sprintf('baseurl=%s', pkg$meta$url), file = Sys.getenv("GITHUB_ENV"), append = TRUE)
62 |
63 | - name: Set site deploy subdirectory
64 | run: |
65 | if [[ -d docs/dev ]]; then
66 | srcdir=docs/dev
67 | targetdir=dev
68 | else
69 | srcdir=docs/
70 | targetdir=.
71 | fi
72 | if [[ $GITHUB_REF == refs/tags/v* ]]; then
73 | # If event is a version tag event, set targetdir to ''
74 | targetdir=${GITHUB_REF#refs/tags/}
75 | elif [[ $GITHUB_REF == refs/pull/* ]]; then
76 | # If PR, set targetdir to 'preview/pr'
77 | targetdir=preview/pr${{ github.event.pull_request.number }}
78 | fi
79 | echo "Deploying site from $srcdir to $targetdir on gh-pages"
80 | echo "srcdir=$srcdir" >> $GITHUB_ENV
81 | echo "targetdir=$targetdir" >> $GITHUB_ENV
82 |
83 | - name: Deploy to GitHub pages 🚀
84 | uses: JamesIves/github-pages-deploy-action@4.1.4
85 | with:
86 | clean-exclude: |
87 | preview/
88 | v*/
89 | dev/
90 | branch: gh-pages
91 | folder: ${{ env.srcdir }}
92 | target-folder: ${{ env.targetdir }}
93 |
94 | - name: Notify pkgdown deployment
95 | if: github.event_name == 'pull_request'
96 | uses: hasura/comment-progress@v2.2.0
97 | with:
98 | github-token: ${{ secrets.GITHUB_TOKEN }}
99 | repository: ${{ github.repository }}
100 | number: ${{ github.event.number }}
101 | id: pkgdown-deploy
102 | append: false
103 | message: >
104 | :book: ${{ env.baseurl }}/${{ env.targetdir }}
105 | Preview documentation for this PR (at commit ${{ github.event.pull_request.head.sha }})
106 |
107 |
108 | pkgdown-clean:
109 | if: ${{ github.event_name == 'pull_request' && github.event.action == 'closed' }}
110 | runs-on: ubuntu-latest
111 |
112 | env:
113 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
114 |
115 | steps:
116 | - uses: actions/checkout@v2
117 | with:
118 | ref: "gh-pages"
119 |
120 | - name: Clean up PR Preview
121 | run: |
122 | git config --local user.name "$GITHUB_ACTOR"
123 | git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com"
124 | preview_dir="preview/pr${{ github.event.pull_request.number }}"
125 | if [ -d "$preview_dir" ]; then
126 | git rm -r $preview_dir
127 | git commit -m "Remove $preview_dir (GitHub Actions)" || echo 'No preview to remove'
128 | git push origin || echo 'No preview to remove'
129 | else
130 | echo 'No preview to remove'
131 | fi
132 |
133 | - name: Notify pkgdown cleanup
134 | uses: hasura/comment-progress@v2.2.0
135 | with:
136 | github-token: ${{ secrets.GITHUB_TOKEN }}
137 | repository: ${{ github.repository }}
138 | number: ${{ github.event.number }}
139 | id: pkgdown-deploy
140 | message: |
141 | _:closed_book: Preview documentation for this PR has been cleaned up._
142 |
--------------------------------------------------------------------------------
/R/social.R:
--------------------------------------------------------------------------------
1 |
2 | #' Social Media Metadata
3 | #'
4 | #' Generate metadata tags for social media cards.
5 | #'
6 | #' @template describe-meta
7 | #' @param title Content title
8 | #' @param description Content description. If you have already used
9 | #' [meta_general()] to set the content's description, that description will
10 | #' automatically be used.
11 | #' @param url Content URL
12 | #' @param image Image url for card.
13 | #' @param image_alt A description of what's in the image (not a caption)
14 | #' @param image_width The width of the image in pixels
15 | #' @param image_height The height of the image in pixels
16 | #' @param og_site_name The name of the site hosting the content
17 | #' @param og_type Open Graph card type, default is `"website"`. Other common
18 | #' options include `"article"`, `"book"`, or `"profile"`. The full list of
19 | #' valid options can be referenced at
20 | #' @param og_locale The locale these tags are marked up in. Of the format `language_TERRITORY`. Default is `"en_US"`.
21 | #' @param og_author Writers of the article. Multiple authors may be specified in
22 | #' a vector of character strings.
23 | #' @param twitter_card_type One of `"summary"`, `"summary_large_image"`,
24 | #' `"app"`, or `"player"`.
25 | #' @param twitter_creator `@username` for the content creator / author.
26 | #' @param twitter_site `@username`` for the website used in the card footer.
27 | #' `twitter_creator` is used by default.
28 | #' @param facebook_app_id The Facebook app ID. See the
29 | #' [Facebook Open Graph Markup](https://developers.facebook.com/docs/sharing/webmasters#markup)
30 | #' page for more information.
31 | #' @param disable_pinterest If `TRUE`, adds a metadata tag disabling pins from
32 | #' your website. See the
33 | #' [Pinterest help center](https://help.pinterest.com/en/business/article/prevent-saves-to-pinterest-from-your-site)
34 | #' for more information.
35 | #'
36 | #' @references
37 | #' - [Open Graph](https://ogp.me/)
38 | #' - [Google Structured Data Testing Tool](https://search.google.com/structured-data/testing-tool)
39 | #' - [Facebook Sharing Debugger](https://developers.facebook.com/tools/debug/)
40 | #' - [Twitter Card Documentation](https://developer.twitter.com/en/docs/twitter-for-websites/cards/guides/getting-started)
41 | #'
42 | #' @template describe-meta-return
43 | #' @examples
44 | #' meta() %>%
45 | #' meta_social(
46 | #' title = "R for Data Science",
47 | #' description = "This book with teach you how to do data science with R",
48 | #' url = "https://r4ds.had.co.nz",
49 | #' image = "https://r4ds.had.co.nz/cover.png",
50 | #' image_alt = "The cover of the R4DS book",
51 | #' og_type = "book",
52 | #' og_author = c("Garrett Grolemund", "Hadley Wickham"),
53 | #' twitter_card_type = "summary",
54 | #' twitter_creator = "@hadley"
55 | #' )
56 | #'
57 | #' @export
58 | meta_social <- function(
59 | .meta = meta(),
60 | title = NULL,
61 | url = NULL,
62 | image = NULL,
63 | image_alt = NULL,
64 | image_width = NULL,
65 | image_height = NULL,
66 | description = NULL,
67 | twitter_card_type = c("summary", "summary_large_image", "app", "player"),
68 | twitter_creator = NULL,
69 | twitter_site = twitter_creator,
70 | og_type = "website",
71 | og_locale = "en_US",
72 | og_author = NULL,
73 | og_site_name = NULL,
74 | facebook_app_id = NULL,
75 | disable_pinterest = FALSE
76 | ) {
77 | assert_is_meta(.meta)
78 | twitter_card_type <- match.arg(twitter_card_type)
79 |
80 | description <- description %||% meta_find_description(.meta)
81 |
82 | social <- list(
83 | "twitter:title" = title,
84 | "twitter:description" = description,
85 | "twitter:url" = url,
86 | "twitter:image" = image,
87 | "twitter:image:alt" = image_alt,
88 | "twitter:image:width" = image_width,
89 | "twitter:image:height"= image_height,
90 | "twitter:card" = twitter_card_type,
91 | "twitter:creator" = twitter_creator,
92 | "twitter:site" = twitter_site,
93 | "og:title" = title,
94 | "og:description" = description,
95 | "og:url" = url,
96 | "og:image" = image,
97 | "og:image:alt" = image_alt,
98 | "og:image:width" = image_width,
99 | "og:image:height" = image_height,
100 | "og:type" = og_type,
101 | "og:locale" = og_locale,
102 | "og:site_name" = og_site_name,
103 | "article:author" = og_author %??% as.list(og_author),
104 | "fb:app_id" = facebook_app_id
105 | )
106 |
107 | meta_social <-
108 | social %>%
109 | duplicate_vector_entries() %>%
110 | collapse_single_string() %>%
111 | purrr::imap(function(content, property) {
112 | if (grepl("^twitter:", property)) {
113 | tag_meta(name = property, content = content)
114 | } else {
115 | tag_meta(property = property, content = content)
116 | }
117 | }) %>%
118 | unname()
119 |
120 | if (disable_pinterest) {
121 | meta_social <- c(
122 | meta_social,
123 | list(tag_meta(
124 | name = "pinterest",
125 | content = "nopin",
126 | description = "Sorry, pins from this website are disabled."
127 | ))
128 | )
129 | }
130 |
131 | append_to_meta(.meta, meta_social)
132 | }
133 |
--------------------------------------------------------------------------------
/man/meta_google_scholar.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/google_scholar.R
3 | \name{meta_google_scholar}
4 | \alias{meta_google_scholar}
5 | \title{Add Google Scholar Metadata}
6 | \usage{
7 | meta_google_scholar(
8 | .meta = meta(),
9 | title,
10 | author,
11 | publication_date,
12 | online_date = NULL,
13 | journal_title = NULL,
14 | conference_title = NULL,
15 | volume = NULL,
16 | issue = NULL,
17 | firstpage = NULL,
18 | lastpage = NULL,
19 | pdf_url = NULL,
20 | issn = NULL,
21 | isbn = NULL,
22 | dissertation_institution = NULL,
23 | technical_report_institution = NULL,
24 | technical_report_number = NULL
25 | )
26 | }
27 | \arguments{
28 | \item{.meta}{A \code{meta} object created by \code{\link[=meta]{meta()}} or \code{\link[=as_meta]{as_meta()}}, or returned
29 | by a \verb{meta_*()} object.}
30 |
31 | \item{title}{The title of the paper.
32 |
33 | The title tag must contain the title of the paper. Don't use it for the
34 | title of the journal or a book in which the paper was published, or for the
35 | name of your repository. This tag is required for inclusion in Google
36 | Scholar.}
37 |
38 | \item{author}{A vector of author names.
39 |
40 | The \code{author} tag, must contain the authors (and only the actual authors) of
41 | the paper. Don't use it for the author of the website or for contributors
42 | other than authors, e.g., thesis advisors. Author names can be listed
43 | either as "Smith, John" or as "John Smith". Put each author name in a
44 | separate tag and omit all affiliations, degrees, certifications, etc., from
45 | this field. At least one author tag is required for inclusion in Google
46 | Scholar.}
47 |
48 | \item{publication_date, online_date}{The date the paper was published in the
49 | journal (\code{publication_date}) or published online (\code{online_date}).
50 |
51 | The \code{publication_date} tag must contain the date of publication, i.e., the
52 | date that would normally be cited in references to this paper from other
53 | papers. Don't use it for the date of entry into the repository - that
54 | should go into \code{online_date} instead. Provide full dates in the "2010/5/12"
55 | format if available; or a year alone otherwise. This tag is required for
56 | inclusion in Google Scholar.}
57 |
58 | \item{journal_title, conference_title, issn, isbn, volume, issue, firstpage, lastpage}{For journal and conference papers, provide the remaining bibliographic
59 | citation data in the following tags: \code{journal_title} or \code{conference_title},
60 | \code{issn}, \code{isbn}, \code{volume}, \code{issue}, \code{firstpage}, and \code{lastpage.} These
61 | fields must contain sufficient information to identify a reference to this
62 | paper from another document, which is normally all of: (a) journal or
63 | conference name, (b) volume and issue numbers, if applicable, and (c) the
64 | number of the first page of the paper in the volume (or issue) in question.}
65 |
66 | \item{pdf_url}{The \verb{} tags normally apply only to the exact page on
67 | which they're provided. If this page shows only the abstract of the paper
68 | and you have the full text in a separate file, e.g., in the PDF format,
69 | please specify the locations of all full text versions using \code{pdf_url}. The
70 | content of the tag is the absolute URL of the PDF file; for security
71 | reasons, it must refer to a file in the same subdirectory as the HTML
72 | abstract.}
73 |
74 | \item{dissertation_institution, technical_report_institution, technical_report_number}{For theses, dissertations, and technical reports, provide the remaining
75 | bibliographic citation data in the following tags:
76 | \code{dissertation_institution}, \code{technical_report_institution} for the name of
77 | the institution and \code{technical_report_number} for the number of the
78 | technical report. As with journal and conference papers, you need to
79 | provide sufficient information to recognize a formal citation to this
80 | document from another article.}
81 | }
82 | \value{
83 | A \code{meta} object, or a set of \verb{} HTML tags inside an HTML
84 | \verb{} tag. For use in \code{\link[rmarkdown:html_document]{rmarkdown::html_document()}}, \code{\link[shiny:runApp]{shiny::runApp()}},
85 | or other HTML locations.
86 | }
87 | \description{
88 | Add bibliographic metadata to pages in the format expected by Google
89 | Scholar. Please reference the
90 | \href{https://scholar.google.com/intl/en/scholar/inclusion.html#indexing}{Google Scholar Inclusion}
91 | page for the most up-to-date information and instructions. Note that this
92 | function adds the \code{citation_} prefix to all of its arguments; the \code{title}
93 | argument becomes the \code{citation_title} \verb{} tag.
94 | }
95 | \examples{
96 | meta_google_scholar(
97 | title = c(
98 | "The testis isoform of the phosphorylase kinase catalytic subunit (PhK-T)",
99 | "plays a critical role in regulation of glycogen mobilization in developing lung"
100 | ),
101 | author = c(
102 | "Liu, Li",
103 | "Rannels, Stephen R.",
104 | "Falconieri, Mary",
105 | "Phillips, Karen S.",
106 | "Wolpert, Ellen B.",
107 | "Weaver, Timothy E."
108 | ),
109 | publication_date = "1996/05/17",
110 | journal_title = "Journal of Biological Chemistry",
111 | volume = 271,
112 | issue = 20,
113 | firstpage = 11761,
114 | lastpage = 11766,
115 | pdf_url = "http://www.example.com/content/271/20/11761.full.pdf"
116 | )
117 |
118 | }
119 | \references{
120 | \url{https://scholar.google.com/intl/en/scholar/inclusion.html#indexing}
121 | }
122 | \seealso{
123 | Other meta:
124 | \code{\link{meta_apple_itunes_app}()},
125 | \code{\link{meta_apple_web_app}()},
126 | \code{\link{meta_general}()},
127 | \code{\link{meta_geo}()},
128 | \code{\link{meta_name}()},
129 | \code{\link{meta_social}()},
130 | \code{\link{meta_tag}()},
131 | \code{\link{meta_viewport}()},
132 | \code{\link{meta}()}
133 | }
134 | \concept{meta}
135 |
--------------------------------------------------------------------------------
/R/google_scholar.R:
--------------------------------------------------------------------------------
1 | #' Add Google Scholar Metadata
2 | #'
3 | #' Add bibliographic metadata to pages in the format expected by Google
4 | #' Scholar. Please reference the
5 | #' [Google Scholar Inclusion](https://scholar.google.com/intl/en/scholar/inclusion.html#indexing)
6 | #' page for the most up-to-date information and instructions. Note that this
7 | #' function adds the `citation_` prefix to all of its arguments; the `title`
8 | #' argument becomes the `citation_title` `` tag.
9 | #'
10 | #' @examples
11 | #' meta_google_scholar(
12 | #' title = c(
13 | #' "The testis isoform of the phosphorylase kinase catalytic subunit (PhK-T)",
14 | #' "plays a critical role in regulation of glycogen mobilization in developing lung"
15 | #' ),
16 | #' author = c(
17 | #' "Liu, Li",
18 | #' "Rannels, Stephen R.",
19 | #' "Falconieri, Mary",
20 | #' "Phillips, Karen S.",
21 | #' "Wolpert, Ellen B.",
22 | #' "Weaver, Timothy E."
23 | #' ),
24 | #' publication_date = "1996/05/17",
25 | #' journal_title = "Journal of Biological Chemistry",
26 | #' volume = 271,
27 | #' issue = 20,
28 | #' firstpage = 11761,
29 | #' lastpage = 11766,
30 | #' pdf_url = "http://www.example.com/content/271/20/11761.full.pdf"
31 | #' )
32 | #'
33 | #' @template describe-meta
34 | #' @param title The title of the paper.
35 | #'
36 | #' The title tag must contain the title of the paper. Don't use it for the
37 | #' title of the journal or a book in which the paper was published, or for the
38 | #' name of your repository. This tag is required for inclusion in Google
39 | #' Scholar.
40 | #' @param author A vector of author names.
41 | #'
42 | #' The `author` tag, must contain the authors (and only the actual authors) of
43 | #' the paper. Don't use it for the author of the website or for contributors
44 | #' other than authors, e.g., thesis advisors. Author names can be listed
45 | #' either as "Smith, John" or as "John Smith". Put each author name in a
46 | #' separate tag and omit all affiliations, degrees, certifications, etc., from
47 | #' this field. At least one author tag is required for inclusion in Google
48 | #' Scholar.
49 | #' @param publication_date,online_date The date the paper was published in the
50 | #' journal (`publication_date`) or published online (`online_date`).
51 | #'
52 | #' The `publication_date` tag must contain the date of publication, i.e., the
53 | #' date that would normally be cited in references to this paper from other
54 | #' papers. Don't use it for the date of entry into the repository - that
55 | #' should go into `online_date` instead. Provide full dates in the "2010/5/12"
56 | #' format if available; or a year alone otherwise. This tag is required for
57 | #' inclusion in Google Scholar.
58 | #'
59 | #' @param journal_title,conference_title,issn,isbn,volume,issue,firstpage,lastpage
60 | #' For journal and conference papers, provide the remaining bibliographic
61 | #' citation data in the following tags: `journal_title` or `conference_title`,
62 | #' `issn`, `isbn`, `volume`, `issue`, `firstpage`, and `lastpage.` These
63 | #' fields must contain sufficient information to identify a reference to this
64 | #' paper from another document, which is normally all of: (a) journal or
65 | #' conference name, (b) volume and issue numbers, if applicable, and (c) the
66 | #' number of the first page of the paper in the volume (or issue) in question.
67 | #'
68 | #' @param dissertation_institution,technical_report_institution,technical_report_number
69 | #' For theses, dissertations, and technical reports, provide the remaining
70 | #' bibliographic citation data in the following tags:
71 | #' `dissertation_institution`, `technical_report_institution` for the name of
72 | #' the institution and `technical_report_number` for the number of the
73 | #' technical report. As with journal and conference papers, you need to
74 | #' provide sufficient information to recognize a formal citation to this
75 | #' document from another article.
76 | #'
77 | #' @param pdf_url The `` tags normally apply only to the exact page on
78 | #' which they're provided. If this page shows only the abstract of the paper
79 | #' and you have the full text in a separate file, e.g., in the PDF format,
80 | #' please specify the locations of all full text versions using `pdf_url`. The
81 | #' content of the tag is the absolute URL of the PDF file; for security
82 | #' reasons, it must refer to a file in the same subdirectory as the HTML
83 | #' abstract.
84 | #'
85 | #' @template describe-meta-return
86 | #'
87 | #' @references
88 | #' @export
89 | meta_google_scholar <- function(
90 | .meta = meta(),
91 | title,
92 | author,
93 | publication_date,
94 | online_date = NULL,
95 | journal_title = NULL,
96 | conference_title = NULL,
97 | volume = NULL,
98 | issue = NULL,
99 | firstpage = NULL,
100 | lastpage = NULL,
101 | pdf_url = NULL,
102 | issn = NULL,
103 | isbn = NULL,
104 | dissertation_institution = NULL,
105 | technical_report_institution = NULL,
106 | technical_report_number = NULL
107 | ) {
108 | assert_is_meta(.meta)
109 |
110 | assert_valid_google_scholar_date(publication_date)
111 | assert_valid_google_scholar_date(online_date)
112 |
113 | scholar <- list(
114 | title = title,
115 | publication_date = publication_date,
116 | online_date = online_date,
117 | journal_title = journal_title,
118 | conference_title = conference_title,
119 | volume = volume,
120 | issue = issue,
121 | firstpage = firstpage,
122 | lastpage = lastpage,
123 | pdf_url = pdf_url,
124 | issn = issn,
125 | isbn = isbn,
126 | dissertation_institution = dissertation_institution,
127 | technical_report_institution = technical_report_institution,
128 | technical_report_number = technical_report_number
129 | )
130 | names(scholar) <- paste0("citation_", names(scholar))
131 |
132 | for (aut in rev(author)) {
133 | scholar <- purrr::prepend(scholar, list(citation_author = aut))
134 | }
135 | idx_title <- which(names(scholar) == "citation_title")
136 | scholar <- c(scholar[idx_title], scholar[-idx_title])
137 |
138 | meta_scholar <-
139 | scholar %>%
140 | purrr::compact() %>%
141 | collapse_single_string() %>%
142 | purrr::imap(~ tag_meta(name = .y, content = .x)) %>%
143 | unname()
144 |
145 | append_to_meta(.meta, meta_scholar)
146 | }
147 |
148 | assert_valid_google_scholar_date <- function(x) {
149 | if (is.null(x)) return()
150 | x_name <- deparse(substitute(x))
151 | x <- as.character(x)
152 |
153 | if (length(x) > 1) {
154 | stop("`", x_name, "` must be a single value.", call. = FALSE)
155 | }
156 |
157 | valid_date_fmt <- "^\\d{4}(/\\d{1,2}/\\d{1,2})?$"
158 |
159 | if (!grepl(valid_date_fmt, x)) {
160 | stop("`", x_name, "` must be in YYYY or YYYY/MM/DD format.", call. = FALSE)
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/R/meta.R:
--------------------------------------------------------------------------------
1 | #' Initialize a List of HTML Metadata Tags
2 | #'
3 | #' Initialize a _metathis_ object (i.e. a list of HTML metadata tags), test if
4 | #' an object is a _metathis_ object, or coerce a list of `meta` tags to be a
5 | #' _metathis_ object.
6 | #'
7 | #' @template describe-meta-return
8 | #'
9 | #' @export
10 | meta <- function() {
11 | as_meta(list())
12 | }
13 |
14 | #' Include Metadata Tags in HTML Document
15 | #'
16 | #' Use `include_meta()` to explicitly declare the [meta()] tags as an HTML
17 | #' dependency. In general, this is not required when knitting to an HTML
18 | #' document. This function explicitly attaches an [htmltools::htmlDependency()]
19 | #' and may work in some unusual cases.
20 | #'
21 | #' @template describe-meta
22 | #' @return An [htmltools::htmlDependency()] containing the metadata tags to be
23 | #' included in the `` of the HTML document.
24 | #'
25 | #' @family meta_actions
26 | #'
27 | #' @examples
28 | #' meta() %>%
29 | #' meta_name("github-repo" = "gadenbuie/metathis") %>%
30 | #' include_meta()
31 | #'
32 | #' @export
33 | include_meta <- function(.meta) {
34 | assert_is_meta(.meta)
35 |
36 | htmltools::tagList(metaDependency(.meta))
37 | }
38 |
39 |
40 | #' Create name/content metadata tag pairs
41 | #'
42 | #' Creates metadata tag pairs where the arguments are the name values and their
43 | #' values are content values.
44 | #'
45 | #' @template describe-meta
46 | #' @param ... Name (argument names) and content (argument value) pairs.
47 | #' @examples
48 | #' meta() %>%
49 | #' meta_name("github-repo" = "hadley/r4ds")
50 | #'
51 | #' @template describe-meta-return
52 | #' @export
53 | meta_name <- function(.meta = meta(), ...) {
54 | assert_is_meta(.meta)
55 |
56 | name_meta <- list(...) %>%
57 | collapse_single_string() %>%
58 | tag_meta_list()
59 |
60 | append_to_meta(.meta, name_meta)
61 | }
62 |
63 | #' Create a metadata tag for attribute/value pairs
64 | #'
65 | #' Creates a `` tag for attribute value pairs, where argument names
66 | #' correspond to attribute names.
67 | #'
68 | #' @template describe-meta
69 | #' @param ... Attribute names and values as `attribute = value`. Values must be
70 | #' a single character string.
71 | #' @examples
72 | #' meta() %>%
73 | #' meta_tag(
74 | #' "http-equiv" = "Content-Security-Policy",
75 | #' content = "default-src 'self'"
76 | #' )
77 | #'
78 | #' @template describe-meta-return
79 | #' @export
80 | meta_tag <- function(.meta = meta(), ...) {
81 | assert_is_meta(.meta)
82 | attrs <- list(...)
83 |
84 | len_gt_1 <- purrr::keep(attrs, ~ length(.) > 1)
85 | if (length(len_gt_1)) {
86 | stop(
87 | "All values must be length 1: '",
88 | paste0(names(len_gt_1), collapse = "', '"),
89 | "'"
90 | )
91 | }
92 |
93 | append_to_meta(.meta, list(tag_meta(...)))
94 | }
95 |
96 | #' @describeIn meta Test if an objects is a _metathis_ object
97 | #' @examples
98 | #' meta() %>%
99 | #' meta_viewport() %>%
100 | #' is_meta()
101 | #'
102 | #' @export
103 | is_meta <- function(x) {
104 | inherits(x, "meta")
105 | }
106 |
107 | assert_is_meta <- function(x, var = ".meta") {
108 | if (!is_meta(x)) {
109 | stop("`", var, "` must be a meta object from meta() or as_meta()")
110 | } else {
111 | invisible(TRUE)
112 | }
113 | }
114 |
115 | #' @describeIn meta Convert a list of meta tags into a _metathis_ object.
116 | #'
117 | #' @param x A list or metathis object
118 | #'
119 | #' @examples
120 | #' list_of_meta_tags <- list(
121 | #' htmltools::tags$meta(github = "gadenbuie"),
122 | #' htmltools::tags$meta(twitter = "grrrck")
123 | #' )
124 | #'
125 | #' as_meta(list_of_meta_tags)
126 | #' @export
127 | as_meta <- function(x) UseMethod("as_meta", x)
128 |
129 | #' @export
130 | as_meta.list <- function(x) {
131 | head <- htmltools::tags$head()
132 | head$children <- x
133 | structure(list(head), class = c("meta", "shiny.tag.list", "list"))
134 | }
135 |
136 | #' @export
137 | as_meta.default <- function(x) {
138 | x_class <- paste(class(x), collapse = ", ")
139 | stop(
140 | "I don't know how to convert an object of class '",
141 | x_class,
142 | "' into a list of tags"
143 | )
144 | }
145 |
146 | #' @export
147 | as_meta.data.frame <- function(x) {
148 | NextMethod()
149 | }
150 |
151 | #' @export
152 | as.character.meta <- function(x, ...) {
153 | x[[1]]$children %>% purrr::map_chr(as.character)
154 | }
155 |
156 | #' @export
157 | format.meta <- function(x, ...) {
158 | collapse(as.character(x), "\n")
159 | }
160 |
161 | #' @export
162 | print.meta <- function(x, ...) {
163 | cat(format(x))
164 | }
165 |
166 | #' @export
167 | knit_print.meta <- function(x, ...) {
168 | .meta <- x
169 | assert_is_meta(.meta)
170 |
171 | # nocov start
172 | if (!grepl("html", knitr::opts_knit$get("rmarkdown.pandoc.to"))) {
173 | warning(
174 | "knitr output format is not HTML. Use `include_meta()` to ensure ",
175 | "that the tags are properly included in the output ",
176 | "(if possible).",
177 | call. = FALSE
178 | )
179 | }
180 |
181 | if (guess_blogdown()) {
182 | warning(
183 | "{metathis} can't directly include tags inside blogdown posts ",
184 | "because the mechanism for including tags in the section of a ",
185 | "page depends on the Hugo template. ",
186 | "If you see this message but are not rendering a blogdown post, you can ",
187 | "use metathis::include_meta() to avoid this check. ",
188 | "See ?meta for more information.",
189 | call. = FALSE
190 | )
191 | return(collapse(.meta, "\n"))
192 | }
193 | #nocov end
194 |
195 | # Thank you: https://github.com/haozhu233/kableExtra/blob/master/R/print.R#L56
196 | knitr::asis_output("", meta = list(metaDependency(.meta)))
197 | }
198 |
199 | append_to_meta <- function(.meta, .list = NULL) {
200 | assert_is_meta(.meta)
201 | .meta[[1]]$children <- append(.meta[[1]]$children, .list)
202 | .meta
203 | }
204 |
205 | prepend_to_meta <- function(.meta, .list = NULL) {
206 | assert_is_meta(.meta)
207 | .meta[[1]]$children <- purrr::prepend(.meta[[1]]$children, .list)
208 | .meta
209 | }
210 |
211 | metaDependency <- function(.meta) {
212 | assert_is_meta(.meta)
213 |
214 | src <- if (has_package_version("rmarkdown", "2.9")) {
215 | c(href = "/")
216 | } else {
217 | system.file(package = "metathis")
218 | }
219 |
220 | htmltools::htmlDependency(
221 | paste0("metathis", "-", random_id()),
222 | version = METATHIS_VERSION,
223 | src = src,
224 | all_files = FALSE,
225 | head = .meta %>% paste()
226 | )
227 | }
228 |
229 | random_id <- function(n = 6) {
230 | c(letters[1:6], 0:9) %>%
231 | sample(8, replace = TRUE) %>%
232 | collapse("")
233 | }
234 |
235 | guess_blogdown <- function() {
236 | blogdown_root <- find_config(getwd())
237 | if (is.null(blogdown_root)) return(FALSE)
238 |
239 | # Check for blogdown config files and confirm if they contain "baseURL"
240 | config_files <- dir(blogdown_root, "config[.](yaml|toml|json)", full.names = TRUE)
241 | if (length(config_files)) {
242 | for (config in config_files) {
243 | if (grepl("baseURL", collapse(readLines(config, warn = FALSE)))) {
244 | return(TRUE)
245 | }
246 | }
247 | }
248 |
249 | # Check if config file + "content" + "layouts" + "static"
250 | blogdown_files <- dir(blogdown_root, "content|layouts|static")
251 | if (length(blogdown_files) == 3 && length(config_files)) {
252 | return(TRUE)
253 | }
254 |
255 | FALSE
256 | }
257 |
258 | find_config <- function(path) {
259 | if (length(dir(path, "config[.](yaml|toml|json)"))) {
260 | return(path)
261 | }
262 |
263 | path_up <- normalizePath(file.path(path, ".."))
264 | if (path == path_up) return(NULL)
265 | find_config(path_up)
266 | }
267 |
268 | meta_find_description <- function(.meta) {
269 | # check existing metadata for description
270 | has_description <- has_meta_with_property(.meta, value = "description")
271 | if (!any(has_description)) {
272 | return(NULL)
273 | }
274 |
275 | desc_existing <- .meta[[1]]$children %>%
276 | purrr::keep(has_description) %>%
277 | purrr::map_chr(~ .$attribs$content) %>%
278 | unique()
279 |
280 | if (length(desc_existing) > 1) {
281 | warning(
282 | "Multiple existing descriptions were found, using first for ",
283 | "social cards:\n",
284 | strwrap(desc_existing[1], indent = 4)
285 | )
286 | }
287 | desc_existing[1]
288 | }
289 |
--------------------------------------------------------------------------------
/README.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | output: github_document
3 | always_allow_html: yes
4 | ---
5 |
6 |
7 |
8 | ```{r, include = FALSE}
9 | knitr::opts_chunk$set(
10 | collapse = TRUE,
11 | comment = "#>",
12 | fig.path = "man/figures/README-",
13 | out.width = "100%"
14 | )
15 | ```
16 |
17 | # metathis
18 |
19 |
20 | [](https://CRAN.R-project.org/package=metathis)
21 | [](https://gadenbuie.r-universe.dev/metathis)
22 | [](https://lifecycle.r-lib.org/articles/stages.html)
23 | [](https://github.com/gadenbuie/metathis/actions/workflows/R-CMD-check.yaml)
24 | [](https://app.codecov.io/github/gadenbuie/metathis)
25 |
26 |
27 | [rmarkdown]: https://rmarkdown.rstudio.com
28 | [blogdown]: https://bookdown.org/yihui/blogdown
29 | [Shiny]: https://shiny.posit.co/
30 | [r4ds]: https://r4ds.had.co.nz/
31 | [xaringan]: https://slides.yihui.org/xaringan
32 | [bookdown]: https://bookdown.org/
33 | [pagedown]: https://github.com/rstudio/pagedown
34 | [htmltools]: https://github.com/rstudio/htmltools
35 | [pkgdown]: https://pkgdown.r-lib.org
36 |
37 | ## Why metathis?
38 |
39 | The goal of **metathis** is to help you add HTML `` tags to your [R Markdown][rmarkdown] and [Shiny] apps.
40 |
41 | HTML `` tags provide browsers and social media with metadata about HTML pages.
42 | Using `` tags will help your users find your articles, Shiny apps, and presentations, and will help you make sure they look great in social media timelines.
43 |
44 | **metathis** makes the process of adding these tags to your R Markdown pages and Shiny apps easier by using the [htmltools] package to add `` tags as a dependency, added directly to the document in an R code chunk or your Shiny app UI rather than requiring you to adjust templates or write additional files.
45 |
46 | If you want great looking social media cards, the [`meta_social()`](http://pkg.garrickadenbuie.com/metathis/reference/meta_social.html) function will help you add everything you need for Twitter, Facebook and other social media sites that support the Open Graph protocol.
47 |
48 | ## Installation
49 |
50 | You can install the latest version of metathis from [CRAN](https://CRAN.R-project.org) with:
51 |
52 | ``` r
53 | # CRAN
54 | install.packages("metathis")
55 | ```
56 |
57 | And the development version from [Github](https://github.com/gadenbuie/metathis) or [r-universe](https://gadenbuie.r-universe.dev/builds) with:
58 |
59 | ``` r
60 | # r-universe
61 | install.packages("metathis", repos = "https://gadenbuie.r-universe.dev")
62 |
63 | # install.packages("devtools")
64 | devtools::install_github("gadenbuie/metathis@main")
65 | ```
66 |
67 | ## Works In
68 |
69 | ✅ [R Markdown][rmarkdown] HTML Documents
70 | ✅ [Shiny] Apps
71 | ✅ [xaringan]
72 | ✅ [pagedown]
73 | ✅ [bookdown]
74 | ❌ [blogdown]1
75 | ❌ [pkgdown]
76 |
77 | `` tags can be added to ✅ packages with a standard R chunk
78 |
79 | ````markdown
80 | ```{r, echo=FALSE}`r ''`
81 | meta() %>%
82 | meta_description("My awesome presentation")
83 | ```
84 | ````
85 |
86 | For other packages or situations, you can use `include_meta()` to explicitly declare the meta tags as an html dependency or use `write_meta()` to save the `` tags to an `.html` file that can be included via `includes: in_header`.
87 | (In blogdown, consult your blogdown/hugo theme for the correct inclusion method.)
88 |
89 | ````markdown
90 | ```{r blogdown-meta, echo = FALSE}`r ''`
91 | meta() %>%
92 | meta_description("A fantastic blog post") %>%
93 | write_meta("meta.html")
94 | ```
95 | ````
96 |
97 | ## Example
98 |
99 | ### In R Markdown
100 |
101 | This is a basic example that re-creates the `` tags for the [R for Data Science][r4ds] book.
102 |
103 | ```{r library}
104 | library(metathis)
105 | ```
106 |
107 | ```{r example, eval=FALSE}
108 | meta() %>%
109 | meta_description(
110 | "This book will teach you how to do data science with R..."
111 | ) %>%
112 | meta_name("github-repo" = "hadley/r4ds") %>%
113 | meta_viewport() %>%
114 | meta_social(
115 | title = "R for Data Science",
116 | url = "https://r4ds.had.co.nz",
117 | image = "https://r4ds.had.co.nz/cover.png",
118 | image_alt = "The cover of the R4DS book",
119 | og_type = "book",
120 | og_author = c("Garrett Grolemund", "Hadley Wickham"),
121 | twitter_card_type = "summary",
122 | twitter_creator = "@hadley"
123 | )
124 | ```
125 |
126 | ```{r example-print, echo=FALSE}
127 | x <-
128 | <>
129 |
130 | print(x)
131 | ```
132 |
133 | ### In Shiny Apps
134 |
135 | To use `metathis` in Shiny apps,
136 | simply call `meta()` and related tags anywhere inside your page UI,
137 | for example inside `fluidPage()`.
138 |
139 | ```r
140 | ui <- fluidPage(
141 | # Application title
142 | titlePanel("metathis Example"),
143 |
144 | meta() %>%
145 | meta_social(
146 | title = "metathis",
147 | description = " and social media cards for web things in R",
148 | url = "https://pkg.garrickadenbuie.com/metathis",
149 | image = "https://garrickadenbuie.com/apple-touch-icon-114x114.png",
150 | image_alt = "An image for social meda cards",
151 | twitter_creator = "@grrrck",
152 | twitter_card_type = "summary",
153 | twitter_site = "@grrrck"
154 | )
155 | # ... your UI ...
156 | )
157 | ```
158 |
159 | ### In xaringan Slides
160 |
161 | To use `metathis` in [xaringan] slides,
162 | add `meta()` and related tags in a chunk anywhere in your slide's source `.Rmd` file.
163 | This example is from a [presentation on the drake package](https://pkg.garrickadenbuie.com/drake-intro/).
164 |
165 | ````markdown
166 | ```{r meta, echo=FALSE}`r ''`
167 | library(metathis)
168 | meta() %>%
169 | meta_general(
170 | description = "A gentle introduction to reproducible data workflows with the {drake} package.",
171 | generator = "xaringan and remark.js"
172 | ) %>%
173 | meta_name("github-repo" = "gadenbuie/drake-intro") %>%
174 | meta_social(
175 | title = "Reproducible Data Workflows With Drake",
176 | url = "https://pkg.garrickadenbuie.com/drake-intro",
177 | image = "https://pkg.garrickadenbuie.com/drake-intro/assets/images/drake-intro-cover.jpg",
178 | image_alt = "The first slide of the Reproducible Data Workflows with drake presentation, featuring the drake hex logo and neatly ordered row of items on a desk (eraser, pencil, coffee cup, paperclips).",
179 | og_type = "website",
180 | og_author = "Garrick Aden-Buie",
181 | twitter_card_type = "summary_large_image",
182 | twitter_creator = "@grrrck"
183 | )
184 | ```
185 | ````
186 |
187 |
188 | ## Thanks
189 |
190 | Thanks to [Josh Buchea](https://github.com/joshbuchea) for providing an [excellent and indispensable resource](https://github.com/joshbuchea/HEAD) on `` tags and other things that go in the HTML `` tags.
191 |
192 | Thanks also to [Malcolm Barret](https://github.com/malcolmbarrett).
193 | Watching over his shoulder as he developed [ymlthis](https://ymlthis.r-lib.org) made putting this package together so much easier.
194 |
195 | Finally, thanks to the [RStudio team](https://github.com/rstudio) and others who developed [htmltools](https://github.com/rstudio/htmltools) for making HTML in R a breeze.
196 |
197 | ```{r, echo=FALSE, warning=FALSE}
198 | meta() %>%
199 | meta_description(
200 | " and social media cards for web things inR"
201 | ) %>%
202 | meta_name("github-repo" = "gadenbuie/metathis") %>%
203 | meta_social(
204 | title = "{metathis}",
205 | url = "https://pkg.garrickadenbuie.com/metathis",
206 | image = "https://pkg.garrickadenbuie.com/metathis/reference/figures/card.png",
207 | image_alt = "many tags and the name of the R package: ",
208 | og_author = c("Garrick Aden-Buie"),
209 | twitter_card_type = "summary",
210 | twitter_creator = "@grrrck"
211 | ) %>%
212 | include_meta()
213 | ```
214 |
215 | ---
216 |
217 | ### Notes
218 |
219 | 1. For adding meta tags to blogdown sites, [Socialize your blogdown by Xavier A](https://xvrdm.github.io/2017/10/23/socialize-your-blogdown/) is an excellent resource and you can use metathis to help discover the tags you need while following the instructions in the article.
220 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # metathis
5 |
6 |
7 |
8 | [](https://CRAN.R-project.org/package=metathis)
10 | [](https://gadenbuie.r-universe.dev/metathis)
12 | [](https://lifecycle.r-lib.org/articles/stages.html)
14 | [](https://github.com/gadenbuie/metathis/actions/workflows/R-CMD-check.yaml)
15 | [](https://app.codecov.io/github/gadenbuie/metathis)
16 |
17 |
18 | ## Why metathis?
19 |
20 | The goal of **metathis** is to help you add HTML `` tags to your
21 | [R Markdown](https://rmarkdown.rstudio.com) and
22 | [Shiny](https://shiny.posit.co/) apps.
23 |
24 | HTML `` tags provide browsers and social media with metadata about
25 | HTML pages. Using `` tags will help your users find your articles,
26 | Shiny apps, and presentations, and will help you make sure they look
27 | great in social media timelines.
28 |
29 | **metathis** makes the process of adding these tags to your R Markdown
30 | pages and Shiny apps easier by using the
31 | [htmltools](https://github.com/rstudio/htmltools) package to add
32 | `` tags as a dependency, added directly to the document in an R
33 | code chunk or your Shiny app UI rather than requiring you to adjust
34 | templates or write additional files.
35 |
36 | If you want great looking social media cards, the
37 | [`meta_social()`](http://pkg.garrickadenbuie.com/metathis/reference/meta_social.html)
38 | function will help you add everything you need for Twitter, Facebook and
39 | other social media sites that support the Open Graph protocol.
40 |
41 | ## Installation
42 |
43 | You can install the latest version of metathis from
44 | [CRAN](https://CRAN.R-project.org) with:
45 |
46 | ``` r
47 | # CRAN
48 | install.packages("metathis")
49 | ```
50 |
51 | And the development version from
52 | [Github](https://github.com/gadenbuie/metathis) or
53 | [r-universe](https://gadenbuie.r-universe.dev/builds) with:
54 |
55 | ``` r
56 | # r-universe
57 | install.packages("metathis", repos = "https://gadenbuie.r-universe.dev")
58 |
59 | # install.packages("devtools")
60 | devtools::install_github("gadenbuie/metathis@main")
61 | ```
62 |
63 | ## Works In
64 |
65 | ✅ [R Markdown](https://rmarkdown.rstudio.com) HTML Documents
66 | ✅ [Shiny](https://shiny.posit.co/) Apps
67 | ✅ [xaringan](https://slides.yihui.org/xaringan)
68 | ✅ [pagedown](https://github.com/rstudio/pagedown)
69 | ✅ [bookdown](https://bookdown.org/)
70 | ❌ [blogdown](https://bookdown.org/yihui/blogdown)1
71 | ❌ [pkgdown](https://pkgdown.r-lib.org)
72 |
73 | `` tags can be added to ✅ packages with a standard R chunk
74 |
75 | ```` markdown
76 | ```{r, echo=FALSE}
77 | meta() %>%
78 | meta_description("My awesome presentation")
79 | ```
80 | ````
81 |
82 | For other packages or situations, you can use `include_meta()` to
83 | explicitly declare the meta tags as an html dependency or use
84 | `write_meta()` to save the `` tags to an `.html` file that can be
85 | included via `includes: in_header`. (In blogdown, consult your
86 | blogdown/hugo theme for the correct inclusion method.)
87 |
88 | ```` markdown
89 | ```{r blogdown-meta, echo = FALSE}
90 | meta() %>%
91 | meta_description("A fantastic blog post") %>%
92 | write_meta("meta.html")
93 | ```
94 | ````
95 |
96 | ## Example
97 |
98 | ### In R Markdown
99 |
100 | This is a basic example that re-creates the `` tags for the [R for
101 | Data Science](https://r4ds.had.co.nz/) book.
102 |
103 | ``` r
104 | library(metathis)
105 | ```
106 |
107 | ``` r
108 | meta() %>%
109 | meta_description(
110 | "This book will teach you how to do data science with R..."
111 | ) %>%
112 | meta_name("github-repo" = "hadley/r4ds") %>%
113 | meta_viewport() %>%
114 | meta_social(
115 | title = "R for Data Science",
116 | url = "https://r4ds.had.co.nz",
117 | image = "https://r4ds.had.co.nz/cover.png",
118 | image_alt = "The cover of the R4DS book",
119 | og_type = "book",
120 | og_author = c("Garrett Grolemund", "Hadley Wickham"),
121 | twitter_card_type = "summary",
122 | twitter_creator = "@hadley"
123 | )
124 | ```
125 |
126 | #>
127 | #>
128 | #>
129 | #>
130 | #>
131 | #>
132 | #>
133 | #>
134 | #>
135 | #>
136 | #>
137 | #>
138 | #>
139 | #>
140 | #>
141 | #>
142 | #>
143 | #>
144 | #>
145 | #>
146 |
147 | ### In Shiny Apps
148 |
149 | To use `metathis` in Shiny apps, simply call `meta()` and related tags
150 | anywhere inside your page UI, for example inside `fluidPage()`.
151 |
152 | ``` r
153 | ui <- fluidPage(
154 | # Application title
155 | titlePanel("metathis Example"),
156 |
157 | meta() %>%
158 | meta_social(
159 | title = "metathis",
160 | description = " and social media cards for web things in R",
161 | url = "https://pkg.garrickadenbuie.com/metathis",
162 | image = "https://garrickadenbuie.com/apple-touch-icon-114x114.png",
163 | image_alt = "An image for social meda cards",
164 | twitter_creator = "@grrrck",
165 | twitter_card_type = "summary",
166 | twitter_site = "@grrrck"
167 | )
168 | # ... your UI ...
169 | )
170 | ```
171 |
172 | ### In xaringan Slides
173 |
174 | To use `metathis` in [xaringan](https://slides.yihui.org/xaringan)
175 | slides, add `meta()` and related tags in a chunk anywhere in your
176 | slide’s source `.Rmd` file. This example is from a [presentation on the
177 | drake package](https://pkg.garrickadenbuie.com/drake-intro/).
178 |
179 | ```` markdown
180 | ```{r meta, echo=FALSE}
181 | library(metathis)
182 | meta() %>%
183 | meta_general(
184 | description = "A gentle introduction to reproducible data workflows with the {drake} package.",
185 | generator = "xaringan and remark.js"
186 | ) %>%
187 | meta_name("github-repo" = "gadenbuie/drake-intro") %>%
188 | meta_social(
189 | title = "Reproducible Data Workflows With Drake",
190 | url = "https://pkg.garrickadenbuie.com/drake-intro",
191 | image = "https://pkg.garrickadenbuie.com/drake-intro/assets/images/drake-intro-cover.jpg",
192 | image_alt = "The first slide of the Reproducible Data Workflows with drake presentation, featuring the drake hex logo and neatly ordered row of items on a desk (eraser, pencil, coffee cup, paperclips).",
193 | og_type = "website",
194 | og_author = "Garrick Aden-Buie",
195 | twitter_card_type = "summary_large_image",
196 | twitter_creator = "@grrrck"
197 | )
198 | ```
199 | ````
200 |
201 | ## Thanks
202 |
203 | Thanks to [Josh Buchea](https://github.com/joshbuchea) for providing an
204 | [excellent and indispensable
205 | resource](https://github.com/joshbuchea/HEAD) on `` tags and other
206 | things that go in the HTML `` tags.
207 |
208 | Thanks also to [Malcolm Barret](https://github.com/malcolmbarrett).
209 | Watching over his shoulder as he developed
210 | [ymlthis](https://ymlthis.r-lib.org) made putting this package together
211 | so much easier.
212 |
213 | Finally, thanks to the [RStudio team](https://github.com/rstudio) and
214 | others who developed [htmltools](https://github.com/rstudio/htmltools)
215 | for making HTML in R a breeze.
216 |
217 | ------------------------------------------------------------------------
218 |
219 | ### Notes
220 |
221 | 1. For adding meta tags to blogdown sites, [Socialize your blogdown by
222 | Xavier
223 | A](https://xvrdm.github.io/2017/10/23/socialize-your-blogdown/) is
224 | an excellent resource and you can use metathis to help discover the
225 | tags you need while following the instructions in the article.
226 |
--------------------------------------------------------------------------------
/man/figures/card.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------