Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for "external" articles #2576

Merged
merged 5 commits into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# pkgdown (development version)

* `build_articles()` now recognises a new `external-articles` top-level field that allows you to define articles that live in other packages (#2028).
* `vignette("search")` has been removed since BS3 is deprecated and all the BS5 docs are also included in `build_search()` (#2564).
* YAML validation has been substantially improved so you should get much clearer errors if you have made a mistake (#1927). Please file an issue if you find a case where the error message is not helpful.
* `template_reference()` and `template_article()` now only add backticks to function names if needed (#2561).
Expand Down
148 changes: 108 additions & 40 deletions R/build-articles.R
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
#' the navbar, it will link directly to the articles index instead of
#' providing a drop-down.
#'
#' # Get started
#' ## Get started
#' Note that a vignette with the same name as the package (e.g.,
#' `vignettes/pkgdown.Rmd` or `vignettes/articles/pkgdown.Rmd`) automatically
#' becomes a top-level "Get started" link, and will not appear in the articles
Expand All @@ -86,13 +86,27 @@
#' (If your package name includes a `.`, e.g. `pack.down`, use a `-` in the
#' vignette name, e.g. `pack-down.Rmd`.)
#'
#' ## Missing topics
#' ## Missing articles
#'
#' pkgdown will warn if there are (non-internal) articles that aren't listed
#' in the articles index. You can suppress such warnings by listing the
#' affected articles in a section with `title: internal` (case sensitive);
#' this section will not be displayed on the index page.
#'
#' ## External articles
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this section is incomplete.

adding the external-articles: entry isn't sufficient, and should be accompanied by adding the name:s to the contents: of articles:

#'
#' You can link to arbitrary additional articles by adding an
#' `external-articles` entry to `_pkgdown.yml`. It should contain an array
#' of objects with fields `name`, `title`, `href`, and `description`.
#'
#' ```yaml
#' external-articles:
#' - name: subsampling
#' title: Subsampling for Class Imbalances
#' description: Improve model performance in imbalanced data sets through undersampling or oversampling.
#' href: https://www.tidymodels.org/learn/models/sub-sampling/
#' ```
#'
#' # External files
#' pkgdown differs from base R in its handling of external files. When building
#' vignettes, R assumes that vignettes are self-contained (a reasonable
Expand Down Expand Up @@ -378,16 +392,16 @@ build_articles_index <- function(pkg = ".") {
data_articles_index <- function(pkg = ".", call = caller_env()) {
pkg <- as_pkgdown(pkg)

meta <- config_pluck_list(
pkg,
"articles",
default = default_articles_index(pkg),
articles <- data_articles(pkg, is_index = TRUE, call = call)
index <- config_pluck_list(pkg, "articles", call = call) %||%
default_articles_index(pkg)
sections <- unwrap_purrr_error(purrr::imap(
index,
data_articles_index_section,
articles = articles,
pkg = pkg,
call = call
)

sections <- unwrap_purrr_error(meta %>%
purrr::imap(data_articles_index_section, pkg = pkg, call = call) %>%
purrr::compact())
))

# Check for unlisted vignettes
listed <- sections %>%
Expand All @@ -396,7 +410,7 @@ data_articles_index <- function(pkg = ".", call = caller_env()) {
purrr::flatten_chr() %>%
unique()

missing <- setdiff(pkg$vignettes$name, listed)
missing <- setdiff(articles$name, listed)
# Exclude get started vignette or article #2150
missing <- missing[!article_is_intro(missing, package = pkg$package)]

Expand All @@ -417,10 +431,89 @@ data_articles_index <- function(pkg = ".", call = caller_env()) {
))
}

data_articles_index_section <- function(section, index, pkg, call = caller_env()) {
data_articles <- function(pkg = ".", is_index = FALSE, call = caller_env()) {
pkg <- as_pkgdown(pkg)

internal <- tibble::tibble(
name = pkg$vignettes$name,
title = pkg$vignettes$title,
href = pkg$vignettes$file_out,
description = pkg$vignettes$description,
)
if (is_index) {
internal$href <- path_rel(internal$href, "articles")
}

external <- config_pluck_external_articles(pkg, call = call)
articles <- rbind(internal, external)

articles$description <- lapply(articles$description, markdown_text_block)

# Hack data structure so we can use select_topics()
articles$alias <- as.list(articles$name)
articles$internal <- FALSE

articles
}

config_pluck_external_articles <- function(pkg, call = caller_env()) {
external <- config_pluck_list(pkg, "external-articles", call = call)
if (is.null(external)) {
return(tibble::tibble(
name = character(),
title = character(),
href = character(),
description = character()
))
}

for (i in seq_along(external)) {
config_check_list(
external[[i]],
has_names = c("name", "title", "href", "description"),
error_path = paste0("external-articles[", i, "]"),
error_pkg = pkg,
error_call = call
)
config_check_string(
external[[i]]$name,
error_path = paste0("external-articles[", i, "].name"),
error_pkg = pkg,
error_call = call
)
config_check_string(
external[[i]]$title,
error_path = paste0("external-articles[", i, "].title"),
error_pkg = pkg,
error_call = call
)
config_check_string(
external[[i]]$href,
error_path = paste0("external-articles[", i, "].href"),
error_pkg = pkg,
error_call = call
)
config_check_string(
external[[i]]$description,
error_path = paste0("external-articles[", i, "].description"),
error_pkg = pkg,
error_call = call
)
}

tibble::tibble(
name = purrr::map_chr(external, "name"),
title = purrr::map_chr(external, "title"),
href = purrr::map_chr(external, "href"),
description = purrr::map_chr(external, "description")
)
}

data_articles_index_section <- function(section, index, articles, pkg, call = caller_env()) {
config_check_list(
section,
error_path = paste0("articles[", index, "]"),
has_names = c("title", "contents"),
error_pkg = pkg,
error_call = call
)
Expand All @@ -443,24 +536,10 @@ data_articles_index_section <- function(section, index, pkg, call = caller_env()
error_pkg = pkg,
error_call = call
)
check_contents(
section$contents,
index,
pkg,
prefix = "articles",
quote(build_articles())
)
check_contents(section$contents, index, pkg, prefix = "articles", call = call)

# Match topics against any aliases
in_section <- select_vignettes(section$contents, pkg$vignettes)
section_vignettes <- pkg$vignettes[in_section, ]
contents <- tibble::tibble(
name = section_vignettes$name,
path = path_rel(section_vignettes$file_out, "articles"),
title = section_vignettes$title,
description = lapply(section_vignettes$description, markdown_text_block),
)

contents <- articles[select_topics(section$contents, articles), ]

list(
title = title,
Expand All @@ -470,17 +549,6 @@ data_articles_index_section <- function(section, index, pkg, call = caller_env()
)
}

# Quick hack: create the same structure as for topics so we can use
# the existing select_topics()
select_vignettes <- function(match_strings, vignettes) {
topics <- tibble::tibble(
name = vignettes$name,
alias = as.list(vignettes$name),
internal = FALSE
)
select_topics(match_strings, topics)
}

default_articles_index <- function(pkg = ".") {
pkg <- as_pkgdown(pkg)

Expand Down
13 changes: 7 additions & 6 deletions R/navbar.R
Original file line number Diff line number Diff line change
Expand Up @@ -165,24 +165,25 @@ navbar_articles <- function(pkg = ".") {
menu_links(vignettes$title, vignettes$file_out)
)
} else {
articles <- config_pluck(pkg, "articles")
articles_index <- config_pluck(pkg, "articles")
articles <- data_articles(pkg)

navbar <- purrr::keep(articles, ~ has_name(.x, "navbar"))
navbar <- purrr::keep(articles_index, ~ has_name(.x, "navbar"))
if (length(navbar) == 0) {
# No articles to be included in navbar so just link to index
menu$articles <- menu_link(tr_("Articles"), "articles/index.html")
} else {
sections <- lapply(navbar, function(section) {
vig <- pkg$vignettes[select_vignettes(section$contents, pkg$vignettes), , drop = FALSE]
vig <- articles[select_topics(section$contents, articles), , drop = FALSE]
vig <- vig[vig$name != pkg$package, , drop = FALSE]
c(
if (!is.null(section$navbar)) list(menu_separator(), menu_heading(section$navbar)),
menu_links(vig$title, vig$file_out)
menu_links(vig$title, vig$href)
)
})
children <- unlist(sections, recursive = FALSE, use.names = FALSE)

if (length(navbar) != length(articles)) {
if (length(navbar) != length(articles_index)) {
children <- c(
children,
list(
Expand Down Expand Up @@ -221,7 +222,7 @@ pkg_navbar_vignettes <- function(name = character(),
title <- title %||% paste0("Title ", name)
file_out <- file_out %||% paste0(name, ".html")

tibble::tibble(name = name, title = title, file_out)
tibble::tibble(name = name, title = title, file_out, description = "desc")
}


Expand Down
2 changes: 1 addition & 1 deletion R/package.R
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ package_vignettes <- function(path = ".") {
check_unique_article_paths(file_in, file_out)

out <- tibble::tibble(
name = path_ext_remove(vig_path),
name = as.character(path_ext_remove(vig_path)),
file_in = file_in,
file_out = file_out,
title = title,
Expand Down
2 changes: 1 addition & 1 deletion inst/BS3/templates/content-article-index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ <h3>{{{title}}}</h3>

<dl>
{{#contents}}
<dt><a href="{{path}}">{{title}}</a></dt>
<dt><a href="{{href}}">{{title}}</a></dt>
<dd>{{{description}}}</dt>
{{/contents}}
</dl>
Expand Down
2 changes: 1 addition & 1 deletion inst/BS5/templates/content-article-index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ <h3>{{{title}}}</h3>

<dl>
{{#contents}}
<dt><a href="{{path}}">{{title}}</a></dt>
<dt><a href="{{href}}">{{title}}</a></dt>
<dd>{{{description}}}</dt>
{{/contents}}
</dl>
Expand Down
21 changes: 18 additions & 3 deletions man/build_articles.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading