From 7d8ee04c0d891fb0c835a790b61876474475ee6c Mon Sep 17 00:00:00 2001 From: Sijie Guo Date: Tue, 31 Jul 2018 15:43:04 -0700 Subject: [PATCH] [website] Enable Translation & Localization (#2251) * [website] Enable Translation & Localization *Motivation* Docusaurus allows for easy translation functionality using [Crowdin](https://crowdin.com/). Documentation files written in English are uploaded to Crowdin for translation by users within a community. *Changes* - Enable the integration with Crowdin. - Adjust hyperlinks to include `language`. Crowdin project: https://crowdin.com/project/apache-pulsar * Add a statement about translations --- .gitignore | 5 + build/docker/Dockerfile | 4 + site2/crowdin.yaml | 49 ++++++++ site2/tools/docker-build-site.sh | 6 +- site2/website/languages.js | 181 +++++++++++++++++++++++++++++ site2/website/package.json | 4 +- site2/website/pages/en/contact.js | 22 ---- site2/website/pages/en/download.js | 20 ++-- site2/website/pages/en/index.js | 89 +++++++------- site2/website/pages/en/versions.js | 2 +- site2/website/siteConfig.js | 1 + 11 files changed, 306 insertions(+), 77 deletions(-) create mode 100644 site2/crowdin.yaml create mode 100644 site2/website/languages.js diff --git a/.gitignore b/.gitignore index 3e3c4e8db4338..38266a8cf251a 100644 --- a/.gitignore +++ b/.gitignore @@ -71,3 +71,8 @@ docker.debug-info # Yarn **/yarn.lock + +# docusaurus + +**/website/i18n/* +**/website/translated_docs* diff --git a/build/docker/Dockerfile b/build/docker/Dockerfile index d28330fedaad8..2f4c3688763cb 100644 --- a/build/docker/Dockerfile +++ b/build/docker/Dockerfile @@ -57,6 +57,10 @@ RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list RUN apt-get update && apt-get install yarn +# Install crowdin +RUN wget https://artifacts.crowdin.com/repo/deb/crowdin.deb -O crowdin.deb +RUN dpkg -i crowdin.deb + # Install PIP and PDoc RUN wget https://bootstrap.pypa.io/get-pip.py && python get-pip.py RUN pip install pdoc diff --git a/site2/crowdin.yaml b/site2/crowdin.yaml new file mode 100644 index 0000000000000..299c305ead437 --- /dev/null +++ b/site2/crowdin.yaml @@ -0,0 +1,49 @@ +project_identifier_env: CROWDIN_DOCUSAURUS_PROJECT_ID +api_key_env: CROWDIN_DOCUSAURUS_API_KEY +base_path: "./" +preserve_hierarchy: true + +files: + - + source: '/docs/*.md' + translation: '/website/translated_docs/%locale%/%original_file_name%' + languages_mapping: &anchor + locale: + 'af': 'af' + 'ar': 'ar' + 'bs-BA': 'bs-BA' + 'ca': 'ca' + 'cs': 'cs' + 'da': 'da' + 'de': 'de' + 'el': 'el' + 'es-ES': 'es-ES' + 'fa': 'fa-IR' + 'fi': 'fi' + 'fr': 'fr' + 'he': 'he' + 'hu': 'hu' + 'id': 'id-ID' + 'it': 'it' + 'ja': 'ja' + 'ko': 'ko' + 'mr': 'mr-IN' + 'nl': 'nl' + 'no': 'no-NO' + 'pl': 'pl' + 'pt-BR': 'pt-BR' + 'pt-PT': 'pt-PT' + 'ro': 'ro' + 'ru': 'ru' + 'sk': 'sk-SK' + 'sr': 'sr' + 'sv-SE': 'sv-SE' + 'tr': 'tr' + 'uk': 'uk' + 'vi': 'vi' + 'zh-CN': 'zh-CN' + 'zh-TW': 'zh-TW' + - + source: '/website/i18n/en.json' + translation: '/website/i18n/%locale%.json' + languages_mapping: *anchor diff --git a/site2/tools/docker-build-site.sh b/site2/tools/docker-build-site.sh index 68a75df6a23c1..948e2869461c8 100755 --- a/site2/tools/docker-build-site.sh +++ b/site2/tools/docker-build-site.sh @@ -38,6 +38,10 @@ echo "---- Build Pulsar website using image $IMAGE" CI_USER=$(id -u) CI_GROUP=$(id -g) +# crowdin keys +CROWDIN_DOCUSAURUS_PROJECT_ID=${CROWDIN_DOCUSAURUS_PROJECT_ID:-apache-pulsar} +CROWDIN_DOCUSAURUS_API_KEY=${CROWDIN_DOCUSAURUS_API_KEY:-UNSET} + DOCKER_CMD="docker run -i -e CI_USER=$CI_USER -e CI_GROUP=$CI_GROUP -v $ROOT_DIR:/pulsar $IMAGE" -$DOCKER_CMD bash -l -c 'cd /pulsar/site2/website && yarn && yarn build && node ./scripts/replace.js && cp -R ./build/pulsar /pulsar/generated-site/content/staging' +$DOCKER_CMD bash -l -c 'cd /pulsar/site2/website && yarn && yarn run crowdin-upload && yarn run crowdin-download && yarn build && node ./scripts/replace.js && cp -R ./build/pulsar /pulsar/generated-site/content/staging' diff --git a/site2/website/languages.js b/site2/website/languages.js new file mode 100644 index 0000000000000..90801eff030c3 --- /dev/null +++ b/site2/website/languages.js @@ -0,0 +1,181 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const languages = [ + { + enabled: true, + name: 'English', + tag: 'en', + }, + { + enabled: true, + name: '日本語', + tag: 'ja', + }, + { + enabled: false, + name: 'العربية', + tag: 'ar', + }, + { + enabled: false, + name: 'Bosanski', + tag: 'bs-BA', + }, + { + enabled: false, + name: 'Català', + tag: 'ca', + }, + { + enabled: false, + name: 'Čeština', + tag: 'cs', + }, + { + enabled: false, + name: 'Dansk', + tag: 'da', + }, + { + enabled: false, + name: 'Deutsch', + tag: 'de', + }, + { + enabled: false, + name: 'Ελληνικά', + tag: 'el', + }, + { + enabled: false, + name: 'Español', + tag: 'es-ES', + }, + { + enabled: false, + name: 'فارسی', + tag: 'fa-IR', + }, + { + enabled: false, + name: 'Suomi', + tag: 'fi', + }, + { + enabled: false, + name: 'Français', + tag: 'fr', + }, + { + enabled: false, + name: 'עִברִית', + tag: 'he', + }, + { + enabled: false, + name: 'Magyar', + tag: 'hu', + }, + { + enabled: false, + name: 'Bahasa Indonesia', + tag: 'id-ID', + }, + { + enabled: false, + name: 'Italiano', + tag: 'it', + }, + { + enabled: false, + name: 'Afrikaans', + tag: 'af', + }, + { + enabled: false, + name: '한국어', + tag: 'ko', + }, + { + enabled: false, + name: 'मराठी', + tag: 'mr-IN', + }, + { + enabled: false, + name: 'Nederlands', + tag: 'nl', + }, + { + enabled: false, + name: 'Norsk', + tag: 'no-NO', + }, + { + enabled: false, + name: 'Polskie', + tag: 'pl', + }, + { + enabled: false, + name: 'Português', + tag: 'pt-PT', + }, + { + enabled: false, + name: 'Português (Brasil)', + tag: 'pt-BR', + }, + { + enabled: false, + name: 'Română', + tag: 'ro', + }, + { + enabled: false, + name: 'Русский', + tag: 'ru', + }, + { + enabled: false, + name: 'Slovenský', + tag: 'sk-SK', + }, + { + enabled: false, + name: 'Српски језик (Ћирилица)', + tag: 'sr', + }, + { + enabled: false, + name: 'Svenska', + tag: 'sv-SE', + }, + { + enabled: false, + name: 'Türkçe', + tag: 'tr', + }, + { + enabled: false, + name: 'Українська', + tag: 'uk', + }, + { + enabled: false, + name: 'Tiếng Việt', + tag: 'vi', + }, + { + enabled: true, + name: '中文', + tag: 'zh-CN', + }, + {enabled: false, name: '繁體中文', tag: 'zh-TW'}, +]; +module.exports = languages; diff --git a/site2/website/package.json b/site2/website/package.json index b5013d40cd4ee..ae5f6e0fc21c6 100644 --- a/site2/website/package.json +++ b/site2/website/package.json @@ -7,7 +7,9 @@ "write-translations": "docusaurus-write-translations", "version": "docusaurus-version", "rename-version": "docusaurus-rename-version", - "test": "jest --detectOpenHandles" + "test": "jest --detectOpenHandles", + "crowdin-upload": "crowdin --config ../crowdin.yaml upload sources --auto-update -b master", + "crowdin-download": "crowdin --config ../crowdin.yaml download -b master" }, "devDependencies": { "axios": "^0.18.0", diff --git a/site2/website/pages/en/contact.js b/site2/website/pages/en/contact.js index 7935924466c7e..7bc48720443e9 100644 --- a/site2/website/pages/en/contact.js +++ b/site2/website/pages/en/contact.js @@ -10,10 +10,6 @@ const CWD = process.cwd(); const siteConfig = require(`${CWD}/siteConfig.js`); -function docUrl(doc, language) { - return siteConfig.baseUrl + 'docs/' + (language ? language + '/' : '') + doc; -} - class Contact extends React.Component { render() { let language = this.props.language || ''; @@ -41,24 +37,6 @@ class Contact extends React.Component { } ] - const supportLinks = [ - { - content: `Learn more using the [documentation on this site.](${docUrl( - 'doc1.html', - language - )})`, - title: 'Browse Docs', - }, - { - content: 'Ask questions about the documentation and project', - title: 'Join the community', - }, - { - content: "Find out what's new with this project", - title: 'Stay up to date', - }, - ]; - return (
diff --git a/site2/website/pages/en/download.js b/site2/website/pages/en/download.js index aff409a450663..8f07c5da5cd6b 100644 --- a/site2/website/pages/en/download.js +++ b/site2/website/pages/en/download.js @@ -7,6 +7,8 @@ const GridBlock = CompLibrary.GridBlock; const CWD = process.cwd(); +const translate = require('../../server/translate.js').translate; + const siteConfig = require(`${CWD}/siteConfig.js`); const releases = require(`${CWD}/releases.json`); @@ -51,9 +53,9 @@ class Download extends React.Component { - - - + + + @@ -105,7 +107,7 @@ class Download extends React.Component {

Once you've downloaded a Pulsar release, instructions on getting up and running with a standalone cluster that you can run on your laptop can be found in the{' '} - Run Pulsar locally tutorial. + Run Pulsar locally tutorial.

@@ -121,19 +123,19 @@ class Download extends React.Component {

- + - + - + - + @@ -170,7 +172,7 @@ class Download extends React.Component { sha512) ) diff --git a/site2/website/pages/en/index.js b/site2/website/pages/en/index.js index 0ad7d5866eb1e..d06920b833044 100755 --- a/site2/website/pages/en/index.js +++ b/site2/website/pages/en/index.js @@ -99,49 +99,51 @@ const Block = props => ( ); -const features = { - row1: [ - { - content: 'Easily deploy lightweight compute logic using developer-friendly APIs without needing to run your own stream processing engine', - title: `[Pulsar Functions](${docUrl('functions-overview')})`, - }, - { - content: 'Pulsar has run in production at Yahoo scale for over 3 years, with millions of messages per second across millions of topics', - title: `[Proven in production](${docUrl('concepts-architecture')})`, - }, - { - content: 'Seamlessly expand capacity to hundreds of nodes', - title: `[Horizontally scalable](${docUrl('concepts-architecture')})`, - } - ], - row2: [ - { - content: 'Designed for low publish latency (< 5ms) at scale with strong durabilty guarantees', - title: `[Low latency with durability](${docUrl('concepts-architecture')})`, - }, - { - content: 'Designed for configurable replication between data centers across multiple geographic regions', - title: `[Geo-replication](${docUrl('administration-geo')})`, - }, - { - content: 'Built from the ground up as a multi-tenant system. Supports Isolation, Authentication, Authorization and Quotas', - title: `[Multi-tenancy](${docUrl('concepts-architecture')})`, - } - ], - row3: [ - { - content: `Persistent message storage based on Apache BookKeeper. Provides IO-level isolation between write and read operations`, - title: `[Persistent storage](${docUrl('concepts-architecture')})`, - }, - { - content: 'Flexible messaging models with high-level APIs for Java, C++, Python and GO', - title: `[Client libraries](${docUrl('client-libraries')})`, - }, - { - content: 'REST Admin API for provisioning, administration, tools and monitoring. Deploy on bare metal or Kubernetes.', - title: `[Operability](${docUrl('admin-api-overview')})`, - } - ] +const features_lang = language => { + return { + row1: [ + { + content: 'Easily deploy lightweight compute logic using developer-friendly APIs without needing to run your own stream processing engine', + title: `[Pulsar Functions](${docUrl('functions-overview', language)})`, + }, + { + content: 'Pulsar has run in production at Yahoo scale for over 3 years, with millions of messages per second across millions of topics', + title: `[Proven in production](${docUrl('concepts-architecture', language)})`, + }, + { + content: 'Seamlessly expand capacity to hundreds of nodes', + title: `[Horizontally scalable](${docUrl('concepts-architecture', language)})`, + } + ], + row2: [ + { + content: 'Designed for low publish latency (< 5ms) at scale with strong durabilty guarantees', + title: `[Low latency with durability](${docUrl('concepts-architecture', language)})`, + }, + { + content: 'Designed for configurable replication between data centers across multiple geographic regions', + title: `[Geo-replication](${docUrl('administration-geo', language)})`, + }, + { + content: 'Built from the ground up as a multi-tenant system. Supports Isolation, Authentication, Authorization and Quotas', + title: `[Multi-tenancy](${docUrl('concepts-architecture', language)})`, + } + ], + row3: [ + { + content: `Persistent message storage based on Apache BookKeeper. Provides IO-level isolation between write and read operations`, + title: `[Persistent storage](${docUrl('concepts-architecture', language)})`, + }, + { + content: 'Flexible messaging models with high-level APIs for Java, C++, Python and GO', + title: `[Client libraries](${docUrl('client-libraries', language)})`, + }, + { + content: 'REST Admin API for provisioning, administration, tools and monitoring. Deploy on bare metal or Kubernetes.', + title: `[Operability](${docUrl('admin-api-overview', language)})`, + } + ] + }; }; const KeyFeautresGrid = props => ( @@ -179,6 +181,7 @@ const ApacheBlock = prop => ( class Index extends React.Component { render() { let language = this.props.language || ''; + let features = features_lang(language); return (
diff --git a/site2/website/pages/en/versions.js b/site2/website/pages/en/versions.js index c730e201c3d41..11afad4d3c152 100644 --- a/site2/website/pages/en/versions.js +++ b/site2/website/pages/en/versions.js @@ -53,7 +53,7 @@ function Versions(props) {
diff --git a/site2/website/siteConfig.js b/site2/website/siteConfig.js index d5f67798ed1a9..43363415d38b7 100644 --- a/site2/website/siteConfig.js +++ b/site2/website/siteConfig.js @@ -101,6 +101,7 @@ const siteConfig = { primaryColor: '#188fff', secondaryColor: '#205C3B', }, + translationRecruitingLink: 'https://crowdin.com/project/apache-pulsar', // This copyright info is used in /core/Footer.js and blog rss/atom feeds. copyright: 'Copyright © ' +
ReleaseLinkCrypto filesReleaseLinkCrypto files
The Pulsar java clientThe Pulsar java client The Pulsar java client
The Pulsar go clientThe Pulsar go client The Pulsar go client
The Pulsar python clientThe Pulsar python client The Pulsar python client
The Pulsar C++ clientThe Pulsar C++ client The Pulsar C++ client
- Release Notes + Release Notes
master + href={`${siteConfig.baseUrl}docs/${props.language}/standalone`}> Documentation