Skip to content

Commit

Permalink
Refactor language handling (#366)
Browse files Browse the repository at this point in the history
Refactor language handling
  • Loading branch information
marvinhagemeister authored Aug 3, 2019
2 parents d6f7eb0 + d4ff7e1 commit 415b02f
Show file tree
Hide file tree
Showing 166 changed files with 337 additions and 152 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion src/components/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { getCurrentDocVersion } from '../lib/docs';
export default class App extends Component {
store = createStore({
url: this.props.url || location.pathname,
lang: '',
lang: 'en',
docVersion: getCurrentDocVersion(location.pathname),
toc: null
});
Expand Down
11 changes: 9 additions & 2 deletions src/components/code-block.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@ const CodeBlock = ({ children, ...props }) => {
let child = children && children[0];
let isHighlight = child && child.type === 'code';

if (isHighlight) {
let text = (child.props.children[0] || '').replace(/(^\s+|\s+$)/g, '');
let firstChild = child.props.children[0];
// Children is mutated and it will have the highlighted tree on second render.
// We can detect that by checken if we have more than one child
if (
isHighlight &&
child.props.children.length === 1 &&
typeof firstChild === 'string'
) {
let text = (firstChild || '').replace(/(^\s+|\s+$)/g, '');
let lang =
child.props.class &&
child.props.class.match(/(?:lang|language)-([a-z]+)/)[1];
Expand Down
17 changes: 10 additions & 7 deletions src/components/content-region.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const memoizeProd = process.env.NODE_ENV === 'production' ? memoize : f => f;

// fetch and parse a markdown document
const getContent = memoizeProd(([lang, name]) => {
let path = lang ? `/content/lang/${lang}` : '/content',
let path = `/content/${lang}`,
url = `${path}/${name.replace(/^\//, '')}`,
[, ext] = url.match(/\.([a-z]+)$/i) || [];
if (!ext) url += '.md';
Expand All @@ -40,11 +40,14 @@ const getContent = memoizeProd(([lang, name]) => {
typeof window !== 'undefined' &&
window['_boostrap_' + url]) ||
fetch(url);

let fallback = false;
return fetchPromise
.then(r => {
// fall back to english
if (!r.ok && lang) {
return fetch(url.replace(/lang\/[^/]+\//, ''));
if (!r.ok && lang != 'en') {
fallback = true;
return fetch(url.replace(/content\/[^/]+\//, 'content/en/'));
}
return r;
})
Expand All @@ -54,16 +57,16 @@ const getContent = memoizeProd(([lang, name]) => {
return fetch(`${path}/${r.status}.md`);
})
.then(r => r.text())
.then(r => parseContent(r));
.then(r => ({ ...parseContent(r), fallback }));
});

export const getContentOnServer = PRERENDER
? route => {
? (route, lang) => {
if (!PRERENDER) return;
if (route == '/') route = '/index';

const fs = __non_webpack_require__('fs');
let data = fs.readFileSync(`content${route}.md`, 'utf8');
let data = fs.readFileSync(`content/${lang}/${route}.md`, 'utf8');

// convert frontmatter from yaml to json:
const yaml = __non_webpack_require__('yaml');
Expand Down Expand Up @@ -195,7 +198,7 @@ export default class ContentRegion extends Component {
content = cachedContent;
} else if (PRERENDER) {
// this is all only run during prerendering
({ content } = getContentOnServer(location.pathname));
({ content } = getContentOnServer(location.pathname, props.lang));
}
}

Expand Down
26 changes: 19 additions & 7 deletions src/components/controllers/page/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ export function useDescription(text) {

const noop = () => {};

export function usePage(route) {
export function usePage(route, lang) {
// on the server, pass data down through the tree to avoid repeated FS lookups
if (PRERENDER) {
const { content, meta } = getContentOnServer(route.path);
const { content, meta } = getContentOnServer(route.path, lang);
return {
current: null,
content,
Expand All @@ -65,6 +65,7 @@ export function usePage(route) {
const content = hydrated && bootData && bootData.content;

const [loading, setLoading] = useState(true);
const [isFallback, setFallback] = useState(false);
let [meta, setMeta] = useState(hydrated ? bootData.meta : {});
if (hydrated) meta = bootData.meta;

Expand All @@ -78,7 +79,8 @@ export function usePage(route) {
useDescription(meta.description);

let didLoad = false;
function onLoad({ meta }) {
function onLoad(data) {
const { meta, fallback } = data;
didLoad = true;

// Don't show loader forever in case of an error
Expand All @@ -88,6 +90,7 @@ export function usePage(route) {

setMeta(meta);
setLoading(false);
setFallback(fallback);
const current = getContent(route);
const bootData = getPrerenderData(current);
setHydrated(!!bootData);
Expand All @@ -108,13 +111,17 @@ export function usePage(route) {
content,
meta,
loading,
onLoad
onLoad,
isFallback
};
}

export default function Page({ route }) {
const { loading, meta, content, current, onLoad } = usePage(route);
const store = useStore(['toc', 'url']);
const store = useStore(['toc', 'url', 'lang']);
const { loading, meta, content, current, onLoad, isFallback } = usePage(
route,
store.state.lang
);
const urlState = store.state;
const url = useMemo(() => urlState.url, [current]);

Expand Down Expand Up @@ -142,7 +149,12 @@ export default function Page({ route }) {
show={hasSidebar}
/>
<div class={style.inner}>
<Hydrator boot={isReady} component={EditThisPage} show={canEdit} />
<Hydrator
boot={isReady}
component={EditThisPage}
show={canEdit}
isFallback={isFallback}
/>
<Hydrator
component={Title}
boot={isReady}
Expand Down
9 changes: 6 additions & 3 deletions src/components/controllers/page/sidebar-nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,20 @@ import { getCurrentUrl } from 'preact-router';
*/
export default function SidebarNav({ items, onClick }) {
// Remove trailing slash to fix activeCss check below.
const url = getCurrentUrl().replace(/\/$/, '');
const url = getCurrentUrl()
.replace(/\/$/, '')
.replace(/\?.*/, '');

return (
<nav
tabIndex="0"
class={cx(style.toc, !(items && items.length > 1) && style.disabled)}
>
{items.map(({ text, level, id, href }) => {
{items.map(({ text, level, href }) => {
let activeCss = href === url ? style.linkActive : undefined;
return (
<a
href={id != null ? '#' + id : href}
href={href}
onClick={onClick}
class={cx(style.link, activeCss, style['level-' + level])}
>
Expand Down
9 changes: 7 additions & 2 deletions src/components/controllers/page/sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,23 @@ import { useCallback } from 'preact/hooks';
import config from '../../../config.json';
import { useStore } from '../../store-adapter';
import { useOverlayToggle } from '../../../lib/toggle-overlay';
import { getRouteName } from '../../header';

export default function Sidebar() {
const [open, setOpen] = useOverlayToggle(false);
const toggle = useCallback(() => setOpen(!open), [open]);
const close = useCallback(() => setOpen(false));
const { docVersion } = useStore(['docVersion']).state;
const { docVersion, lang } = useStore(['docVersion', 'lang']).state;

// Get menu items for the current version of the docs (guides)
// TODO: allow multiple sections - config[meta.section]
const docNav = config.docs
.filter(item => item.path.indexOf(`/v${docVersion}`) > -1)
.map(item => ({ text: item.name, level: 2, href: item.path }));
.map(item => ({
text: getRouteName(item, lang),
level: 2,
href: item.path
}));

return (
<div class={style.wrapper} data-open={open}>
Expand Down
1 change: 1 addition & 0 deletions src/components/doc-version/style.less
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
.select {
padding: 0.2rem;
margin-left: 0.2rem;
font-size: 0.8125rem;
}
39 changes: 25 additions & 14 deletions src/components/edit-button/index.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
import { useStore } from '../store-adapter';
import style from './style.less';
import cx from '../../lib/cx';
import { Fragment } from 'preact';

export default function EditThisPage(props) {
export default function EditThisPage({ show, isFallback }) {
const store = useStore(['lang', 'url']);
const { url, lang } = store.state;
let path = url.replace(/\/$/, '') || '/index';
if (lang) path = `/lang/${lang}${path}`;
let editUrl = `https://github.com/preactjs/preact-www/tree/master/content${path}.md`;
path = !isFallback ? path + '.md' : '';
const editUrl = `https://github.com/preactjs/preact-www/tree/master/content/${lang}${path}`;
return (
props.show && (
<div class={style.wrapper}>
<a
class={style.edit}
href={editUrl}
target="_blank"
rel="noopener noreferrer"
>
Edit this Page
</a>
</div>
show && (
<Fragment>
<div class={cx(style.wrapper, isFallback && style.withFallback)}>
<a
class={style.edit}
href={editUrl}
target="_blank"
rel="noopener noreferrer"
>
{!isFallback ? 'Edit this Page' : 'Add translation'}
</a>

{isFallback && (
<div class={style.fallback}>
<b>Error:</b> Could not find a translation for this page. You can
help us out by <a href={editUrl}>adding one here</a>.
</div>
)}
</div>
</Fragment>
)
);
}
15 changes: 15 additions & 0 deletions src/components/edit-button/style.less
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
max-width: @content-width;
margin-left: auto;
margin-right: auto;

&.withFallback {
padding-top: 4rem;
}
}

.edit {
Expand All @@ -25,3 +29,14 @@
right: 0;
}
}

.fallback {
background: var(--color-error-bg);
padding: 0.75rem 1rem;
border-left: 0.3rem solid var(--color-error-border);

a {
.link;
color: var(--color-link);
}
}
Loading

0 comments on commit 415b02f

Please sign in to comment.