Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
bfb5f46
add 404 page for bs4_book
maelle Dec 1, 2020
26929ae
fix
maelle Dec 1, 2020
0db8cbd
Merged upstream/master into maelle-404
cderv Jul 1, 2021
9350609
Add 404 page in splitting chapter process
cderv Jul 1, 2021
4694d91
use explicit name
cderv Jul 1, 2021
ae1372f
bs4_book can use bookdown feature now
cderv Jul 1, 2021
f4e70f3
Adapt text based on @apreshill feedback
cderv Jul 1, 2021
6947d89
Allow customization using _404.md or providing a 404.html directly
cderv Jul 1, 2021
567953c
Use _404.Rmd or _404.md
cderv Jul 1, 2021
6013211
separate in its own function
cderv Jul 1, 2021
2cba367
build function needs more arguments
cderv Jul 1, 2021
53cdb07
if 404 is set by md or Rmd, add the edit buttons
cderv Jul 1, 2021
93894e7
tweak 404 to remove sidebar
cderv Jul 1, 2021
92c5a72
Do nothing if 404.html exists already
cderv Jul 1, 2021
15e9cb9
Add tests for bs4_book
cderv Jul 2, 2021
c79badc
Start using testthat for new functions
cderv Jul 2, 2021
d95269e
Add a NEWS bullet
cderv Jul 2, 2021
025ffa8
Merge commit '28b11a489b843959d5b883208971243a6100b332'
cderv Jul 2, 2021
87de9fd
resolve NEWS conflict
cderv Jul 6, 2021
2b0a2e0
Merge branch 'upstream/master'
cderv Jul 6, 2021
183ed78
Merged upstream/master into maelle-404
cderv Jul 13, 2021
74b7c40
trivial cosmetic changes
yihui Jul 19, 2021
b252098
I don't think the variables `found` and `p404` can be found in the ne…
yihui Jul 19, 2021
a1c208f
use existing_files()
yihui Jul 19, 2021
33602ad
mostly cosmetic changes so that we don't need to pass several variabl…
yihui Jul 19, 2021
2630883
tweak tests for build_404()
yihui Jul 19, 2021
8ac3b62
further tweaking tests
yihui Jul 20, 2021
a527d39
don't move the existing 404.html
yihui Jul 20, 2021
a8d98d9
Don't remove empty lines in 404.html created using html_fragment()
cderv Jul 21, 2021
fd73253
Bump version
cderv Jul 21, 2021
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
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: bookdown
Type: Package
Title: Authoring Books and Technical Documents with R Markdown
Version: 0.22.12
Version: 0.22.13
Authors@R: c(
person("Yihui", "Xie", role = c("aut", "cre"), email = "[email protected]", comment = c(ORCID = "0000-0003-0645-5666")),
person("JJ", "Allaire", role = "ctb"),
Expand Down
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
# CHANGES IN bookdown VERSION 0.23

- For HTML book formats, a default `404.html` page will now be created if none exists already. This page can be customized by adding a `_404.md` or `_404.Rmd` file which will be rendered to HTML and inserted in the book. Most web serving platforms (e.g. Netlify, GH Pages, etc.) will use this file named `404.html` in the root as a custom error page. Otherwise, like browsers do, a default 404 page is shown. For context, a 404 error indicates that the file can’t be found, and it happens when a browser can’t find a requested web page. This could happen with your online book if you shared a link to a section but change the name of this section leading to a change in url (#1035).

- In `bs4_book()`, improvement regarding copy button:
* It has now a light icon instead of a text with white background (#1192).
* It will no more show on output block code when knitr's option is `collapse = FALSE` (#1197).
* It will now be placed correctly on the right side of the code block, with a light color which gets darker on hover so that it is less obtrusive when ovelapping text in block with long lines (#1204). If you want to customize part of the UI to change this default behavior, you can do it using a custom css with `bs4_book()`.

- In `bs4_book()`, copy button has now a light icon instead of a text with white background (#1192).
- Fix an issue with `bs4_book()` where text written using [Line Block](https://bookdown.org/yihui/rmarkdown-cookbook/indent-text.html) was not found in search (thanks, @dmklotz, #1141).

- `bs4_book()` has now some `<meta>` tags that allows sharing a published book on social media. `cover-image`, `url`, `title` and `description` set in YAML will be used in `index.html` and then modified to be adapted per HTML page (#1034).
Expand Down
13 changes: 13 additions & 0 deletions R/bs4_book.R
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,13 @@ bs4_chapters_tweak <- function(output,
message("Tweaking ", path)
index[[i]] <- bs4_chapter_tweak(path, toc, rmd_index = rmd_index, repo = repo)
}
# tweak 404.html ---
path_404 <- file.path(output_dir, "404.html")
if (file.exists(path_404)) {
message("Tweaking ", path_404)
bs4_chapter_tweak(path_404, toc, rmd_index = rmd_index, repo = repo)

}
index <- unlist(index, recursive = FALSE, use.names = FALSE)

jsonlite::write_json(
Expand All @@ -371,6 +378,7 @@ bs4_chapter_tweak <- function(path, toc, rmd_index = NULL, repo = NULL) {
tweak_part_screwup(html)
tweak_navbar(html, toc, basename(path), rmd_index = rmd_index, repo = repo)
tweak_metadata(html, path)
if (basename(path) == "404.html") tweak_404(html)
downlit::downlit_html_node(html)

xml2::write_html(html, path, format = FALSE)
Expand All @@ -383,6 +391,11 @@ bs4_chapter_tweak <- function(path, toc, rmd_index = NULL, repo = NULL) {
)
}

tweak_404 <- function(html) {
sidebar_toc <- xml2::xml_find_all(html, ".//div[contains(@class, 'sidebar')]/nav[@id='toc']")
xml2::xml_remove(sidebar_toc)
}

tweak_chapter <- function(html) {
num <- xml2::xml_find_all(html, ".//h1//span[@class='header-section-number']")
xml2::xml_text(num) <- gsub("Chapter ", "", xml2::xml_text(num))
Expand Down
41 changes: 40 additions & 1 deletion R/html.R
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,19 @@ split_chapters = function(output, build = build_chapter, number_sections, split_
)
write_utf8(html, nms[i])
}
nms = move_to_output_dir(nms)

# add a 404 page
r404 = build_404()
p404 = r404$path; h404 = r404$html
if (!is.null(h404)) {
h404 = build(
prepend_chapter_title(html_head, h404), html_toc, h404, NULL, NULL,
r404$rmd_cur, p404, html_foot, ...
)
write_utf8(h404, p404)
}

nms = move_to_output_dir(c(nms, p404))

# find the HTML output file corresponding to the Rmd file passed to render_book()
if (is.null(input) || length(nms_chaps) == 0) j = 1 else {
Expand All @@ -440,6 +452,33 @@ split_chapters = function(output, build = build_chapter, number_sections, split_
nms[j]
}

build_404 = function() {
p404 = '404.html'
# if a 404 page already exist, we do nothing specific and assume
# user has already a workflow in place
if (file.exists(p404)) return()
# We create 404 page if it does not exist
if (length(rmd_cur <- existing_files(c('_404.md', '_404.Rmd'), TRUE))) {
xfun::Rscript_call(rmarkdown::render, list(
rmd_cur, rmarkdown::html_fragment(pandoc_args = c('--metadata', 'title=404')),
output_file = p404, quiet = TRUE
))
h404 = xfun::read_utf8(p404)
} else {
rmd_cur = NULL
# default content for 404 page
h404 = c(
'<div id="page-not-found" class="section level1">',
'<h1>Page not found</h1>',
'<p>The page you requested cannot be found (perhaps it was moved or renamed).</p>',
'<p>You may want to try searching to find the page\'s new location, or use',
'the table of contents to find the page you are looking for.</p>',
'</div>'
)
}
list(path = p404, html = h404, rmd_cur = rmd_cur)
}

# clean HTML tags inside <meta>, which can be introduced by certain YAML
# metadata, such as an improper description that contains Markdown syntax, e.g.,
# <meta name="description" content="A <i>description</i>.">
Expand Down
26 changes: 26 additions & 0 deletions tests/testthat/test-bs4_book.R
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,29 @@ test_that("bs4_book() metadata tweaking works -- not index", {
)

})

test_that("bs4_book() and 404 -- page is tweaked", {
skip_if_bs4_book_deps_missing()
book <- local_bs4_book()
withr::local_dir(book)
expect_true(file.exists("_book/404.html"))
html <- xml2::read_html("_book/404.html")
expect_length(xml2::xml_find_all(html, ".//nav[@id = 'toc']"), 0L)
})

test_that("bs4_book() and 404 -- custom 404 page", {
skip_if_bs4_book_deps_missing()
book <- local_bs4_book()
withr::local_dir(book)
xfun::write_utf8(c("# Page not found", "", "I am created with _404.Rmd"), "_404.Rmd")
suppressMessages(render_book(".", "bookdown::bs4_book", quiet = TRUE))
expect_true(file.exists("_book/404.html"))
html <- xml2::read_html("_book/404.html")
expect_match(xml2::xml_text(xml2::xml_find_first(html, ".//main/div/p")), "_404.Rmd", fixed = TRUE)
unlink("_404.Rmd")
xfun::write_utf8(c("# Page not found", "", "I am created with _404.md"), "_404.md")
suppressMessages(render_book(".", "bookdown::bs4_book", quiet = TRUE))
expect_true(file.exists("_book/404.html"))
html <- xml2::read_html("_book/404.html")
expect_match(xml2::xml_text(xml2::xml_find_first(html, ".//main/div/p")), "_404.md", fixed = TRUE)
})
25 changes: 25 additions & 0 deletions tests/testthat/test-html.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
test_that("build_404 creates correct 404 page", {
tmp_dir <- withr::local_tempdir()
withr::local_dir(tmp_dir)

# default page
expect_false(file.exists("404.html"))
expect_null(build_404()$rmd_cur)
expect_false(file.exists("404.html"))

# custom pages
xfun::write_utf8(c("# Page not found", "", "I am created with _404.Rmd"), "_404.Rmd")
build_404()
expect_true(file.exists("404.html"))
expect_match(xfun::file_string("404.html"), "I am created with _404.Rmd", fixed = TRUE)

# do nothing if one exist
expect_null(build_404()$html)

unlink(c("404.html", "_404.Rmd"))

xfun::write_utf8(c("# Page not found", "", "I am created with _404.md"), "_404.md")
build_404()
expect_true(file.exists("404.html"))
expect_match(xfun::file_string("404.html"), "I am created with _404.md", fixed = TRUE)
})