Skip to content

Commit

Permalink
feat: on board docusaurus i18n system
Browse files Browse the repository at this point in the history
closes #160

BREAKING CHANGE: drop `translations` in options
  • Loading branch information
weareoutman committed May 19, 2022
1 parent e59ad09 commit 27e09ae
Show file tree
Hide file tree
Showing 19 changed files with 3,902 additions and 406 deletions.
31 changes: 20 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ module.exports = {
// ... Your options.
// `hashed` is recommended as long-term-cache of index file is possible.
hashed: true,
explicitSearchResultPath: true,
// For Docs using Chinese, The `language` is recommended to set to:
// ```
// language: ["en", "zh"],
Expand Down Expand Up @@ -86,27 +85,37 @@ module.exports = {
| searchResultLimits | number | `8` | Limit the search results. |
| searchResultContextMaxLength | number | `50` | Set the max length of characters of each search result to show. |
| explicitSearchResultPath | boolean | false | Whether an explicit path to a heading should be presented on a suggestion template. |
| translations | TranslationMap | - | Set translations of this theme, see [docs below](#translations). |
| ignoreFiles | string \| RegExp \| (string \| RegExp)[] | /**meta**\$/ | Set the match rules to ignore some files. |

### Translations
### I18N

Since v0.25.0, we support [docusaurus i18n system]((https://docusaurus.io/docs/i18n/introduction)), and provided `en` and `zh-CN` translations out of the box.

For other languages, please follow the official tutorial about how to [translate plugin data](https://docusaurus.io/docs/i18n/tutorial#translate-plugin-data). And translate `theme.SearchBar.*` and `theme.SearchPage.*` in `i18n/*/code.json`.

And translations by options is dropped since v0.25.0.

<details>
<summary>See translation options for &lt;0.25.0</summary>
To make this theme localized, pass a `translations` option which defaults to:

```json
{
"search_placeholder": "Search",
"see_all_results": "See all results",
"no_results": "No results.",
"search_results_for": "Search results for \"{{ keyword }}\"",
"search_the_documentation": "Search the documentation",
"count_documents_found": "{{ count }} document found",
"count_documents_found_plural": "{{ count }} documents found",
"no_documents_were_found": "No documents were found"
"translations": {
"search_placeholder": "Search",
"see_all_results": "See all results",
"no_results": "No results.",
"search_results_for": "Search results for \"{{ keyword }}\"",
"search_the_documentation": "Search the documentation",
"count_documents_found": "{{ count }} document found",
"count_documents_found_plural": "{{ count }} documents found",
"no_documents_were_found": "No documents were found"
}
}
```

Note that `*_plural` can be omitted if it is the same as singular.
</details>

## Custom Styles

Expand Down
3 changes: 3 additions & 0 deletions __mocks__/Translate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function translate(param) {
return param.message;
}
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module.exports = {
// snapshotSerializers: ["enzyme-to-json/serializer"],
moduleNameMapper: {
"\\.module\\.css$": "identity-obj-proxy",
"@docusaurus/Translate": "<rootDir>/__mocks__/Translate.js",
},
// Ref https://github.com/facebook/jest/issues/2070#issuecomment-431706685
// Todo(steve): remove next line when issue fixed.
Expand Down
9 changes: 9 additions & 0 deletions locales/zh-Hans.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"theme.SearchBar.label": "搜索",
"theme.SearchBar.seeAll": "查看全部结果",
"theme.SearchBar.noResultsText": "没有找到任何文档",
"theme.SearchPage.existingResultsTitle": "“{query}” 的搜索结果",
"theme.SearchPage.emptyResultsTitle": "搜索文档",
"theme.SearchPage.documentsFound.plurals": "共找到 {count} 篇文档",
"theme.SearchPage.noResultsText": "没有找到任何文档"
}
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"build": "npm run build:client && npm run build:server",
"build:client": "tsc --project tsconfig.client.json",
"build:server": "tsc --project tsconfig.server.json",
"postbuild": "copyfiles -u 3 \"src/client/theme/**/*.css\" dist/client/client/theme",
"postbuild": "copyfiles -u 3 \"src/client/theme/**/*.css\" dist/client/client/theme && copyfiles -u 1 \"locales/*.json\" dist/locales",
"release": "standard-version"
},
"main": "dist/server/server/index.js",
Expand All @@ -26,6 +26,8 @@
},
"license": "MIT",
"dependencies": {
"@docusaurus/theme-common": "^2.0.0-beta.20",
"@docusaurus/theme-translations": "^2.0.0-beta.20",
"@docusaurus/utils": "^2.0.0-beta.20",
"@docusaurus/utils-common": "^2.0.0-beta.20",
"@docusaurus/utils-validation": "^2.0.0-beta.20",
Expand Down Expand Up @@ -81,8 +83,5 @@
"rimraf": "^3.0.2",
"standard-version": "^9.0.0",
"typescript": "^4.6.4"
},
"resolutions": {
"joi": "17.6.0"
}
}
7 changes: 5 additions & 2 deletions src/client/theme/SearchBar/EmptyTemplate.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { translations } from "../../utils/proxiedGenerated";
import {translate} from '@docusaurus/Translate';
import { iconNoResults } from "./icons";
import styles from "./SearchBar.module.css";

export function EmptyTemplate(): string {
if (process.env.NODE_ENV === "production") {
return `<span class="${styles.noResults}"><span class="${styles.noResultsIcon}">${iconNoResults}</span><span>${translations.no_results}</span></span>`;
return `<span class="${styles.noResults}"><span class="${styles.noResultsIcon}">${iconNoResults}</span><span>${translate({
id: "theme.SearchBar.noResultsText",
message: "No results",
})}</span></span>`;
}
return `<span class="${styles.noResults}">⚠️ The search index is only available when you run docusaurus build!</span>`;
}
13 changes: 10 additions & 3 deletions src/client/theme/SearchBar/SearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import clsx from "clsx";
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
import ExecutionEnvironment from "@docusaurus/ExecutionEnvironment";
import { useHistory, useLocation } from "@docusaurus/router";
import {translate} from '@docusaurus/Translate';

import { fetchIndexes } from "./fetchIndexes";
import { SearchSourceFactory } from "../../utils/SearchSourceFactory";
Expand All @@ -18,7 +19,6 @@ import { SearchResult } from "../../../shared/interfaces";
import {
searchResultLimits,
Mark,
translations,
} from "../../utils/proxiedGenerated";
import LoadingRing from "../LoadingRing/LoadingRing";

Expand Down Expand Up @@ -108,7 +108,10 @@ export default function SearchBar({
const a = document.createElement("a");
const url = `${baseUrl}search?q=${encodeURIComponent(query)}`;
a.href = url;
a.textContent = translations.see_all_results;
a.textContent = translate({
id: "theme.SearchBar.seeAll",
message: "See all results",
});
a.addEventListener("click", (e) => {
if (!e.ctrlKey && !e.metaKey) {
e.preventDefault();
Expand Down Expand Up @@ -238,7 +241,11 @@ export default function SearchBar({
})}
>
<input
placeholder={translations.search_placeholder}
placeholder={translate({
id: "theme.SearchBar.label",
message: "Search",
description: "The ARIA label and placeholder for search button",
})}
aria-label="Search"
className="navbar__search-input"
onMouseEnter={onInputMouseEnter}
Expand Down
39 changes: 26 additions & 13 deletions src/client/theme/SearchPage/SearchPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
import Layout from "@theme/Layout";
import Head from "@docusaurus/Head";
import Link from "@docusaurus/Link";
import {translate} from '@docusaurus/Translate';
import {usePluralForm} from "@docusaurus/theme-common";

import useSearchQuery from "../hooks/useSearchQuery";
import { fetchIndexes } from "../SearchBar/fetchIndexes";
Expand All @@ -12,8 +14,6 @@ import { highlight } from "../../utils/highlight";
import { highlightStemmed } from "../../utils/highlightStemmed";
import { getStemmedPositions } from "../../utils/getStemmedPositions";
import LoadingRing from "../LoadingRing/LoadingRing";
import { translations } from "../../utils/proxiedGenerated";
import { simpleTemplate } from "../../utils/simpleTemplate";

import styles from "./SearchPage.module.css";
import { concatDocumentPath } from "../../utils/concatDocumentPath";
Expand All @@ -22,6 +22,7 @@ export default function SearchPage(): React.ReactElement {
const {
siteConfig: { baseUrl },
} = useDocusaurusContext();
const {selectMessage} = usePluralForm();
const { searchValue, updateSearchPath } = useSearchQuery();
const [searchQuery, setSearchQuery] = useState(searchValue);
const [searchSource, setSearchSource] =
Expand All @@ -33,10 +34,18 @@ export default function SearchPage(): React.ReactElement {
const pageTitle = useMemo(
() =>
searchQuery
? simpleTemplate(translations.search_results_for, {
keyword: searchQuery,
? translate({
id: "theme.SearchPage.existingResultsTitle",
message: "Search results for \"{query}\"",
description: 'The search page title for non-empty query',
}, {
query: searchQuery,
})
: translations.search_the_documentation,
: translate({
id: "theme.SearchPage.emptyResultsTitle",
message: "Search the documentation",
description: 'The search page title for empty query',
}),
[searchQuery]
);

Expand Down Expand Up @@ -111,17 +120,21 @@ export default function SearchPage(): React.ReactElement {
{searchResults &&
(searchResults.length > 0 ? (
<p>
{simpleTemplate(
searchResults.length === 1
? translations.count_documents_found
: translations.count_documents_found_plural,
{
count: searchResults.length,
}
{selectMessage(
searchResults.length,
translate({
id: "theme.SearchPage.documentsFound.plurals",
message: "1 document found|{count} documents found",
description: 'Pluralized label for "{count} documents found". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',
}, { count: searchResults.length })
)}
</p>
) : process.env.NODE_ENV === "production" ? (
<p>{translations.no_documents_were_found}</p>
<p>{translate({
id: "theme.SearchPage.noDocumentsFound",
message: "No documents were found",
description: "The paragraph for empty search result",
})}</p>
) : (
<p>
⚠️ The search index is only available when you run docusaurus
Expand Down
10 changes: 0 additions & 10 deletions src/client/utils/__mocks__/proxiedGenerated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,6 @@ export const indexHash = "abc";
export const searchResultLimits = 8;
export const searchResultContextMaxLength = 50;
export const explicitSearchResultPath = false;
export const translations = {
search_placeholder: "Search",
see_all_results: "See all results",
no_results: "No results.",
search_results_for: 'Search results for "{{ keyword }}"',
search_the_documentation: "Search the documentation",
count_documents_found: "{{ count }} document found",
count_documents_found_plural: "{{ count }} documents found",
no_documents_were_found: "No documents were found",
};

export function __setLanguage(value: string[]): void {
language = value;
Expand Down
22 changes: 0 additions & 22 deletions src/client/utils/simpleTemplate.spec.ts

This file was deleted.

8 changes: 0 additions & 8 deletions src/client/utils/simpleTemplate.ts

This file was deleted.

12 changes: 0 additions & 12 deletions src/declarations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,10 @@ declare module "*/generated.js" {
export const searchResultLimits: number;
export const searchResultContextMaxLength: number;
export const explicitSearchResultPath: boolean;
export const translations: Required<TranslationMap>;
// These below are for mocking only.
export const __setLanguage: (value: string[]) => void;
export const __setRemoveDefaultStopWordFilter: (value: boolean) => void;
export const __setRemoveDefaultStemmer: (value: boolean) => void;
}

declare module "@docusaurus/Head";

declare interface TranslationMap {
search_placeholder?: string;
see_all_results?: string;
no_results?: string;
search_results_for?: string;
search_the_documentation?: string;
count_documents_found?: string;
count_documents_found_plural?: string;
no_documents_were_found?: string;
}
16 changes: 16 additions & 0 deletions src/server/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import path from "path";
import fs from "fs-extra";
import { normalizeUrl } from "@docusaurus/utils";
import { codeTranslationLocalesToTry } from "@docusaurus/theme-translations";
import { DocusaurusContext, PluginOptions } from "../shared/interfaces";
import { processPluginOptions } from "./utils/processPluginOptions";
import { postBuildFactory } from "./utils/postBuildFactory";
Expand Down Expand Up @@ -34,6 +35,21 @@ export default function DocusaurusSearchLocalPlugin(
return [pagePath];
},

async getDefaultCodeTranslationMessages() {
const dirPath = path.join(__dirname, "../../locales");
const localesToTry = codeTranslationLocalesToTry(context.i18n.currentLocale);

// Return the content of the first file that match
// fr_FR.json => fr.json => nothing
for (const locale of localesToTry) {
const filePath = path.resolve(dirPath, `${locale}.json`);
if (await fs.pathExists(filePath)) {
return fs.readJSON(filePath);
}
}
return {};
},

async contentLoaded({ actions: { addRoute } }: any) {
addRoute({
path: normalizeUrl([context.baseUrl, "search"]),
Expand Down
Loading

0 comments on commit 27e09ae

Please sign in to comment.