From bd4e0743af938dda7df37fa933f30e3f21e2773d Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Wed, 18 Sep 2024 22:29:06 +0200 Subject: [PATCH 01/29] docs: rewrite README --- README.Rmd | 226 ------------------------------------- README.md | 323 ++--------------------------------------------------- 2 files changed, 8 insertions(+), 541 deletions(-) delete mode 100644 README.Rmd diff --git a/README.Rmd b/README.Rmd deleted file mode 100644 index 3d093a4..0000000 --- a/README.Rmd +++ /dev/null @@ -1,226 +0,0 @@ ---- -output: github_document ---- - - - -```{r, include = FALSE} -knitr::opts_chunk$set( - collapse = TRUE, - comment = "#>", - fig.path = "man/figures/README-", - out.width = "100%" -) -``` - -# babelquarto - - -[![R-CMD-check](https://github.com/ropensci-review-tools/quartobabel/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/ropensci-review-tools/quartobabel/actions/workflows/R-CMD-check.yaml) - - -The goal of babelquarto is to render a Quarto multilingual project, book or website. - -## Installation - -You can install the development version of babelquarto from rOpenSci R-universe: - -```r -install.packages('babelquarto', repos = c('https://ropensci.r-universe.dev', 'https://cloud.r-project.org')) -``` - -Or from [GitHub](https://github.com/) with: - -``` r -# install.packages("pak") -pak::pak("ropensci-review-tools/babelquarto") -``` - -Once using babelquarto, you cannot render your book or website using Quarto CLI (or the RStudio IDE render button) directly. -You need to use `babelquarto::render_book()` or `babelquarto::render_website()`, respectively. - -## Example book - -Create a starter/example book. - -```{r} -parent_dir <- withr::local_tempdir() -project_dir <- "blop" -babelquarto::quarto_multilingual_book(parent_dir = parent_dir, project_dir = project_dir) -readLines(file.path(parent_dir, project_dir, "_quarto.yml")) -fs::dir_tree(file.path(parent_dir, project_dir)) -``` - -```{r, results='hide'} -babelquarto::render_book(file.path(parent_dir, project_dir)) -``` - -We end up with three books, that cross-link to each other from the left sidebar. -[Example](https://devdevguide.netlify.app). - - -## Example website - - -Create a starter/example website. - -```{r} -parent_dir <- withr::local_tempdir() -project_dir <- "blop" -babelquarto::quarto_multilingual_website(parent_dir = parent_dir, project_dir = project_dir) -readLines(file.path(parent_dir, project_dir, "_quarto.yml")) -fs::dir_tree(file.path(parent_dir, project_dir)) -``` - -```{r, results='hide'} -babelquarto::render_website(file.path(parent_dir, project_dir)) -``` - -[Example](https://maelle.github.io/babelsite), [source](https://github.com/maelle/babelsite) - - -## Configure the base URL - -Use the [usual Quarto field](https://quarto.org/docs/websites/website-tools.html), or use the `site_url` argument of `babelquarto::render_book()`. - -``` -book: - site-url: https://example.com -``` - -## Configure the version text - -If you want the choice to be between, say "English" and "Español" rather than "Version in EN" and "Version in ES", add these fields under the babelquarto YAML key, in `_quarto.yml`: - -```yaml -babelquarto: - languagecodes: - - name: es - text: "Español" - - name: en - text: "English" -``` - -Using `babelquarto::register_main_language()` and `babelquarto::register_further_languages()` will create the boilertemplate for these fields. - -## Configure the language link placement - -The language link menu can be placed in the *sidebar* or in the *navbar*. -To change the placement, use the `languagelinks` field in the babelquarto YAML key, in `_quarto.yml`: - -```yaml -babelquarto: - languagelinks: sidebar -``` - -Beware: depending on the value of `languagelinks`, the corresponding menu needs to be configured. -Books always have a *sidebar*, but websites can have either *navbar* or *sidebar*. See [Quarto documentation](https://quarto.org/docs/websites/website-navigation.html#side-navigation) for more information. - -## Distinct configuration per language - -There are two complementary/overlapping solutions for making the different language versions distinct (different banner, different navbar for instance): - -### Configuration file per language - -For a book with French ("fr") and English ("en") versions you could have three Quarto configuration files: - -- `_quarto.yml` with the general configuration including the chapters list; -- `_quarto-fr.yml` with an [announcement bar](https://quarto.org/docs/websites/website-tools.html#announcement-bar) in French; -- `_quarto-en.yml` with an [announcement bar](https://quarto.org/docs/websites/website-tools.html#announcement-bar) in English. - -You could use the same strategy for having different navbars in the different language versions of a multilingual website. - -This uses [Quarto profiles](https://quarto.org/docs/projects/profiles.html) under the hood. -You can still use other profiles such as development and production, by passing them as the `profile` argument of `render_book()` and `render_website()`. - -### Configure templates - -If you want, say, a banner with different content in the different languages, you can create a [partial template](https://quarto.org/docs/journals/templates.html#html-partials) and in it use the variables `lang-fr` and `lang-en` for instance for content in French and English. - -The Quarto configuration file `_quarto.yml` would include: - -```yaml -format: - html: - template-partials: - - metadata.html -``` - -The end of the `metadata.html` template would be: - -```html - -
-$if(lang-en)$Hello$endif$ -$if(lang-fr)$Salut$endif$ -$if(lang-es)$Hola$endif$ -
-``` - -## Content translation - -From a book whose main language is English... - -```{r} -parent_dir <- withr::local_tempdir() -project_dir <- "babelbook" -quarto_bin <- quarto::quarto_path() -withr::with_dir(parent_dir, { - sys::exec_wait( - quarto_bin, - args = c("create-project", project_dir, "--type", "book") - ) -}) -``` - -- Register languages in the Quarto configuration, for instance - -```{r} -project_path <- file.path(parent_dir, project_dir) -babelquarto::register_main_language(main_language = "en", project_path = project_path) -babelquarto::register_further_languages(further_languages = "es", project_path = project_path) -``` - - -This is how the config file now looks like: - -````{r, results='asis', echo=FALSE} -c( - "```yaml", - readLines(file.path(project_path, "_quarto.yml")), - "```" -) |> - paste(collapse = "\n") |> - cat() -```` - - -- qmd/Rmd files. `bla.qmd` translation in Spanish would live in `bla.es.qmd`. See [babeldown](https://docs.ropensci.org/babeldown) for getting an automated translation. -- parts. The part title translation can be stored in `_quarto.yml` like so: - -```yml - - part: Building Your Package - part-es: Construyendo tu paquete - chapters: - - pkg_building.Rmd - - pkg_ci.Rmd - - pkg_security.Rmd -``` - -If it does not exist, babelquarto falls back to the part title in the main language. - -- title, author, description. Their translation can be stored in `_quarto.yml` like so (NOT in the `book` list): - -```yml -book: - title: Cool book - author: Myself - -title-es: Libro genial -author-es: Yo misma -``` - -If these fields do not exist, babelquarto falls back to their text in the main language. - -Note that babelquarto does not _translate_ the content! -Translation tooling lives in [babeldown](https://docs.ropensci.org/babeldown). diff --git a/README.md b/README.md index 3a588bb..70c1b21 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,4 @@ - - # babelquarto @@ -8,12 +6,15 @@ [![R-CMD-check](https://github.com/ropensci-review-tools/quartobabel/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/ropensci-review-tools/quartobabel/actions/workflows/R-CMD-check.yaml) -The goal of babelquarto is to render a Quarto multilingual project, book +The goal of {babelquarto} is to render a Quarto multilingual project, book or website. +Note that babelquarto does not *translate* the content! Translation +tooling lives in {[babeldown](https://docs.ropensci.org/babeldown)}. + ## Installation -You can install the development version of babelquarto from rOpenSci +You can install the development version of {babelquarto} from rOpenSci R-universe: ``` r @@ -27,315 +28,7 @@ Or from [GitHub](https://github.com/) with: pak::pak("ropensci-review-tools/babelquarto") ``` -Once using babelquarto, you cannot render your book or website using -Quarto CLI (or the RStudio IDE render button) directly. You need to use -`babelquarto::render_book()` or `babelquarto::render_website()`, -respectively. - -## Example book - -Create a starter/example book. - -``` r -parent_dir <- withr::local_tempdir() -project_dir <- "blop" -babelquarto::quarto_multilingual_book(parent_dir = parent_dir, project_dir = project_dir) -#> [1] "/var/folders/gd/rrsyq__147x_8y_3zcpymj_40000gn/T//Rtmpr3nsvT/filed2be237749e5/blop" -readLines(file.path(parent_dir, project_dir, "_quarto.yml")) -#> [1] "project:" " type: book" -#> [3] "" "book:" -#> [5] " site-url: https://example.com" " title: \"blop\"" -#> [7] " author: \"Pascal Burkhard\"" " date: \"11.09.2024\"" -#> [9] " chapters:" " - index.qmd" -#> [11] " - intro.qmd" " - summary.qmd" -#> [13] " - references.qmd" "" -#> [15] "bibliography: references.bib" "" -#> [17] "format:" " html:" -#> [19] " theme: cosmo" "" -#> [21] "babelquarto:" " languagelinks: sidebar" -#> [23] " languagecodes:" " - name: es" -#> [25] " text: \"Version in es\"" " - name: fr" -#> [27] " text: \"Version in fr\"" " - name: en" -#> [29] " text: \"Version in en\"" " mainlanguage: 'en'" -#> [31] " languages: ['es', 'fr']" "title-es: title in es" -#> [33] "title-fr: title in fr" "description-es: description in es" -#> [35] "description-fr: description in fr" "author-es: author in es" -#> [37] "author-fr: author in fr" "lang: en" -fs::dir_tree(file.path(parent_dir, project_dir)) -#> /var/folders/gd/rrsyq__147x_8y_3zcpymj_40000gn/T//Rtmpr3nsvT/filed2be237749e5/blop -#> ├── _quarto.yml -#> ├── cover.png -#> ├── index.es.qmd -#> ├── index.fr.qmd -#> ├── index.qmd -#> ├── intro.es.qmd -#> ├── intro.fr.qmd -#> ├── intro.qmd -#> ├── references.bib -#> ├── references.es.qmd -#> ├── references.fr.qmd -#> ├── references.qmd -#> ├── summary.es.qmd -#> ├── summary.fr.qmd -#> └── summary.qmd -``` - -``` r -babelquarto::render_book(file.path(parent_dir, project_dir)) -``` - -We end up with three books, that cross-link to each other from the left -sidebar. [Example](https://devdevguide.netlify.app). - -## Example website - -Create a starter/example website. - -``` r -parent_dir <- withr::local_tempdir() -project_dir <- "blop" -babelquarto::quarto_multilingual_website(parent_dir = parent_dir, project_dir = project_dir) -#> [1] "/var/folders/gd/rrsyq__147x_8y_3zcpymj_40000gn/T//Rtmpr3nsvT/filed2be4d2b3e3/blop" -readLines(file.path(parent_dir, project_dir, "_quarto.yml")) -#> [1] "project:" " type: website" -#> [3] "" "website:" -#> [5] " site-url: https://example.com" " title: \"blop\"" -#> [7] " navbar:" " left:" -#> [9] " - href: index.qmd" " text: Home" -#> [11] " - about.qmd" "" -#> [13] "format:" " html:" -#> [15] " theme: cosmo" " css: styles.css" -#> [17] " toc: true" "" -#> [19] "" "" -#> [21] "" "babelquarto:" -#> [23] " languagelinks: navbar" " languagecodes:" -#> [25] " - name: es" " text: \"Version in es\"" -#> [27] " - name: fr" " text: \"Version in fr\"" -#> [29] " - name: en" " text: \"Version in en\"" -#> [31] " mainlanguage: 'en'" " languages: ['es', 'fr']" -#> [33] "title-es: title in es" "title-fr: title in fr" -#> [35] "description-es: description in es" "description-fr: description in fr" -#> [37] "author-es: author in es" "author-fr: author in fr" -#> [39] "lang: en" -fs::dir_tree(file.path(parent_dir, project_dir)) -#> /var/folders/gd/rrsyq__147x_8y_3zcpymj_40000gn/T//Rtmpr3nsvT/filed2be4d2b3e3/blop -#> ├── _quarto.yml -#> ├── about.es.qmd -#> ├── about.fr.qmd -#> ├── about.qmd -#> ├── index.es.qmd -#> ├── index.fr.qmd -#> ├── index.qmd -#> └── styles.css -``` - -``` r -babelquarto::render_website(file.path(parent_dir, project_dir)) -``` - -[Example](https://maelle.github.io/babelsite), -[source](https://github.com/maelle/babelsite) - -## Configure the base URL - -Use the [usual Quarto -field](https://quarto.org/docs/websites/website-tools.html), or use the -`site_url` argument of `babelquarto::render_book()`. - - book: - site-url: https://example.com - -## Configure the version text - -If you want the choice to be between, say “English” and “Español” rather -than “Version in EN” and “Version in ES”, add these fields under the -babelquarto YAML key, in `_quarto.yml`: - -``` yaml -babelquarto: - languagecodes: - - name: es - text: "Español" - - name: en - text: "English" -``` - -Using `babelquarto::register_main_language()` and -`babelquarto::register_further_languages()` will create the -boilertemplate for these fields. - -## Configure the language link placement - -The language link menu can be placed in the *sidebar* or in the -*navbar*. To change the placement, use the `languagelinks` field in the -babelquarto YAML key, in `_quarto.yml`: - -``` yaml -babelquarto: - languagelinks: sidebar -``` - -Beware: depending on the value of `languagelinks`, the corresponding -menu needs to be configured. Books always have a *sidebar*, but websites -can have either *navbar* or *sidebar*. See [Quarto -documentation](https://quarto.org/docs/websites/website-navigation.html#side-navigation) -for more information. - -## Distinct configuration per language - -There are two complementary/overlapping solutions for making the -different language versions distinct (different banner, different navbar -for instance): - -### Configuration file per language - -For a book with French (“fr”) and English (“en”) versions you could have -three Quarto configuration files: - -- `_quarto.yml` with the general configuration including the chapters - list; -- `_quarto-fr.yml` with an [announcement - bar](https://quarto.org/docs/websites/website-tools.html#announcement-bar) - in French; -- `_quarto-en.yml` with an [announcement - bar](https://quarto.org/docs/websites/website-tools.html#announcement-bar) - in English. - -You could use the same strategy for having different navbars in the -different language versions of a multilingual website. - -This uses [Quarto -profiles](https://quarto.org/docs/projects/profiles.html) under the -hood. You can still use other profiles such as development and -production, by passing them as the `profile` argument of `render_book()` -and `render_website()`. - -### Configure templates - -If you want, say, a banner with different content in the different -languages, you can create a [partial -template](https://quarto.org/docs/journals/templates.html#html-partials) -and in it use the variables `lang-fr` and `lang-en` for instance for -content in French and English. - -The Quarto configuration file `_quarto.yml` would include: - -``` yaml -format: - html: - template-partials: - - metadata.html -``` - -The end of the `metadata.html` template would be: - -``` html - -
-$if(lang-en)$Hello$endif$ -$if(lang-fr)$Salut$endif$ -$if(lang-es)$Hola$endif$ -
-``` - -## Content translation - -From a book whose main language is English… - -``` r -parent_dir <- withr::local_tempdir() -project_dir <- "babelbook" -quarto_bin <- quarto::quarto_path() -withr::with_dir(parent_dir, { - sys::exec_wait( - quarto_bin, - args = c("create-project", project_dir, "--type", "book") - ) -}) -#> [1] 0 -``` - -- Register languages in the Quarto configuration, for instance - -``` r -project_path <- file.path(parent_dir, project_dir) -babelquarto::register_main_language(main_language = "en", project_path = project_path) -babelquarto::register_further_languages(further_languages = "es", project_path = project_path) -``` - -This is how the config file now looks like: +## Getting Started -``` yaml -project: - type: book - -book: - title: "babelbook" - author: "Norah Jones" - date: "11.09.2024" - chapters: - - index.qmd - - intro.qmd - - summary.qmd - - references.qmd - -bibliography: references.bib - -format: - html: - theme: cosmo - pdf: - documentclass: scrreprt - - - - -babelquarto: - languagecodes: - - name: es - text: "Version in es" - - name: en - text: "Version in en" - mainlanguage: 'en' - languages: ['es'] -title-es: title in es -description-es: description in es -author-es: author in es -lang: en -``` - -- qmd/Rmd files. `bla.qmd` translation in Spanish would live in - `bla.es.qmd`. See [babeldown](https://docs.ropensci.org/babeldown) for - getting an automated translation. -- parts. The part title translation can be stored in `_quarto.yml` like - so: - -``` yml - - part: Building Your Package - part-es: Construyendo tu paquete - chapters: - - pkg_building.Rmd - - pkg_ci.Rmd - - pkg_security.Rmd -``` - -If it does not exist, babelquarto falls back to the part title in the -main language. - -- title, author, description. Their translation can be stored in - `_quarto.yml` like so (NOT in the `book` list): - -``` yml -book: - title: Cool book - author: Myself - -title-es: Libro genial -author-es: Yo misma -``` - -If these fields do not exist, babelquarto falls back to their text in -the main language. - -Note that babelquarto does not *translate* the content! Translation -tooling lives in [babeldown](https://docs.ropensci.org/babeldown). +If you are just getting started with {babelquarto}, +you should start by reading the tutorial `vignette("babelquarto")`. From 265fabcbd2be457d5d94e7c499d95a5fc0d6f591 Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Wed, 18 Sep 2024 22:29:43 +0200 Subject: [PATCH 02/29] docs: prepare for Quarto vignettes --- .gitignore | 3 +++ DESCRIPTION | 2 ++ _pkdown.yml | 2 ++ man/figures/logo.png | Bin 0 -> 33568 bytes vignettes/.gitignore | 1 + 5 files changed, 8 insertions(+) create mode 100644 _pkdown.yml create mode 100644 man/figures/logo.png create mode 100644 vignettes/.gitignore diff --git a/.gitignore b/.gitignore index 565f2b6..9b35bd0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ .Rdata .httr-oauth .DS_Store + +docs +vignettes/*_files diff --git a/DESCRIPTION b/DESCRIPTION index d46e6ac..aff448e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -34,3 +34,5 @@ Suggests: URL: https://github.com/ropensci-review-tools/babelquarto BugReports: https://github.com/ropensci-review-tools/babelquarto/issues Config/testthat/edition: 3 +VignetteBuilder: + quarto diff --git a/_pkdown.yml b/_pkdown.yml new file mode 100644 index 0000000..ec0a740 --- /dev/null +++ b/_pkdown.yml @@ -0,0 +1,2 @@ +template: + bootstrap: 5 diff --git a/man/figures/logo.png b/man/figures/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..de60c8d0631d4a0a580ba784c73f0c36d8b866dc GIT binary patch literal 33568 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 B;7b4i literal 0 HcmV?d00001 diff --git a/vignettes/.gitignore b/vignettes/.gitignore new file mode 100644 index 0000000..075b254 --- /dev/null +++ b/vignettes/.gitignore @@ -0,0 +1 @@ +/.quarto/ From 1f6e6cbfb78238bbc59f2877941a221812530eed Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Wed, 18 Sep 2024 22:30:14 +0200 Subject: [PATCH 03/29] docs: vignette Getting started --- vignettes/babelquarto.qmd | 146 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 vignettes/babelquarto.qmd diff --git a/vignettes/babelquarto.qmd b/vignettes/babelquarto.qmd new file mode 100644 index 0000000..03405d7 --- /dev/null +++ b/vignettes/babelquarto.qmd @@ -0,0 +1,146 @@ +--- +title: "Get started" +vignette: > + %\VignetteIndexEntry{Get started} + %\VignetteEngine{quarto::html} + %\VignetteEncoding{UTF-8} +--- + +The goal of this vignette is to show how you can start a new multilingual Quarto project using {babelquarto}. +There are two types of project you can start: a book or a website. We will look at each type seperately below. + +If you want to turn an existing project into a multilingual project, have a look at `vignette("convert")`. + +## Installing babelquarto + +Before you can start a new multilingual project, you need to install {babelquarto}. + +```r +install.packages('babelquarto', repos = c('https://ropensci.r-universe.dev', 'https://cloud.r-project.org')) +``` + +Or from [GitHub](https://github.com/) with: + +``` r +# install.packages("pak") +pak::pak("ropensci-review-tools/babelquarto") +``` + +Load the babelquarto package: + +```{r} +library(babelquarto) +``` + +## Starting a multilingual book + +To start with a multilingual book, use `quarto_multilingual_book()` with the `parent_dir` argument to specify where you want to create the project and the `project_dir` argument to specify the name of the project. + +```{r} +#| label: setup_book +#| results: 'hide' +parent_dir <- withr::local_tempdir() +project_dir <- "multilingual_book" +quarto_multilingual_book(parent_dir = parent_dir, project_dir = project_dir) +``` + +Look at the `_quarto.yml` file in the project directory. To get familiar with the configuration, take a look at the example below: + +```{r} +#| label: display_book_config +#| echo: false +#| results: 'asis' + +# Awaiting r-lib/pkgdown#2776 +# cat("```{.yaml filename='_quarto.yml'}\n") +cat("```yaml\n") +readLines(file.path(parent_dir, project_dir, "_quarto.yml")) |> + cat(sep = "\n") +cat("```\n") +``` + +The file structure of the project looks like this: + +```{r} +#| label: book_dir_structure +fs::dir_tree(file.path(parent_dir, project_dir)) +``` + +Each quarto file has a spanish and a french translation. If you look at the `index.qmd` file, you'll see that the french translation is `index.fr.qmd` and the spanish translation is `index.es.qmd`. + +When you're ready to render your book, use `render_book()`: + +```{r} +#| label: render_book +#| eval: false +babelquarto::render_book(file.path(parent_dir, project_dir)) +``` + +We end up with three books, that cross-link to each other from the left sidebar. +[Example](https://devdevguide.netlify.app). + +## Starting a multilingual website + +To start a multilingual website, use `quarto_multilingual_website()` with the `parent_dir` argument to specify where you want to create the project and the `project_dir` argument to specify the name of the project. + +```{r} +#| label: setup_website +#| results: 'hide' +parent_dir <- withr::local_tempdir() +project_dir <- "multilingual_website" +babelquarto::quarto_multilingual_website(parent_dir = parent_dir, project_dir = project_dir) +``` + +Look at the `_quarto.yml` file in the project directory. To get familiar with the configuration, take a look at the example below: + +```{r} +#| label: display_website_config +#| echo: false +#| results: 'asis' + +# cat("```{.yaml filename='_quarto.yml'}\n") +cat("```yaml\n") +readLines(file.path(parent_dir, project_dir, "_quarto.yml")) |> + cat(sep = "\n") +cat("```\n") +``` + +The file structure of the project looks like this: + +```{r} +#| label: website_dir_structure +fs::dir_tree(file.path(parent_dir, project_dir)) +``` + +Each quarto file has a spanish and a french translation. If you look at the `index.qmd` file, you'll see that the french translation is `index.fr.qmd` and the spanish translation is `index.es.qmd`. + +When you're ready to render your website, use `render_website()`: + +```{r} +#| label: render_website +#| eval: false +babelquarto::render_website(file.path(parent_dir, project_dir)) +``` + +We end up with a multilingual website. [Example](https://maelle.github.io/babelsite), [source](https://github.com/maelle/babelsite) + +## Previewing your multilingual project + +Once you have rendered your project, you will have a `_site` or `_book` folder in your project. To easily preview your project, can use the [`servr` package](https://cran.rstudio.com/web/packages/servr/index.html). + +You can use `servr::httw()` to preview your project. + +```{r} +#| eval: false +# For a multilingual website +servr::httw("_site") + +# For a multilingual book +servr::httw("_book") +``` + +## Next steps + +Take a deeper dive into the configuration options available in {babelquarto} you can have a look at `vignette("configuration")`. + +If you want to setup your own CI and deploy your website, have a look at `vignette("render-with-ci")`. From df523b75e776a99d35812002c52731bb1306b883 Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Wed, 18 Sep 2024 22:36:23 +0200 Subject: [PATCH 04/29] docs: vignette Convert and existing project --- vignettes/convert.qmd | 65 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 vignettes/convert.qmd diff --git a/vignettes/convert.qmd b/vignettes/convert.qmd new file mode 100644 index 0000000..aeb4949 --- /dev/null +++ b/vignettes/convert.qmd @@ -0,0 +1,65 @@ +--- +title: "Convert an existing project" +description: > + How to convert an existing project to a multilingual Quarto project +vignette: > + %\VignetteIndexEntry{Convert an existing project} + %\VignetteEngine{quarto::html} + %\VignetteEncoding{UTF-8} +--- + +If you want to turn an existing project into a multilingual project, you can use {babelquarto}'s `register_main_language()` and `register_further_languages()` functions. + +Let's start with a book whose main language is English. + +```{r} +#| results: 'hide' +parent_dir <- withr::local_tempdir() +project_dir <- "babelbook" +quarto_bin <- quarto::quarto_path() +withr::with_dir(parent_dir, { + sys::exec_wait( + quarto_bin, + args = c("create-project", project_dir, "--type", "book") + ) +}) +``` + +First you'll need to register the main language in the Quarto configuration: + +```{r} +project_path <- file.path(parent_dir, project_dir) +babelquarto::register_main_language( + main_language = "en", + project_path = project_path +) +``` + +Then you can add further languages, say Spanish and French: + +```{r} +babelquarto::register_further_languages( + further_languages = c("es", "fr"), + project_path = project_path +) +``` + +We end up with a multilingual book in English and Spanish. If you look at the `_quarto.yml` file in the project directory, you'll see that the `main_language` key is `en` and the `languages` key contains `es` and `fr`. + +```{r} +#| echo: false +#| results: 'asis' + +# Awaiting r-lib/pkgdown#2776 +#cat("```{.yaml filename='_quarto.yml'}\n") +cat("```yaml\n") +readLines(file.path(parent_dir, project_dir, "_quarto.yml")) |> + cat(sep = "\n") +cat("```\n") +``` + +## Next steps + +Take a deeper dive into the configuration options available in {babelquarto} you can have a look at `vignette("configuration")`. + +If you want to setup your own CI and deploy your website, have a look at `vignette("render-with-ci")`. From a6f2ca1b6f6261cc2f72effdb38fdbc03c2fb686 Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Wed, 18 Sep 2024 22:36:37 +0200 Subject: [PATCH 05/29] docs: vignette Configuration --- vignettes/configuration.qmd | 134 ++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 vignettes/configuration.qmd diff --git a/vignettes/configuration.qmd b/vignettes/configuration.qmd new file mode 100644 index 0000000..588bf01 --- /dev/null +++ b/vignettes/configuration.qmd @@ -0,0 +1,134 @@ +--- +title: "Configuration" +vignette: > + %\VignetteIndexEntry{Get started} + %\VignetteEngine{quarto::html} + %\VignetteEncoding{UTF-8} +--- + +The goal of this vignette is to show the configuration options that are available in {babelquarto}. + +## Basic configuration + +When you start a {babelquarto} project, from scratch or from an existing project, your `_quarto.yml` file will contain a number of new options: + +```{r} +#| echo: false +#| message: false +#| results: 'asis' +parent_dir <- withr::local_tempdir() +project_dir <- "multilingual_book" +book <- babelquarto::quarto_multilingual_book(parent_dir = parent_dir, project_dir = project_dir) +config_path <- file.path(parent_dir, project_dir, "_quarto.yml") +config_lines <- brio::read_lines(config_path) +where_babelquarto <- grep("babelquarto:", config_lines, fixed = TRUE) + +# Awaiting r-lib/pkgdown#2776 +# cat("```{.yaml filename='_quarto.yml'}\n") +cat("```yaml\n") +config_lines[where_babelquarto:length(config_lines)] |> + cat(sep = "\n") +cat("```\n") +``` + +By default, {babelquarto} will have the following options under the `babelquarto` key: + +| | | +|------------------------------------|------------------------------------| +| `languagelinks` | Where the menu with the links to other languages will be placed. Can be either `sidebar` or `navbar`. | +| `languagecodes` | A list with each language defined. Each entry has a `name` with the language abbreviation (for example *en* or *es*. The `text` key changes the text used for the links to this language. | +| `mainlanguage` | The main language of the project. | +| `languages` | An array of the additional languages (not including the main language). | + +In addition to the `babelquarto` key, you will see language specific keys for `title`, `description` and `author`. These keys allow you to have a specific title, description or author in for each additional language. + +### Configure the version text + +If you want the choice to be between, say "English" and "Español" rather than "Version in EN" and "Version in ES", add these fields under the `babelquarto/languagecodes` key, in `_quarto.yml`: + +```yaml +babelquarto: + languagecodes: + - name: es + text: "Español" + - name: en + text: "English" +``` + +Using `register_main_language()` and `register_further_languages()` will create the boilertemplate for these fields. + +## Configure the base URL + +If you need to configure a base URL, you can use the [usual Quarto field](https://quarto.org/docs/websites/website-tools.html), or use the `site_url` argument of `render_book()`. + +```yaml +book: + site-url: https://example.com +``` + +```yaml +website: + site-url: https://example.com +``` + +If you render your multilingual book or website in a CI context, you need will need to set the `BABELQUARTO_CI_URL` environment variable. See `vignette("render-with-ci")` for more information. + +## Translate parts in multilingual books + +In multilingual books, if you use parts to structure your book, you can translate the part titles like so: + + +```yaml +book: + chapters: + - index.qmd + - part: Foreword + part-fr: Préface + chapters: + - foreword.qmd + - part: Explore + part-fr: Explorer + chapters: + - intro-explore.qmd + - data-visualisation.qmd +``` + +For each additional language, you can use a `part-xx` key to translate the part title. + +## Using profiles for advanced configuration + +For more advanced customalization, you can use [Quarto project profiles](https://quarto.org/docs/projects/profiles.html). In {babelquarto} we will automatically load a profile if it exists in the project directory. Profile configuration are **merged** with the main `_quarto.yml` file. + +For example, if you have a project with English as the main language and French as an additional language. When rendering the main English language, {babelquarto} will load the *en* profile and the *fr* profile when rendering the French version. + +You could for example have different navigation menus for each language: + +```{.yaml filename="_quarto-en.yml"} +website: + navbar: + title: "My Website" + left: + - label: "Home" + href: "index.qmd" + right: + - label: "About" + href: "about.qmd" +``` + +```yaml +website: + navbar: + title: "Mon site web" + left: + - label: "Accueil" + href: "index.qmd" + right: + - label: "À propos" + href: "about.qmd" +``` + +Profiles allow for advanced configuration, but a careful read of the [profiles documentation](https://quarto.org/docs/projects/profiles.html) is recommended. The main `_quarto.yml` file will be merged with the profile options and this often needs a careful planning of what keys are put in the different configuration files. + +### Additional profiles + +For complex project, you might want to use additional profiles. When you render a project, you can pass a `profile` argument to `render_book()` and `render_website()` to use additional profiles. The profile will be merged with the main `_quarto.yml` and the language profile. From d5c1333ee4ffc2d08bc91cdf7361f4502e48670a Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Wed, 18 Sep 2024 22:36:51 +0200 Subject: [PATCH 06/29] docs: vignette Render with CI --- vignettes/render-with-ci.qmd | 95 ++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 vignettes/render-with-ci.qmd diff --git a/vignettes/render-with-ci.qmd b/vignettes/render-with-ci.qmd new file mode 100644 index 0000000..83b79bd --- /dev/null +++ b/vignettes/render-with-ci.qmd @@ -0,0 +1,95 @@ +--- +title: "Render with CI" +description: > + How to render with CI +vignette: > + %\VignetteIndexEntry{Render with CI} + %\VignetteEngine{quarto::html} + %\VignetteEncoding{UTF-8} +--- + +If you want to render and publish your multilingual book or website with CI, you must render your project with `render_book()` or `render_website()`, respectively. Don't use Quarto's own render and publish steps. + +## Github Actions and Github Pages + +If you want to use GitHub Pages to deploy your website, use the Quarto CLI to setup the branch for you: + +```bash +quarto publish gh-pages +``` + +This will create a new branch called `gh-pages` in your repository. **Note: as your project was rendered using `quarto render` it won't be multilingual yet.** + +You can then setup your GitHub Actions. In your repository in `.github/workflows/` create a file named `publish.yml` with the following content. +Make sure you set the correct url for the environment variable `BABELQUARTO_CI_URL`. This is used as `site-url` parameter in a CI context. + +### Multilingual Book + + + +```yaml +name: Render Book +on: + push: + branches: main +jobs: + render: + runs-on: ubuntu-latest + env: + BABELQUARTO_CI_URL: https://nenuial.github.io/babelbook/ + permissions: + contents: write + steps: + - uses: actions/checkout@v2 + - uses: r-lib/actions/setup-r@v1 + - uses: r-lib/actions/setup-pandoc@v1 + - name: Set up R dependencies + uses: r-lib/actions/setup-r-dependencies@v2 + with: + packages: | + github::ropensci-review-tools/babelquarto + - name: Render Book with babelquarto + run: Rscript -e 'babelquarto::render_book()' + - name: Publish + uses: quarto-dev/quarto-actions/publish@v2 + with: + target: gh-pages + render: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +``` + +### Multilingual Website + + +```yaml +name: Render Website +on: + push: + branches: main +jobs: + render: + runs-on: ubuntu-latest + env: + BABELQUARTO_CI_URL: https://nenuial.github.io/babelbook/ + permissions: + contents: write + steps: + - uses: actions/checkout@v2 + - uses: r-lib/actions/setup-r@v1 + - uses: r-lib/actions/setup-pandoc@v1 + - name: Set up R dependencies + uses: r-lib/actions/setup-r-dependencies@v2 + with: + packages: | + github::ropensci-review-tools/babelquarto + - name: Render Book with babelquarto + run: Rscript -e 'babelquarto::render_website()' + - name: Publish + uses: quarto-dev/quarto-actions/publish@v2 + with: + target: gh-pages + render: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +``` From 62bde707efcc30142716497e8c79726ccd824f3d Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Wed, 18 Sep 2024 22:44:25 +0200 Subject: [PATCH 07/29] chore: linting --- .lintr | 5 ++++- vignettes/babelquarto.qmd | 17 ++++++++++------- vignettes/configuration.qmd | 9 +++++---- vignettes/convert.qmd | 4 +--- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/.lintr b/.lintr index bfcb9a4..56c975a 100644 --- a/.lintr +++ b/.lintr @@ -2,5 +2,8 @@ linters: lintr::linters_with_tags(tags = NULL, indentation_linter = NULL) encoding: "UTF-8" exclusions: list( # excluded from all lints: - "tests/testthat.R" + "tests/testthat.R", + "vignettes/babelquarto.qmd" = list( + undesirable_function_linter = Inf ) + ) diff --git a/vignettes/babelquarto.qmd b/vignettes/babelquarto.qmd index 03405d7..3805d8a 100644 --- a/vignettes/babelquarto.qmd +++ b/vignettes/babelquarto.qmd @@ -41,7 +41,10 @@ To start with a multilingual book, use `quarto_multilingual_book()` with the `pa #| results: 'hide' parent_dir <- withr::local_tempdir() project_dir <- "multilingual_book" -quarto_multilingual_book(parent_dir = parent_dir, project_dir = project_dir) +quarto_multilingual_book( + parent_dir = parent_dir, + project_dir = project_dir +) ``` Look at the `_quarto.yml` file in the project directory. To get familiar with the configuration, take a look at the example below: @@ -51,10 +54,8 @@ Look at the `_quarto.yml` file in the project directory. To get familiar with th #| echo: false #| results: 'asis' -# Awaiting r-lib/pkgdown#2776 -# cat("```{.yaml filename='_quarto.yml'}\n") cat("```yaml\n") -readLines(file.path(parent_dir, project_dir, "_quarto.yml")) |> +readLines(file.path(parent_dir, project_dir, "_quarto.yml")) |> cat(sep = "\n") cat("```\n") ``` @@ -88,7 +89,10 @@ To start a multilingual website, use `quarto_multilingual_website()` with the `p #| results: 'hide' parent_dir <- withr::local_tempdir() project_dir <- "multilingual_website" -babelquarto::quarto_multilingual_website(parent_dir = parent_dir, project_dir = project_dir) +babelquarto::quarto_multilingual_website( + parent_dir = parent_dir, + project_dir = project_dir +) ``` Look at the `_quarto.yml` file in the project directory. To get familiar with the configuration, take a look at the example below: @@ -98,9 +102,8 @@ Look at the `_quarto.yml` file in the project directory. To get familiar with th #| echo: false #| results: 'asis' -# cat("```{.yaml filename='_quarto.yml'}\n") cat("```yaml\n") -readLines(file.path(parent_dir, project_dir, "_quarto.yml")) |> +readLines(file.path(parent_dir, project_dir, "_quarto.yml")) |> cat(sep = "\n") cat("```\n") ``` diff --git a/vignettes/configuration.qmd b/vignettes/configuration.qmd index 588bf01..7134177 100644 --- a/vignettes/configuration.qmd +++ b/vignettes/configuration.qmd @@ -18,15 +18,16 @@ When you start a {babelquarto} project, from scratch or from an existing project #| results: 'asis' parent_dir <- withr::local_tempdir() project_dir <- "multilingual_book" -book <- babelquarto::quarto_multilingual_book(parent_dir = parent_dir, project_dir = project_dir) +book <- babelquarto::quarto_multilingual_book( + parent_dir = parent_dir, + project_dir = project_dir +) config_path <- file.path(parent_dir, project_dir, "_quarto.yml") config_lines <- brio::read_lines(config_path) where_babelquarto <- grep("babelquarto:", config_lines, fixed = TRUE) -# Awaiting r-lib/pkgdown#2776 -# cat("```{.yaml filename='_quarto.yml'}\n") cat("```yaml\n") -config_lines[where_babelquarto:length(config_lines)] |> +config_lines[where_babelquarto:length(config_lines)] |> cat(sep = "\n") cat("```\n") ``` diff --git a/vignettes/convert.qmd b/vignettes/convert.qmd index aeb4949..6fc3e56 100644 --- a/vignettes/convert.qmd +++ b/vignettes/convert.qmd @@ -50,10 +50,8 @@ We end up with a multilingual book in English and Spanish. If you look at the `_ #| echo: false #| results: 'asis' -# Awaiting r-lib/pkgdown#2776 -#cat("```{.yaml filename='_quarto.yml'}\n") cat("```yaml\n") -readLines(file.path(parent_dir, project_dir, "_quarto.yml")) |> +readLines(file.path(parent_dir, project_dir, "_quarto.yml")) |> cat(sep = "\n") cat("```\n") ``` From e35df48bf75a3051dff0ed3276e50292c7d621ca Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Wed, 18 Sep 2024 23:03:01 +0200 Subject: [PATCH 08/29] docs: fix configuration vignette index entry --- vignettes/configuration.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/configuration.qmd b/vignettes/configuration.qmd index 7134177..29acaa4 100644 --- a/vignettes/configuration.qmd +++ b/vignettes/configuration.qmd @@ -1,7 +1,7 @@ --- title: "Configuration" vignette: > - %\VignetteIndexEntry{Get started} + %\VignetteIndexEntry{Configuration} %\VignetteEngine{quarto::html} %\VignetteEncoding{UTF-8} --- From bb55ac824902768450eab37a1e56729f67d32ff4 Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Thu, 19 Sep 2024 07:50:42 +0200 Subject: [PATCH 09/29] chore: fix windows CI --- vignettes/babelquarto.qmd | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/vignettes/babelquarto.qmd b/vignettes/babelquarto.qmd index 3805d8a..862a529 100644 --- a/vignettes/babelquarto.qmd +++ b/vignettes/babelquarto.qmd @@ -26,12 +26,6 @@ Or from [GitHub](https://github.com/) with: pak::pak("ropensci-review-tools/babelquarto") ``` -Load the babelquarto package: - -```{r} -library(babelquarto) -``` - ## Starting a multilingual book To start with a multilingual book, use `quarto_multilingual_book()` with the `parent_dir` argument to specify where you want to create the project and the `project_dir` argument to specify the name of the project. @@ -41,7 +35,7 @@ To start with a multilingual book, use `quarto_multilingual_book()` with the `pa #| results: 'hide' parent_dir <- withr::local_tempdir() project_dir <- "multilingual_book" -quarto_multilingual_book( +babelquarto::quarto_multilingual_book( parent_dir = parent_dir, project_dir = project_dir ) From b973338325be5775f46f93f4d31455cea3101e93 Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Thu, 19 Sep 2024 17:38:18 +0200 Subject: [PATCH 10/29] docs: apply review suggestions to babelquarto vignette --- vignettes/babelquarto.qmd | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/vignettes/babelquarto.qmd b/vignettes/babelquarto.qmd index 862a529..287fcf0 100644 --- a/vignettes/babelquarto.qmd +++ b/vignettes/babelquarto.qmd @@ -6,8 +6,8 @@ vignette: > %\VignetteEncoding{UTF-8} --- -The goal of this vignette is to show how you can start a new multilingual Quarto project using {babelquarto}. -There are two types of project you can start: a book or a website. We will look at each type seperately below. +The goal of this vignette is to show how you can start and maintain a new multilingual Quarto project using {babelquarto}. +There are two types of projects: a book or a website. We will look at each type separately below. If you want to turn an existing project into a multilingual project, have a look at `vignette("convert")`. @@ -41,7 +41,8 @@ babelquarto::quarto_multilingual_book( ) ``` -Look at the `_quarto.yml` file in the project directory. To get familiar with the configuration, take a look at the example below: +Look at the `_quarto.yml` file in the project directory. +To get familiar with the configuration, take a look at the example below: ```{r} #| label: display_book_config @@ -109,9 +110,10 @@ The file structure of the project looks like this: fs::dir_tree(file.path(parent_dir, project_dir)) ``` -Each quarto file has a spanish and a french translation. If you look at the `index.qmd` file, you'll see that the french translation is `index.fr.qmd` and the spanish translation is `index.es.qmd`. +Each Quarto file has a Spanish and a French translation. +If you look at the `index.qmd` file, you'll see that the French translation is `index.fr.qmd` and the Spanish translation is `index.es.qmd`. -When you're ready to render your website, use `render_website()`: +When you're ready to render your website, use `babelquarto::render_website()`: ```{r} #| label: render_website From 97ea75ca7261fd8b46e91ec774f77b6f1833b7f5 Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Thu, 19 Sep 2024 17:39:40 +0200 Subject: [PATCH 11/29] docs: apply review suggestions to configuration vignette --- vignettes/configuration.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/configuration.qmd b/vignettes/configuration.qmd index 29acaa4..3388a3e 100644 --- a/vignettes/configuration.qmd +++ b/vignettes/configuration.qmd @@ -98,7 +98,7 @@ For each additional language, you can use a `part-xx` key to translate the part ## Using profiles for advanced configuration -For more advanced customalization, you can use [Quarto project profiles](https://quarto.org/docs/projects/profiles.html). In {babelquarto} we will automatically load a profile if it exists in the project directory. Profile configuration are **merged** with the main `_quarto.yml` file. +For more advanced customization, you can use [Quarto project profiles](https://quarto.org/docs/projects/profiles.html). In {babelquarto} we will automatically load a language profile if it exists in the project directory and follows our naming convention. Profile configuration are **merged** with the main `_quarto.yml` file. For example, if you have a project with English as the main language and French as an additional language. When rendering the main English language, {babelquarto} will load the *en* profile and the *fr* profile when rendering the French version. From fbe826455078adafa2ff693e15c2d8a32c17f860 Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Thu, 19 Sep 2024 17:46:18 +0200 Subject: [PATCH 12/29] docs: add link to babeldown in the next steps sections --- vignettes/babelquarto.qmd | 2 ++ vignettes/convert.qmd | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/vignettes/babelquarto.qmd b/vignettes/babelquarto.qmd index 287fcf0..9f0f4ba 100644 --- a/vignettes/babelquarto.qmd +++ b/vignettes/babelquarto.qmd @@ -142,4 +142,6 @@ servr::httw("_book") Take a deeper dive into the configuration options available in {babelquarto} you can have a look at `vignette("configuration")`. +If you want to translate your multilingual project using automatic translation with DeepL, you should have a look at [babeldown](http://docs.ropensci.org/babeldown/articles/quarto.html). + If you want to setup your own CI and deploy your website, have a look at `vignette("render-with-ci")`. diff --git a/vignettes/convert.qmd b/vignettes/convert.qmd index 6fc3e56..bfc8bbe 100644 --- a/vignettes/convert.qmd +++ b/vignettes/convert.qmd @@ -60,4 +60,6 @@ cat("```\n") Take a deeper dive into the configuration options available in {babelquarto} you can have a look at `vignette("configuration")`. -If you want to setup your own CI and deploy your website, have a look at `vignette("render-with-ci")`. +If you want to translate your multilingual project using automatic translation with DeepL, you should have a look at [babeldown](http://docs.ropensci.org/babeldown/articles/quarto.html). + +If you want to deploy your website on continuous integration, have a look at `vignette("render-with-ci")`. From 6f42ffb36b139df16d18b28508c2aedecc7f9490 Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Thu, 19 Sep 2024 17:48:55 +0200 Subject: [PATCH 13/29] docs: apply review suggestions to render-with-ci vignette --- vignettes/render-with-ci.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/render-with-ci.qmd b/vignettes/render-with-ci.qmd index 83b79bd..d8df6cf 100644 --- a/vignettes/render-with-ci.qmd +++ b/vignettes/render-with-ci.qmd @@ -1,5 +1,5 @@ --- -title: "Render with CI" +title: "Render with continuous integration (CI)" description: > How to render with CI vignette: > From 63ae254fefdac14e9156d51e7b4fa295ad4c639a Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Thu, 19 Sep 2024 17:53:29 +0200 Subject: [PATCH 14/29] docs: mention quarto preview in the previewing part --- vignettes/babelquarto.qmd | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/vignettes/babelquarto.qmd b/vignettes/babelquarto.qmd index 9f0f4ba..fc11e11 100644 --- a/vignettes/babelquarto.qmd +++ b/vignettes/babelquarto.qmd @@ -125,7 +125,10 @@ We end up with a multilingual website. [Example](https://maelle.github.io/babels ## Previewing your multilingual project -Once you have rendered your project, you will have a `_site` or `_book` folder in your project. To easily preview your project, can use the [`servr` package](https://cran.rstudio.com/web/packages/servr/index.html). +Once you have rendered your project, you will have a `_site` or `_book` folder in your project. +In Quarto you would use `quarto preview` to be able to get a look at what you project looks like. +Because of the way {babelquarto} operates, this isn't possible. +You can however preview your files using the [{servr} package](https://cran.rstudio.com/web/packages/servr/index.html). You can use `servr::httw()` to preview your project. From 1a1f5652de647b64bdf08972f33acfb44d5d7bd4 Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Thu, 19 Sep 2024 18:10:54 +0200 Subject: [PATCH 15/29] docs: make sure people understand that babelquarto doesn't translate --- vignettes/babelquarto.qmd | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/vignettes/babelquarto.qmd b/vignettes/babelquarto.qmd index fc11e11..28cd377 100644 --- a/vignettes/babelquarto.qmd +++ b/vignettes/babelquarto.qmd @@ -62,7 +62,10 @@ The file structure of the project looks like this: fs::dir_tree(file.path(parent_dir, project_dir)) ``` -Each quarto file has a spanish and a french translation. If you look at the `index.qmd` file, you'll see that the french translation is `index.fr.qmd` and the spanish translation is `index.es.qmd`. +Each Quarto file has a Spanish and a French version. +These files aren't automatically translated and are just copies of the original English version. +You will have to provide the translations yourself, or look at {[babeldown](https://docs.ropensci.org/babeldown/)} for automatic translation. +If you look at the `index.qmd` file, you'll see that the French file is called `index.fr.qmd` and the Spanish file is called `index.es.qmd`. When you're ready to render your book, use `render_book()`: @@ -110,8 +113,10 @@ The file structure of the project looks like this: fs::dir_tree(file.path(parent_dir, project_dir)) ``` -Each Quarto file has a Spanish and a French translation. -If you look at the `index.qmd` file, you'll see that the French translation is `index.fr.qmd` and the Spanish translation is `index.es.qmd`. +Each Quarto file has a Spanish and a French version. +These files aren't automatically translated and are just copies of the original English version. +You will have to provide the translations yourself, or look at {[babeldown](https://docs.ropensci.org/babeldown/)} for automatic translation. +If you look at the `index.qmd` file, you'll see that the French file is called `index.fr.qmd` and the Spanish file is called `index.es.qmd`. When you're ready to render your website, use `babelquarto::render_website()`: From d2c2b0c6fd3eb1d881b31d5f251cef27815f2257 Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Thu, 19 Sep 2024 18:10:54 +0200 Subject: [PATCH 16/29] docs: add `main_language` and `further_languages` to book and website examples --- vignettes/babelquarto.qmd | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/vignettes/babelquarto.qmd b/vignettes/babelquarto.qmd index 28cd377..83b3ebe 100644 --- a/vignettes/babelquarto.qmd +++ b/vignettes/babelquarto.qmd @@ -28,7 +28,8 @@ pak::pak("ropensci-review-tools/babelquarto") ## Starting a multilingual book -To start with a multilingual book, use `quarto_multilingual_book()` with the `parent_dir` argument to specify where you want to create the project and the `project_dir` argument to specify the name of the project. +To start a multilingual book, use `quarto_multilingual_book()` with the `parent_dir` argument to specify where you want to create the project and the `project_dir` argument to specify the name of the project. +The argument `main_language` is used to specify the main language of the project and `further_languages` lists all additional languages. ```{r} #| label: setup_book @@ -37,7 +38,9 @@ parent_dir <- withr::local_tempdir() project_dir <- "multilingual_book" babelquarto::quarto_multilingual_book( parent_dir = parent_dir, - project_dir = project_dir + project_dir = project_dir, + main_language = "en", + further_languages = c("es", "fr") ) ``` @@ -81,6 +84,7 @@ We end up with three books, that cross-link to each other from the left sidebar. ## Starting a multilingual website To start a multilingual website, use `quarto_multilingual_website()` with the `parent_dir` argument to specify where you want to create the project and the `project_dir` argument to specify the name of the project. +The argument `main_language` is used to specify the main language of the project and `further_languages` lists all additional languages. ```{r} #| label: setup_website @@ -89,7 +93,9 @@ parent_dir <- withr::local_tempdir() project_dir <- "multilingual_website" babelquarto::quarto_multilingual_website( parent_dir = parent_dir, - project_dir = project_dir + project_dir = project_dir, + main_language = "en", + further_languages = c("es", "fr") ) ``` From df8bd881450695ef43709a40bfdd0cdfe0cc4534 Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Thu, 19 Sep 2024 18:26:07 +0200 Subject: [PATCH 17/29] docs: add more information to main README --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 70c1b21..5ce37a9 100644 --- a/README.md +++ b/README.md @@ -30,5 +30,11 @@ pak::pak("ropensci-review-tools/babelquarto") ## Getting Started -If you are just getting started with {babelquarto}, -you should start by reading the tutorial `vignette("babelquarto")`. +The {babelquarto} package allows you to create a multilingual Quarto project (a book or a website). +A multilingual project is based on a main language and can feature any number of additional languages. +The languages are registered once and are then present in your `_quarto.yml` configuration file under the `babelquarto` key. +Each Quarto markdown file in your project can then be translated into these further languages and these will be used to generate the project in each language. + +If you start from scratch, you might want to look at `babelquarto::quarto_multilingual_book()` or `babelquarto::quarto_multilingual_website()` and read `vignette("babelquarto")`. + +If you already have and existing Quarto project and want to convert it to a multilingual project, you can use `babelquarto::register_main_language()` and `babelquarto::register_further_languages()` to get started. For more information you can read `vignette("convert)`. From 769f55905ecc6e29de52a2a91502308272edc1b3 Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Thu, 19 Sep 2024 19:13:26 +0200 Subject: [PATCH 18/29] chore: fix CI --- .github/workflows/R-CMD-check.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 863c2f3..05c99bd 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -41,9 +41,14 @@ jobs: - uses: r-lib/actions/setup-r-dependencies@v2 with: - extra-packages: any::rcmdcheck + extra-packages: | + any::rcmdcheck + any::devtools needs: check + - run: devtools::install(build_vignettes = FALSE) + shell: Rscript {0} + - uses: r-lib/actions/check-r-package@v2 with: upload-snapshots: true From 1e2d7506cc87998325f6b30592542f371e405c4e Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Fri, 20 Sep 2024 09:17:40 +0200 Subject: [PATCH 19/29] docs: add examples to README --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 5ce37a9..95873a3 100644 --- a/README.md +++ b/README.md @@ -38,3 +38,9 @@ Each Quarto markdown file in your project can then be translated into these furt If you start from scratch, you might want to look at `babelquarto::quarto_multilingual_book()` or `babelquarto::quarto_multilingual_website()` and read `vignette("babelquarto")`. If you already have and existing Quarto project and want to convert it to a multilingual project, you can use `babelquarto::register_main_language()` and `babelquarto::register_further_languages()` to get started. For more information you can read `vignette("convert)`. + +## Examples + +To get a feel of what a multilingual book can look like, you can have a look at this book: [*rOpenSci Packages: Development, Maintenance, and Peer Review*](https://devguide.ropensci.org/). + +For a multilingual website, you can check out [@joelnitta's website](https://www.joelnitta.com/). From 3399eb83c42856f1c95769f223197368ac9a157b Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Fri, 20 Sep 2024 09:18:44 +0200 Subject: [PATCH 20/29] docs: better title for custom language links --- vignettes/configuration.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/configuration.qmd b/vignettes/configuration.qmd index 3388a3e..4d85626 100644 --- a/vignettes/configuration.qmd +++ b/vignettes/configuration.qmd @@ -43,7 +43,7 @@ By default, {babelquarto} will have the following options under the `babelquarto In addition to the `babelquarto` key, you will see language specific keys for `title`, `description` and `author`. These keys allow you to have a specific title, description or author in for each additional language. -### Configure the version text +### Customizing the language menu labels If you want the choice to be between, say "English" and "Español" rather than "Version in EN" and "Version in ES", add these fields under the `babelquarto/languagecodes` key, in `_quarto.yml`: From 72da76b23538fcfc6c23f040d28617ed34200961 Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Wed, 25 Sep 2024 13:32:25 +0200 Subject: [PATCH 21/29] docs: document custom templates with babelquarto --- vignettes/babelquarto.qmd | 2 ++ vignettes/convert.qmd | 2 ++ vignettes/custom-templates.qmd | 41 ++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 vignettes/custom-templates.qmd diff --git a/vignettes/babelquarto.qmd b/vignettes/babelquarto.qmd index 83b3ebe..2ccf5ea 100644 --- a/vignettes/babelquarto.qmd +++ b/vignettes/babelquarto.qmd @@ -159,3 +159,5 @@ Take a deeper dive into the configuration options available in {babelquarto} you If you want to translate your multilingual project using automatic translation with DeepL, you should have a look at [babeldown](http://docs.ropensci.org/babeldown/articles/quarto.html). If you want to setup your own CI and deploy your website, have a look at `vignette("render-with-ci")`. + +If you need to personalize the quarto templates, have a look at `vignette("custom-templates")`. diff --git a/vignettes/convert.qmd b/vignettes/convert.qmd index bfc8bbe..af322eb 100644 --- a/vignettes/convert.qmd +++ b/vignettes/convert.qmd @@ -63,3 +63,5 @@ Take a deeper dive into the configuration options available in {babelquarto} you If you want to translate your multilingual project using automatic translation with DeepL, you should have a look at [babeldown](http://docs.ropensci.org/babeldown/articles/quarto.html). If you want to deploy your website on continuous integration, have a look at `vignette("render-with-ci")`. + +If you need to personalize the quarto templates, have a look at `vignette("custom-templates")`. diff --git a/vignettes/custom-templates.qmd b/vignettes/custom-templates.qmd new file mode 100644 index 0000000..2bb1a6d --- /dev/null +++ b/vignettes/custom-templates.qmd @@ -0,0 +1,41 @@ +--- +title: "Custom templates" +description: > + How to have multilingual parts in your custom templates +vignette: > + %\VignetteIndexEntry{Convert an existing project} + %\VignetteEngine{quarto::html} + %\VignetteEncoding{UTF-8} +--- + +The goal of this vignette is to show how you can have multilingual parts in your custom templates. + +If you need a more advanced way of customizing you project, you can use [Quarto's custom templates](https://quarto.org/docs/journals/templates.html). This allows you to have a more fine-grained control over the render of your pages. + +In order to use the multilingual features of {babelquarto} in your custom templates, we provide a variable for each language rendered in the project. The variable is named `lang-en` for an English render, `lang-fr` for a French render and so on. This allows you to have different content for each language in your custom templates. You can use [pandoc's `$if(lang-en)$` syntax](https://pandoc.org/MANUAL.html#conditionals) to conditionally include content based on the language. + +## Example + +If you want to have a specific metadata block on your webpage, you might want to use the [`medadata.html` partial from Quarto](https://quarto.org/docs/journals/templates.html#html-partials). + +You would configure your `_quarto.yml` file like this: + +``` yaml +format: + html: + template-partials: + - metadata.html +``` + +In your `metadata.html` file, you can use the `lang-en` variable to have a specific metadata block for the English render and the `lang-fr` variable for the French render. The end of the metadata.html template would be: + +``` html + +$if(lang-en)$ + +$endif$ +$if(lang-fr)$ + +$endif$ + +``` From c88e2f6b6ce1afe067742ecb5bddef4ba05e82cc Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Thu, 26 Sep 2024 18:13:08 +0200 Subject: [PATCH 22/29] chore: lintr rules no longer need an exception for the Getting started vignette --- .lintr | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.lintr b/.lintr index 56c975a..ea2d34e 100644 --- a/.lintr +++ b/.lintr @@ -2,8 +2,5 @@ linters: lintr::linters_with_tags(tags = NULL, indentation_linter = NULL) encoding: "UTF-8" exclusions: list( # excluded from all lints: - "tests/testthat.R", - "vignettes/babelquarto.qmd" = list( - undesirable_function_linter = Inf - ) + "tests/testthat.R" ) From d0191594055474d4d7d20e7bd073cc88ed895fa0 Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Thu, 26 Sep 2024 18:15:37 +0200 Subject: [PATCH 23/29] docs: apply review suggestions to README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 95873a3..edefa0a 100644 --- a/README.md +++ b/README.md @@ -30,10 +30,10 @@ pak::pak("ropensci-review-tools/babelquarto") ## Getting Started -The {babelquarto} package allows you to create a multilingual Quarto project (a book or a website). +The {babelquarto} package allows you to create and render a multilingual Quarto project, book or website. A multilingual project is based on a main language and can feature any number of additional languages. The languages are registered once and are then present in your `_quarto.yml` configuration file under the `babelquarto` key. -Each Quarto markdown file in your project can then be translated into these further languages and these will be used to generate the project in each language. +Each Quarto Markdown file in your project can then be translated into these further languages and these will be used to generate the project in each language. If you start from scratch, you might want to look at `babelquarto::quarto_multilingual_book()` or `babelquarto::quarto_multilingual_website()` and read `vignette("babelquarto")`. @@ -43,4 +43,4 @@ If you already have and existing Quarto project and want to convert it to a mult To get a feel of what a multilingual book can look like, you can have a look at this book: [*rOpenSci Packages: Development, Maintenance, and Peer Review*](https://devguide.ropensci.org/). -For a multilingual website, you can check out [@joelnitta's website](https://www.joelnitta.com/). +For a multilingual website, you can check out [Joel Nitta's website](https://www.joelnitta.com/). From e872830e659509146d96baf5e55e88114e5cb14e Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Thu, 26 Sep 2024 18:19:28 +0200 Subject: [PATCH 24/29] docs: apply review suggestions to the Getting started vignette --- vignettes/babelquarto.qmd | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vignettes/babelquarto.qmd b/vignettes/babelquarto.qmd index 2ccf5ea..da6ae68 100644 --- a/vignettes/babelquarto.qmd +++ b/vignettes/babelquarto.qmd @@ -79,7 +79,7 @@ babelquarto::render_book(file.path(parent_dir, project_dir)) ``` We end up with three books, that cross-link to each other from the left sidebar. -[Example](https://devdevguide.netlify.app). +[Example](https://devguide.ropensci.org/). ## Starting a multilingual website @@ -152,6 +152,8 @@ servr::httw("_site") servr::httw("_book") ``` +This will show an URL that you can open in your IDE or browser to see your project. + ## Next steps Take a deeper dive into the configuration options available in {babelquarto} you can have a look at `vignette("configuration")`. @@ -160,4 +162,4 @@ If you want to translate your multilingual project using automatic translation w If you want to setup your own CI and deploy your website, have a look at `vignette("render-with-ci")`. -If you need to personalize the quarto templates, have a look at `vignette("custom-templates")`. +If you need to personalize the Quarto templates, have a look at `vignette("custom-templates")`. From cecfe473808e466c4ae571885e205a66d727edf0 Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Thu, 26 Sep 2024 18:21:02 +0200 Subject: [PATCH 25/29] docs: apply review suggestions to the Configuration vignette --- vignettes/configuration.qmd | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/vignettes/configuration.qmd b/vignettes/configuration.qmd index 4d85626..3a7e735 100644 --- a/vignettes/configuration.qmd +++ b/vignettes/configuration.qmd @@ -98,9 +98,12 @@ For each additional language, you can use a `part-xx` key to translate the part ## Using profiles for advanced configuration -For more advanced customization, you can use [Quarto project profiles](https://quarto.org/docs/projects/profiles.html). In {babelquarto} we will automatically load a language profile if it exists in the project directory and follows our naming convention. Profile configuration are **merged** with the main `_quarto.yml` file. +For more advanced customization, you can use [Quarto project profiles](https://quarto.org/docs/projects/profiles.html). +In {babelquarto} we will automatically load a language profile if it exists in the project directory and follows our naming convention. +Profile configuration are **merged** with the main `_quarto.yml` file. -For example, if you have a project with English as the main language and French as an additional language. When rendering the main English language, {babelquarto} will load the *en* profile and the *fr* profile when rendering the French version. +For example, let's say you have a project with English as the main language and French as an additional language. +When rendering the main English language, {babelquarto} will load the *en* profile and the *fr* profile when rendering the French version. You could for example have different navigation menus for each language: @@ -128,7 +131,8 @@ website: href: "about.qmd" ``` -Profiles allow for advanced configuration, but a careful read of the [profiles documentation](https://quarto.org/docs/projects/profiles.html) is recommended. The main `_quarto.yml` file will be merged with the profile options and this often needs a careful planning of what keys are put in the different configuration files. +Profiles allow for advanced configuration, but a careful read of the [profiles documentation](https://quarto.org/docs/projects/profiles.html) is recommended. +The main `_quarto.yml` file will be merged with the profile options and this often needs a careful planning of what keys are put in the different configuration files. ### Additional profiles From 35c71da297f86f253fbb63d9653b43e9321864dc Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Thu, 26 Sep 2024 18:27:10 +0200 Subject: [PATCH 26/29] docs: apply review suggestions to the Convert vignette --- vignettes/convert.qmd | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/vignettes/convert.qmd b/vignettes/convert.qmd index af322eb..423958e 100644 --- a/vignettes/convert.qmd +++ b/vignettes/convert.qmd @@ -56,12 +56,16 @@ readLines(file.path(parent_dir, project_dir, "_quarto.yml")) |> cat("```\n") ``` +You can now start translating your book into Spanish and French. Each file of you project can be translated by adding a suffix to the file name. +For example, the Spanish version of `index.md` will be in `index.es.md` and the French version in `index.fr.md`. + +You will have to provide the translations yourself. +If you want to translate your multilingual project using automatic translation with DeepL, you should have a look at [babeldown](http://docs.ropensci.org/babeldown/articles/quarto.html). + ## Next steps Take a deeper dive into the configuration options available in {babelquarto} you can have a look at `vignette("configuration")`. -If you want to translate your multilingual project using automatic translation with DeepL, you should have a look at [babeldown](http://docs.ropensci.org/babeldown/articles/quarto.html). - If you want to deploy your website on continuous integration, have a look at `vignette("render-with-ci")`. If you need to personalize the quarto templates, have a look at `vignette("custom-templates")`. From 7ee68b3713639dc7f73b30cdf60a0adbe3431360 Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Thu, 26 Sep 2024 18:28:56 +0200 Subject: [PATCH 27/29] docs: apply review suggestions to Custom templates vignette --- vignettes/custom-templates.qmd | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/vignettes/custom-templates.qmd b/vignettes/custom-templates.qmd index 2bb1a6d..82e5f39 100644 --- a/vignettes/custom-templates.qmd +++ b/vignettes/custom-templates.qmd @@ -10,9 +10,13 @@ vignette: > The goal of this vignette is to show how you can have multilingual parts in your custom templates. -If you need a more advanced way of customizing you project, you can use [Quarto's custom templates](https://quarto.org/docs/journals/templates.html). This allows you to have a more fine-grained control over the render of your pages. +If you need a more advanced way of customizing you project, you can use [Quarto's custom templates](https://quarto.org/docs/journals/templates.html). +This allows you to have a more fine-grained control over the render of your pages. -In order to use the multilingual features of {babelquarto} in your custom templates, we provide a variable for each language rendered in the project. The variable is named `lang-en` for an English render, `lang-fr` for a French render and so on. This allows you to have different content for each language in your custom templates. You can use [pandoc's `$if(lang-en)$` syntax](https://pandoc.org/MANUAL.html#conditionals) to conditionally include content based on the language. +In order to use the multilingual features of {babelquarto} in your custom templates, we provide a variable for each language rendered in the project. +The variable is named `lang-en` for an English render, `lang-fr` for a French render and so on. +This allows you to have different content for each language in your custom templates. +You can use [pandoc's `$if(lang-en)$` syntax](https://pandoc.org/MANUAL.html#conditionals) to conditionally include content based on the language. ## Example From 8e8daa94258b1048bd5ad86b61944fae5e001eb6 Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Thu, 26 Sep 2024 18:44:06 +0200 Subject: [PATCH 28/29] docs: rewrite the Render with CI vignette completely --- vignettes/render-with-ci.qmd | 93 ++++++------------------------------ 1 file changed, 15 insertions(+), 78 deletions(-) diff --git a/vignettes/render-with-ci.qmd b/vignettes/render-with-ci.qmd index d8df6cf..a8988ac 100644 --- a/vignettes/render-with-ci.qmd +++ b/vignettes/render-with-ci.qmd @@ -1,95 +1,32 @@ --- title: "Render with continuous integration (CI)" description: > - How to render with CI + How to render with continuous integration vignette: > %\VignetteIndexEntry{Render with CI} %\VignetteEngine{quarto::html} %\VignetteEncoding{UTF-8} --- -If you want to render and publish your multilingual book or website with CI, you must render your project with `render_book()` or `render_website()`, respectively. Don't use Quarto's own render and publish steps. +If you want to render and publish your multilingual book or website with CI, you must render your project with `render_book()` or `render_website()`, respectively. +Don't use Quarto's own render and publish steps. +You can find more information about publishing with CI in the [Quarto documentation](https://quarto.org/docs/publishing/ci.html). -## Github Actions and Github Pages +### Site URL -If you want to use GitHub Pages to deploy your website, use the Quarto CLI to setup the branch for you: +When you render a project in a CI context, you need to set the URL of the publishing website in an environement variable. +You can do that with the `BABELQUARTO_CI_URL` environment variable. -```bash -quarto publish gh-pages -``` +### Steps for rendering -This will create a new branch called `gh-pages` in your repository. **Note: as your project was rendered using `quarto render` it won't be multilingual yet.** +To render your project with CI, you need to follow these general steps: -You can then setup your GitHub Actions. In your repository in `.github/workflows/` create a file named `publish.yml` with the following content. -Make sure you set the correct url for the environment variable `BABELQUARTO_CI_URL`. This is used as `site-url` parameter in a CI context. +* Install the necessary dependencies including Quarto and R dependencies +* Render you project using {babelquarto}'s `render_book()` or `render_website()` functions +* Publish the rendered HTML (_site or _book folder) where you deploy your project (a GitHub pages branch, Netlify, etc.) -### Multilingual Book +## Example - - -```yaml -name: Render Book -on: - push: - branches: main -jobs: - render: - runs-on: ubuntu-latest - env: - BABELQUARTO_CI_URL: https://nenuial.github.io/babelbook/ - permissions: - contents: write - steps: - - uses: actions/checkout@v2 - - uses: r-lib/actions/setup-r@v1 - - uses: r-lib/actions/setup-pandoc@v1 - - name: Set up R dependencies - uses: r-lib/actions/setup-r-dependencies@v2 - with: - packages: | - github::ropensci-review-tools/babelquarto - - name: Render Book with babelquarto - run: Rscript -e 'babelquarto::render_book()' - - name: Publish - uses: quarto-dev/quarto-actions/publish@v2 - with: - target: gh-pages - render: false - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -``` +Here's an example of how you could render a multilingual book with CI using GitHub Actions: -### Multilingual Website - - -```yaml -name: Render Website -on: - push: - branches: main -jobs: - render: - runs-on: ubuntu-latest - env: - BABELQUARTO_CI_URL: https://nenuial.github.io/babelbook/ - permissions: - contents: write - steps: - - uses: actions/checkout@v2 - - uses: r-lib/actions/setup-r@v1 - - uses: r-lib/actions/setup-pandoc@v1 - - name: Set up R dependencies - uses: r-lib/actions/setup-r-dependencies@v2 - with: - packages: | - github::ropensci-review-tools/babelquarto - - name: Render Book with babelquarto - run: Rscript -e 'babelquarto::render_website()' - - name: Publish - uses: quarto-dev/quarto-actions/publish@v2 - with: - target: gh-pages - render: false - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -``` +[Babelbook](https://nenuial.github.io/babelbook/) and [source code](https://github.com/Nenuial/babelbook). From ad47623b88ec4ba70d9eb9c62d914b0aeef1cdd4 Mon Sep 17 00:00:00 2001 From: Pascal Burkhard Date: Fri, 27 Sep 2024 20:43:25 +0200 Subject: [PATCH 29/29] docs: add a second example for CI render --- vignettes/render-with-ci.qmd | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vignettes/render-with-ci.qmd b/vignettes/render-with-ci.qmd index a8988ac..cf367bc 100644 --- a/vignettes/render-with-ci.qmd +++ b/vignettes/render-with-ci.qmd @@ -27,6 +27,7 @@ To render your project with CI, you need to follow these general steps: ## Example -Here's an example of how you could render a multilingual book with CI using GitHub Actions: +Here are two examplee of how you could render a multilingual book with CI using GitHub Actions: -[Babelbook](https://nenuial.github.io/babelbook/) and [source code](https://github.com/Nenuial/babelbook). +* A demo [Babelbook](https://nenuial.github.io/babelbook/) with its [workflow file](https://github.com/Nenuial/babelbook/blob/main/.github/workflows/publish.yml) +* The [rOpenSci Packages: Development, Maintenance, and Peer Review](https://devguide.ropensci.org/index.html) book with its [workflow file](https://github.com/ropensci/dev_guide/blob/main/.github/workflows/scheduled-manual-main.yml)