diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml index d26eb64f..ed72938b 100644 --- a/.github/workflows/website.yml +++ b/.github/workflows/website.yml @@ -9,15 +9,10 @@ on: push: branches: - master - - website* paths: - 'website/**' - '.github/workflows/website.yml' workflow_dispatch: # useful for testing tx pushes - workflow_call: - -permissions: - contents: write defaults: run: @@ -39,7 +34,9 @@ jobs: python-version: '3.10' - name: Install Python requirements - run: pip install -r requirements.txt + run: | + pip install -r requirements.txt + pip install -r requirements-dev.txt - name: Install Python requirements insiders run: pip install -r requirements-insiders.txt @@ -52,6 +49,9 @@ jobs: curl -OL https://github.com/transifex/cli/releases/download/v1.6.10/tx-linux-amd64.tar.gz tar -xvzf tx-linux-amd64.tar.gz + - name: Extract translatable content from mkdocs.yml config + run: ./scripts/mkdocs_tx.py create_source + - name: Configure Transifex run: scripts/transifex_utils.py env: @@ -64,13 +64,21 @@ jobs: TX_TOKEN: ${{ secrets.TX_TOKEN }} - name: Pull translations from Transifex - if: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name == 'opengisch/signalo' && github.actor != 'dependabot[bot]' }} + if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.full_name == 'opengisch/signalo' && github.actor != 'dependabot[bot]' }} run: | ./tx pull --translations --all --minimum-perc 10 ./tx status env: TX_TOKEN: ${{ secrets.TX_TOKEN }} + - name: Translate Mkdocs config + if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.full_name == 'opengisch/signalo' && github.actor != 'dependabot[bot]' }} + run: | + ./scripts/mkdocs_tx.py -s fr update_config + ./scripts/mkdocs_tx_commit.sh + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Build documentation run: mkdocs build diff --git a/website/.tx/config b/website/.tx/config index 33c329bc..7616e9ce 100644 --- a/website/.tx/config +++ b/website/.tx/config @@ -1,50 +1,2 @@ [main] host = https://www.transifex.com - -[o:opengisch:p:signalo-website:r:documentation_desktop] -file_filter = documentation/desktop..md -source_file = documentation/desktop.fr.md -source_lang = fr -type = GITHUBMARKDOWN - -[o:opengisch:p:signalo-website:r:documentation_roadmap] -file_filter = documentation/roadmap..md -source_file = documentation/roadmap.fr.md -source_lang = fr -type = GITHUBMARKDOWN - -[o:opengisch:p:signalo-website:r:documentation_mobile] -file_filter = documentation/mobile..md -source_file = documentation/mobile.fr.md -source_lang = fr -type = GITHUBMARKDOWN - -[o:opengisch:p:signalo-website:r:documentation_installation] -file_filter = documentation/installation..md -source_file = documentation/installation.fr.md -source_lang = fr -type = GITHUBMARKDOWN - -[o:opengisch:p:signalo-website:r:documentation_home] -file_filter = documentation/index..md -source_file = documentation/index.fr.md -source_lang = fr -type = GITHUBMARKDOWN - -[o:opengisch:p:signalo-website:r:documentation_datamodel-doc] -file_filter = documentation/datamodel-doc..md -source_file = documentation/datamodel-doc.fr.md -source_lang = fr -type = GITHUBMARKDOWN - -[o:opengisch:p:signalo-website:r:documentation_data-model] -file_filter = documentation/data-model..md -source_file = documentation/data-model.fr.md -source_lang = fr -type = GITHUBMARKDOWN - -[o:opengisch:p:signalo-website:r:documentation_contribute] -file_filter = documentation/contribute..md -source_file = documentation/contribute.fr.md -source_lang = fr -type = GITHUBMARKDOWN diff --git a/website/mkdocs.yml b/website/mkdocs.yml index 4bbf9da1..e3bc484b 100644 --- a/website/mkdocs.yml +++ b/website/mkdocs.yml @@ -112,14 +112,14 @@ plugins: toggle: icon: material/brightness-auto name: Wechseln Sie in den Lichtmodus - # Palette toggle for light mode + # Palette toggle for light mode - media: "(prefers-color-scheme: light)" scheme: default primary: grey toggle: icon: material/brightness-7 name: Wechseln Sie in den Dunkelmodus - # Palette toggle for dark mode + # Palette toggle for dark mode - media: "(prefers-color-scheme: dark)" scheme: slate primary: grey diff --git a/website/requirements-dev.txt b/website/requirements-dev.txt new file mode 100644 index 00000000..f3d7632e --- /dev/null +++ b/website/requirements-dev.txt @@ -0,0 +1,2 @@ +ruamel.yaml==0.18.6 +pre-commit==3.6.2 diff --git a/website/scripts/mkdocs_tx.py b/website/scripts/mkdocs_tx.py new file mode 100755 index 00000000..6712514a --- /dev/null +++ b/website/scripts/mkdocs_tx.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python + +import argparse +import copy + +from ruamel.yaml import YAML + +# This scripts helps with translatable content from mkdocs.yml +# It provides commands: +# * to create the YAML translatable file +# * to update the mkdocs.yml with the translated content + + +def read_config(file_path: str): + yaml = YAML(typ="rt") + yaml.preserve_quotes = True + with open(file_path) as f: + return yaml.load(f) + + +def create_translation_source(config_path, source_path): + config = read_config(config_path) + + nav_config = [] + for _entry in config["nav"]: + nav_config.append({v: k for k, v in _entry.items()}) + + tx_cfg = {"nav": nav_config} + + try: + tx_cfg["theme"] = {"palette": []} + for palette in config["theme"]["palette"]: + tx_cfg["theme"]["palette"].append( + {"toggle": {"name": palette["toggle"]["name"]}} + ) + except KeyError: + print("No theme/palette/toggle/name to translate") + + with open(source_path, "w") as f: + yaml = YAML() + yaml.dump(tx_cfg, f) + + +def update_config(config_path, source_path, source_language): + config = read_config(config_path) + + nav_config = {} + for _entry in config["nav"]: + for title, page in _entry.items(): + nav_config[page] = title + + found = False + for plugin in config["plugins"]: + if type(plugin) != str and "i18n" in plugin: + found = True + for lang in plugin["i18n"]["languages"]: + ltx = lang["locale"] + print(f"language found: '{ltx}'") + + if ltx == source_language: + print("skipping source language") + continue + + tx_file = f'{source_path.removesuffix(".yml")}.{ltx}.yml' + with open(tx_file) as f: + yaml = YAML() + tx = yaml.load(f) + + for nav_entry in tx["nav"]: + for page, title in nav_entry.items(): + source_language_tile = nav_config[page] + if title: + lang["nav_translations"][source_language_tile] = title + + try: + lang["palette"] = copy.deepcopy(config["theme"]["palette"]) + i = 0 + for palette in tx["theme"]["palette"]: + lang["palette"][i]["toggle"]["name"] = palette["toggle"][ + "name" + ] + i += 1 + except KeyError: + print("No theme/palette/toggle/name to translate") + + assert found + + with open(config_path, "w") as f: + yaml = YAML() + yaml.indent(mapping=2, sequence=4, offset=2) + yaml.dump(config, f) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument( + "-c", "--config_path", default="mkdocs.yml", help="mkdocs.yml complete path" + ) + parser.add_argument( + "-s", "--source_language", default="en", help="source language of the config" + ) + parser.add_argument( + "-t", + "--translation_file_path", + default="mkdocs_tx.yml", + help="Translation file to create and translate", + ) + + subparsers = parser.add_subparsers(title="command", dest="command") + + # create the parser for the create_source command + parser_source = subparsers.add_parser( + "create_source", help="Creates the source file to be translated" + ) + + # create the parser for the update_config command + parser_update = subparsers.add_parser( + "update_config", + help="Updates the mkdocs.yml config file from the downloaded translated files", + ) + + args = parser.parse_args() + + if args.command == "create_source": + create_translation_source(args.config_path, args.translation_file_path) + + elif args.command == "update_config": + update_config( + args.config_path, args.translation_file_path, args.source_language + ) + + else: + raise ValueError diff --git a/website/scripts/mkdocs_tx_commit.sh b/website/scripts/mkdocs_tx_commit.sh new file mode 100755 index 00000000..e1375d14 --- /dev/null +++ b/website/scripts/mkdocs_tx_commit.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +set -e + +if [[ $(git diff --exit-code mkdocs.yml) ]]; then + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" + + echo "detected changes in mkdocs.yml" + if [[ ${GITHUB_EVENT_NAME} == "pull_request" ]]; then + # on PR push to the same branch + gh pr checkout $(echo "${GITHUB_REF_NAME}" | cut -d/ -f1) + pre-commit install + pre-commit run --files mkdocs.yml || true + git add mkdocs.yml + git commit -m "Update mkdocs.yml translation" --no-verify + git push + else + # on push/workflow_dispatch create a pull request + git checkout ${GITHUB_REF_NAME} + BRANCH="update-mkdocs-tx-$RANDOM" + git checkout -b ${BRANCH} + pre-commit install + pre-commit run --files mkdocs.yml || true + git add mkdocs.yml + git commit -m "Update mkdocs.yml translation" --no-verify + git push -u origin $BRANCH + gh pr create -B ${GITHUB_REF_NAME} -H ${BRANCH} --title 'Update mkdocs translations' --body 'run from mkdocs_tx' + fi +else + echo "no change mkdocs.yml" +fi diff --git a/website/scripts/transifex_utils.py b/website/scripts/transifex_utils.py index 18e17097..b255565f 100755 --- a/website/scripts/transifex_utils.py +++ b/website/scripts/transifex_utils.py @@ -25,6 +25,17 @@ def create_transifex_config(): f.write("[main]\n") f.write("host = https://www.transifex.com\n\n") + if os.path.isfile(f"{root}/mkdocs_tx.yml"): + print(f"Found mkdocs config translated content") + f.write(f"[o:{TX_ORGANIZATION}:p:{TX_PROJECT}:r:site_navigation]\n") + f.write("resource_name = site navigation\n") + f.write("file_filter = mkdocs_tx..yml\n") + f.write(f"source_file = mkdocs_tx.yml\n") + f.write(f"source_lang = {TX_SOURCE_LANG}\n") + f.write(f"type = YAML_GENERIC\n\n") + else: + print("No translation of mkdocs config found") + for file in glob.iglob( current_dir + "/../documentation/**/*.fr.md", recursive=True ):