Skip to content

Commit

Permalink
feat: Allow customizing how client locale is interpreted #20
Browse files Browse the repository at this point in the history
  • Loading branch information
lo5 committed Oct 14, 2022
1 parent 723d41e commit 1c3e73a
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 29 deletions.
70 changes: 47 additions & 23 deletions py/pkg/h2o_nitro/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,15 +284,27 @@ def dump(self) -> dict:
))


class Bundle:
def __init__(self, locale: str, resources: Dict[str, str]):
class Translation:
def __init__(self, locale: str, strings: Dict[str, str]):
self.locale = locale
self.resources = resources
self.strings = strings

def dump(self) -> dict:
return dict(
locale=self.locale,
resources=self.resources,
strings=self.strings,
)


class Resources:
def __init__(self, locale: str, translations: Sequence[Translation]):
self.locale = locale
self.translations = translations

def dump(self) -> dict:
return dict(
locale=self.locale,
translations=_dump(self.translations),
)


Expand Down Expand Up @@ -618,7 +630,7 @@ def _marshal_set(
theme: Optional[Theme] = None,
plugins: Optional[Iterable[Plugin]] = None,
help: Optional[Dict[str, str]] = None,
bundles: Optional[Sequence[Bundle]] = None,
resources: Optional[Resources] = None,
mode: Optional[str] = None,
):
return _marshal(dict(
Expand All @@ -631,7 +643,7 @@ def _marshal_set(
theme=_dump(theme),
plugins=_dump(plugins),
help=_dump(help),
bundles=_dump(bundles),
resources=_dump(resources),
mode=mode,
))))

Expand All @@ -647,17 +659,30 @@ def _marshal_switch(method: str, params: Optional[dict]):
def _lookup_resources(
lookup: Optional[Dict[str, Dict[str, str]]],
*locales: Optional[str],
) -> Optional[Bundle]:
) -> Optional[Translation]:
if lookup:
for locale in locales:
r = lookup.get(locale)
if r:
return Bundle(locale, r)
return Translation(locale, r)
return None


def _to_bundles(lookup: Optional[Dict[str, Dict[str, str]]]):
return [Bundle(l, r) for l, r in lookup.items()] if lookup else None
def _to_resources(locale: str, lookup: Optional[Dict[str, Dict[str, str]]]):
translations = [Translation(l, r) for l, r in lookup.items()] if lookup else None
return Resources(locale, translations)


TranslateLocale = Callable[[str], str]
LocaleOrTranslate = Union[str, TranslateLocale]


def _translate_locale(translate: LocaleOrTranslate, locale: str) -> str:
if translate:
if isinstance(translate, str):
return translate
return translate(locale)
return locale or 'en-US'


class Delegator:
Expand Down Expand Up @@ -709,7 +734,7 @@ def __init__(
plugins: Optional[Iterable[Plugin]] = None,
help: Optional[Dict[str, str]] = None,
resources: Optional[Dict[str, Dict[str, str]]] = None,
default_locale: Optional[str] = None,
locale: Optional[LocaleOrTranslate] = None,
delegator: Optional[Delegator] = None,
):
self._delegate = delegate
Expand All @@ -725,16 +750,15 @@ def __init__(
self._plugins = plugins
self._help = help
self._resources = resources
self._default_locale = default_locale or 'en-US'
self._locale = locale
# TODO clone instead? (to account for view-local closures)
self._delegator = delegator or Delegator()

for options in [self._menu, self._nav, self._routes]:
self._delegator.scan_opts(options)

def _ack(self, mode: Optional[str] = None, locale: Optional[str] = None):
# TODO filter by locale?
bundles = _to_bundles(self._resources)
resources = _to_resources(locale, self._resources)
return _marshal_set(
title=self._title,
caption=self._caption,
Expand All @@ -743,7 +767,7 @@ def _ack(self, mode: Optional[str] = None, locale: Optional[str] = None):
theme=self._theme,
plugins=self._plugins,
help=self._help,
bundles=bundles,
resources=resources,
mode=mode,
)

Expand Down Expand Up @@ -786,11 +810,11 @@ def __init__(
plugins: Optional[Iterable[Plugin]] = None,
help: Optional[Dict[str, str]] = None,
resources: Optional[Dict[str, Dict[str, str]]] = None,
default_locale: Optional[str] = None,
locale: Optional[LocaleOrTranslate] = None,
delegator: Optional[Delegator] = None,
):
super().__init__(delegate, context, send, recv, title, caption, menu, nav, routes, theme, plugins,
help, resources, default_locale, delegator)
help, resources, locale, delegator)

def serve(self, send: Callable, recv: Callable, context: any = None):
View(
Expand All @@ -807,14 +831,14 @@ def serve(self, send: Callable, recv: Callable, context: any = None):
plugins=self._plugins,
help=self._help,
resources=self._resources,
default_locale=self._default_locale,
locale=self._locale,
delegator=self._delegator,
)._run()

def _run(self):
# Handshake
method, mode, locale = self._read(_MsgType.Join)
self._send(self._ack(mode, locale))
self._send(self._ack(mode, _translate_locale(self._locale, locale)))

# Event loop
params = None
Expand Down Expand Up @@ -926,11 +950,11 @@ def __init__(
plugins: Optional[Iterable[Plugin]] = None,
help: Optional[Dict[str, str]] = None,
resources: Optional[Dict[str, Dict[str, str]]] = None,
default_locale: Optional[str] = None,
locale: Optional[LocaleOrTranslate] = None,
delegator: Optional[Delegator] = None,
):
super().__init__(delegate, context, send, recv, title, caption, menu, nav, routes, theme, plugins,
help, resources, default_locale, delegator)
help, resources, locale, delegator)

async def serve(self, send: Callable, recv: Callable, context: any = None):
await AsyncView(
Expand All @@ -947,14 +971,14 @@ async def serve(self, send: Callable, recv: Callable, context: any = None):
plugins=self._plugins,
help=self._help,
resources=self._resources,
default_locale=self._default_locale,
locale=self._locale,
delegator=self._delegator,
)._run()

async def _run(self):
# Handshake
method, mode, locale = await self._read(_MsgType.Join)
await self._send(self._ack(mode, locale))
await self._send(self._ack(mode, _translate_locale(self._locale, locale)))

# Event loop
params = None
Expand Down
6 changes: 3 additions & 3 deletions web/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ export const jump = (v: V, params?: Dict<S>) => {
window.open(v, target ?? '_blank', features.length ? features.join(',') : undefined)
}

const emptyBundle: Bundle = { locale: clientLocale, resources: {} }
const emptyBundle: Bundle = { locale: clientLocale, strings: {} }
const toBundleLookup = (bs: Bundle[]) => {
const d: Dict<Bundle> = {}
for (const b of bs) d[b.locale] = b
Expand Down Expand Up @@ -369,7 +369,7 @@ export const newClient = (server: Server) => {
{
const
{ settings } = msg,
{ title, caption, menu, nav, theme, plugins, help, mode, bundles } = settings
{ title, caption, menu, nav, theme, plugins, help, mode, resources } = settings

if (title) titleB(title)
if (caption) captionB(caption)
Expand All @@ -379,7 +379,7 @@ export const newClient = (server: Server) => {
if (mode) modeB(mode)
if (plugins) installPlugins(plugins)
if (help) helpB(sanitizeHelp(formatterB(), help))
if (bundles) formatterB(formatter(toBundleLookup(bundles), clientLocale))
if (resources) formatterB(formatter(toBundleLookup(resources.translations), resources.locale))
const state = stateB()
if (state.t === ClientStateT.Connected) busyB(false)
}
Expand Down
2 changes: 1 addition & 1 deletion web/src/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const formatter = (bundles: Dict<Bundle>, locale: S | S[]): Formatter =>
if (!bundle) bundle = loadBundle(bundles, locale)

if (bundle && /^@\w+$/.test(s)) {
const x = bundle.resources[s.substring(1)]
const x = bundle.strings[s.substring(1)]
if (x) s = x
}

Expand Down
6 changes: 4 additions & 2 deletions web/src/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@ export type Script = {

export type DisplayMode = 'normal' | 'chromeless'

export type Bundle = { locale: S, resources: Dict<S> }
export type Bundle = { locale: S, strings: Dict<S> }

export type Resources = { locale: S, translations: Bundle[] }

export type Settings = {
title?: S,
Expand All @@ -119,7 +121,7 @@ export type Settings = {
theme?: Theme
plugins?: Plugin[]
help?: Dict<S>
bundles?: Bundle[]
resources?: Resources
mode?: DisplayMode
}

Expand Down

0 comments on commit 1c3e73a

Please sign in to comment.