This is an automated email from the ASF dual-hosted git repository. shuai pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/answer-website.git
The following commit(s) were added to refs/heads/main by this push: new 1f2eda7fe Locales nav (#289) 1f2eda7fe is described below commit 1f2eda7feba6a7a5c62f1f56297d63c879175125 Author: dashuai <lishuail...@sifou.com> AuthorDate: Mon Jan 13 14:32:53 2025 +0800 Locales nav (#289) --- plugins/blog-plugin.js | 3 -- .../blog/BlogCategoryPostsPage/index.tsx | 1 - src/components/blog/BlogDetailPage/index.tsx | 1 - src/components/blog/BlogHome/index.tsx | 1 - src/theme/DocSidebarItem/Category/index.tsx | 3 -- src/theme/Layout/BrowserLanguage.tsx | 57 ++++++++++++++++++++++ src/theme/Layout/index.tsx | 3 +- src/theme/NavbarItem/NavbarNavLink.tsx | 21 +++++++- 8 files changed, 78 insertions(+), 12 deletions(-) diff --git a/plugins/blog-plugin.js b/plugins/blog-plugin.js index fcd05dd90..59689bc83 100644 --- a/plugins/blog-plugin.js +++ b/plugins/blog-plugin.js @@ -149,8 +149,6 @@ async function blogPluginExtended(...pluginArgs) { const { createData, addRoute } = actions; - // console.log('blogPosts', blogPosts[0]); - const removeDraftPosts = allBlogPosts.filter((post) => !post.metadata.frontMatter?.draft); // Fecommend posts list @@ -264,7 +262,6 @@ async function blogPluginExtended(...pluginArgs) { permalink: generateCategoryPath(category.label), }; - // console.log('categoryProp', categoryProp); const categoryPropPath = await createData( `${utils.docuHash(categoryProp.label)}.json`, JSON.stringify(categoryProp, null, 2), diff --git a/src/components/blog/BlogCategoryPostsPage/index.tsx b/src/components/blog/BlogCategoryPostsPage/index.tsx index 0c312f351..3b8ab793c 100644 --- a/src/components/blog/BlogCategoryPostsPage/index.tsx +++ b/src/components/blog/BlogCategoryPostsPage/index.tsx @@ -21,7 +21,6 @@ interface IProps extends Props { } const Index = (props: IProps) => { const { category, categoriyList, items, listMetadata, } = props - // console.log('...props', props); return ( <HtmlClassNameProvider className={clsx( diff --git a/src/components/blog/BlogDetailPage/index.tsx b/src/components/blog/BlogDetailPage/index.tsx index f40da2d19..5c8ba8882 100644 --- a/src/components/blog/BlogDetailPage/index.tsx +++ b/src/components/blog/BlogDetailPage/index.tsx @@ -21,7 +21,6 @@ import BlogPostItem from '../BlogPostItem'; function BlogPostPageContent({relatedList, sidebar, children}) { const {metadata, toc} = useBlogPost(); - // console.log('BlogPostPageContent', toc); const { frontMatter} = metadata; const { hide_table_of_contents: hideTableOfContents, diff --git a/src/components/blog/BlogHome/index.tsx b/src/components/blog/BlogHome/index.tsx index 036ddf222..9508032c0 100644 --- a/src/components/blog/BlogHome/index.tsx +++ b/src/components/blog/BlogHome/index.tsx @@ -33,7 +33,6 @@ interface HomeProps { } export function Home({ featuredPosts, categoyList, metadata, blogList }: HomeProps): JSX.Element { - // console.log('metadata', metadata); return ( <HtmlClassNameProvider className={clsx( diff --git a/src/theme/DocSidebarItem/Category/index.tsx b/src/theme/DocSidebarItem/Category/index.tsx index a8cfd2df1..0da5f3933 100644 --- a/src/theme/DocSidebarItem/Category/index.tsx +++ b/src/theme/DocSidebarItem/Category/index.tsx @@ -80,7 +80,6 @@ function CollapseButton({ categoryLabel: string; onClick: ComponentProps<'button'>['onClick']; }) { - // console.log('categoryLabel', categoryLabel); return ( <button aria-label={ @@ -157,8 +156,6 @@ export default function DocSidebarItemCategory({ } }, [collapsible, expandedItem, index, setCollapsed, autoCollapseCategories]); - console.log('collapsed', item); - return ( <li className={clsx( diff --git a/src/theme/Layout/BrowserLanguage.tsx b/src/theme/Layout/BrowserLanguage.tsx new file mode 100644 index 000000000..631bc987e --- /dev/null +++ b/src/theme/Layout/BrowserLanguage.tsx @@ -0,0 +1,57 @@ +import React, {useEffect} from 'react'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; + +const LANGUAGE_PREFERENCE_KEY = '_lang_browser_'; + +export default function BrowserLanguageRedirect() { + const { + siteConfig: { + i18n: {defaultLocale, locales}, + }, + } = useDocusaurusContext(); + + useEffect(() => { + window.addEventListener('languagechange', () => { + localStorage.setItem(LANGUAGE_PREFERENCE_KEY, navigator.language); + }) + + const currentPath = window.location.pathname; + const storageLocale = localStorage.getItem('_lang_user_') || localStorage.getItem(LANGUAGE_PREFERENCE_KEY); + const storageLocaleIsDefault = storageLocale === defaultLocale; + + if (storageLocale) { + if (storageLocaleIsDefault) { + if (currentPath === '/') return; + return; + } else { + if (currentPath.startsWith(`/${storageLocale}`)) { + return; + } else { + window.location.pathname = `/${storageLocale}${currentPath}`; + return; + } + } + } else { + const browserLanguage = navigator.language.toLowerCase(); + const matchedLocale = locales.find(locale => + browserLanguage === locale.toLowerCase() || + browserLanguage.startsWith(locale.toLowerCase() + '-') + ); + if (matchedLocale) { + localStorage.setItem(LANGUAGE_PREFERENCE_KEY, matchedLocale); + window.location.pathname = `/${matchedLocale}${currentPath}`; + } else { + window.location.pathname = currentPath; + } + } + + // remove the event listener + return () => { + window.removeEventListener('languagechange', () => { + localStorage.setItem(LANGUAGE_PREFERENCE_KEY, navigator.language); + }) + } + }, []); + + return null; +} diff --git a/src/theme/Layout/index.tsx b/src/theme/Layout/index.tsx index e310f20f8..ad7de5c10 100644 --- a/src/theme/Layout/index.tsx +++ b/src/theme/Layout/index.tsx @@ -23,6 +23,7 @@ import LayoutProvider from '@theme/Layout/Provider'; import ErrorPageContent from '@theme/ErrorPageContent'; import type {Props} from '@theme/Layout'; import mixpanel from 'mixpanel-browser'; +import BrowserLanguage from './BrowserLanguage'; import styles from './styles.module.css'; @@ -45,7 +46,6 @@ export default function Layout(props: Props): JSX.Element { }, []) useEffect(() => { - // console.log('Layout.tsx: location.pathname: ', location); mixpanel.track_pageview(); }, [location]); @@ -58,6 +58,7 @@ export default function Layout(props: Props): JSX.Element { <AnnouncementBar /> <Navbar /> + <BrowserLanguage /> <div id={SkipToContentFallbackId} diff --git a/src/theme/NavbarItem/NavbarNavLink.tsx b/src/theme/NavbarItem/NavbarNavLink.tsx index 8e22a938f..70d0ba0c9 100644 --- a/src/theme/NavbarItem/NavbarNavLink.tsx +++ b/src/theme/NavbarItem/NavbarNavLink.tsx @@ -12,10 +12,16 @@ import isInternalUrl from '@docusaurus/isInternalUrl'; import {isRegexpStringMatch} from '@docusaurus/theme-common'; import IconExternalLink from '@theme/Icon/ExternalLink'; import type {Props} from '@theme/NavbarItem/NavbarNavLink'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; + +interface SProps extends Props { + tos: Record<string, any> +} export default function NavbarNavLink({ activeBasePath, activeBaseRegex, + tos, to, href, label, @@ -23,14 +29,23 @@ export default function NavbarNavLink({ isDropdownLink, prependBaseUrlToHref, ...props -}: Props): JSX.Element { +}: SProps): JSX.Element { // TODO all this seems hacky // {to: 'version'} should probably be forbidden, in favor of {to: '/version'} - const toUrl = useBaseUrl(to); + const { i18n: { currentLocale } } = useDocusaurusContext(); + // If to is a string, we assume it's a path that needs localization + const aliasTo = tos?.[currentLocale] || to; + const toUrl = useBaseUrl(aliasTo); const activeBaseUrl = useBaseUrl(activeBasePath); const normalizedHref = useBaseUrl(href, {forcePrependBaseUrl: true}); const isExternalLink = label && href && !isInternalUrl(href); + const clickLink = (e) => { + if (e.target?.lang) { + localStorage.setItem('_lang_user_', e.target.lang); + } + } + // Link content is set through html XOR label const linkContentProps = html ? {dangerouslySetInnerHTML: {__html: html}} @@ -53,6 +68,7 @@ export default function NavbarNavLink({ href={prependBaseUrlToHref ? normalizedHref : href} {...props} {...linkContentProps} + onClick={clickLink} /> ); } @@ -69,6 +85,7 @@ export default function NavbarNavLink({ })} {...props} {...linkContentProps} + onClick={clickLink} /> ); }