cezerin
cezerin copied to clipboard
Multilingual cezerin
I know you can set up a shop with different languages thanks to many translations done already but that is still a single language shop. I would like to make shop available in multiple languages. Product descriptions, titles, attributes, etc. would be written in other languages in addition to primary language and visitors could choose shop language they want.
Are there any plans for it? What would be the right way to implement that feature on cezerin?
@ceracera does this answer your question:
https://github.com/cezerin/cezerin/issues/523
@ceracera Adding multilingual to Cezerin will take around 1-2 month roughly. Multilingual is a pretty complex task. Mostly for UI. Language switchers everywhere.
I think the current goal should be stable v1 with the customer account. @restmount am I right?
@amp9020 No, I was thinking more like multiple languages at the same time
@sonufrienko Yes, I understand that. The thing is that I would like that feature available really soon so I was thinking in doing some of it, at least some core functionality, myself. Can you point me in the right direction about how to deal with it. Something like a description of what needs to bi changed/added in order to achieve that functionality.
@ceracera
Steps for the multilingual task
- Design database schema
- Modify API to accept language in the header
- Modify API to work with right locale
- Add language option to CezerinClient (REST API client)
- Dashboard: add a language switcher
- Store: add a language switcher
- Theme: change source of locale theme/locales/
.json
The Store is almost headless. So the most modification is needed to do in DB, API, and dashboard. Tips about db schema - Approaches to JSON internationalisation
@sonufrienko
Thanks a lot. That is great help. I'll try to make some basic functionality this weekend and if you have some additional hints and advice, please let me know.
Ok.
@sonufrienko I have trouble finding the right way to pass 'Accept-Language' header to server api. Can you point me in the right direction?
I would like to read Headers when there is no Local storage, and Local storage when user already picked a language before. I have found where are options in cezerinClient but I don't know how to pass 'Accept-Language' header to those options. Would it be ok if I could pass header as an option to api cezerinClient
in src/api/server/ajaxRouter.js
and src/store/server/api.js
?
It would be great if you could help :)
Thanks
@ceracera need to modify CezerinClient at https://github.com/cezerin/client/blob/master/src/apiClient.js#L15 and put language in the header to fetch.
on the server
- on page rendering you need to read all locales and put to Theme
- every router should read language from the header and put to service to operate with MongoDB
on the client
- Theme should receive all locales and find specific
SSR adds complex to this task.
@sonufrienko Thanks a lot. But it's hopeless :( I still cannot figure out how to get user language to CezeringClient. I can read Local storage in browser but since it's shared code on server also, it doesn't work...
What I did is this:
- Changed the db schema
- Modified CezerinClient like you said (as local npm package)
- Updated methods on
src/api/server/
that get translateble fields
It's all working well when I explicitly add eg. {language: "fr"}
to CezerinClient options but I cannot get it to pass Language headers or Local storage items.
@ceracera
- add
setLanguage(<locale>)
to CezerinClient - it should add language to the header on fetch request to API and AJAX (important - both). - call
api.setLanguage(<locale>)
orapi.ajax.setLanguage(<locale>)
when client switch language - also need to check is this header allowed
At this point, your CezerinClient (client and server) will always know your current language and attach it to every fetch requests.
- API and AJAX router should get language from the header and put to services
- AJAX should use language header to access API
Take a point that AJAX is just a proxy to API from the client side.
@sonufrienko Can you give me more info on number 1. above. Some example, pseudo code?
@sonufrienko DB schema and server methods for getting right language are working. But only when I literraly type language header in getConfig
method of apiClient
. I don't understand how can this value be set by setLanguage
function. Do I have to use options in CezerinClent, like the token is passed now?
Any help is more than welcome :)
@ceracera you mean this 1.
class AjaxClient {
constructor(options) {
this.locale = "en";
class AjaxClient {
setLocale(locale) {
this.locale = locale;
class AjaxClient {
getConfig(method, data, cookie) {
let config = {
headers: {
'Accept-Language': this.locale
@sonufrienko Great, thanks, done that. I can call setLocale
from src/store/client/api
, but how can I pass user language from client to src/api/server/ajaxRouter.js
or src/store/server/api.js
? I don't know how to pass localStorage
item to ajaxRouter
...
on Theme (client-side)
if (typeof window !== 'undefined') {
api.ajax.setLocale(localeFromLocalStorage)
CezerinClient will attach headert to every fetch requests.
on ajaxRouter.js
- get Accept-Language from req header
-
api.products.list(filter, localeFromHeader)
for example
@sonufrienko Ok, so on ajaxRouter.js
(src/api/server/ajaxRouter.js
, right?), when I get lang header it gets passed back to CezerinClient and there, in the list(filter)
method, for example, I have to pass that header to api.
From there I can pick a language in, for example, getProducts
method from src/api/server/services/products/products.js
. Is that right?
Sorry to bother you but it's difficult to me to make sense of this since it has many componenets...
@sonufrienko I managed to make it work. It's only for product names for now but it's a start :)
Here is what I did:
On CezerinClient
- added language to api and ajax clients in constructor and header for language in getConfig
- added setLanguage method on both api and ajax clients
On API
- in
ajaxRouter
get language header and callsetLanguage(language)
in CezerinClient with it. (only forget('/products')
route for now) - in
routes/products.js
get language header and pass it toProductsService.getProducts
. - in
services/products/products.js
use language to pick right value based on db schema (item name = item.name[language]
)
On Store
- in
server/loadState.js
get cookie with language and use it to callsetLanguage(language)
in CezerinClient. - edit
server/themeLocales.js
to map through all available languages (hard coded for now) and get all locales - also in
server/loadState.js
use cookie language to modify theme text to get it in right language (themeText: themeText[language]
)
On Theme
- in
components/header/index.js
make language switch that sets the cookie - in
components/products/custom.js
, when fetching products, use cookie to get right language
Now all translatable fields need to be changed like what is now done for products (now is just product name, though). I thought maybe to use traverse
like https://www.drzon.net/posts/approaches-to-json-internationalisation-i18n/ so that no change have to be made on routes and services. Just traverse the resulting json for whatever resource and get the right one back to client.
What do you think? Maybo I can submit a pull request so that you and others can contribute?
@ceracera Awesome! Give me some time to think about it.
Now I added traverse
to CezerinClient, in get
method. So if there is cookie language: fr
and data in mongo is like:
{
name: {
en: "Shirt",
fr: "Chemise'"
} ...
it is fetched as:
{name: "Chemise"} ...
It gets everything translated, products, categories, pages... Problem is updating stuff. What would be the right way to do similar thing for put
and post
in admin area? Maybe to define translatable fields (there are not many of them) and intercept db methods or CezerinClient to assign parent object on updating those fields. Eg. if you are updating {name: Shirt}
and you switched language to English, db should write it as {name: {en: "Shirt"}}
. @sonufrienko What do you think?
@ceracera do you have the code accessible anywhere?
@CezarManea Its not finished yet
@ceracera did you manage to get the changes to some stable point? what is the status of the work? thanks
No, I gave up :( I had trouble with admin part and did not have the time to work on it. Maybe later. I will post here.
Great job @ceracera, please give a sign if you have made a pull request, thx!
https://join.slack.com/t/caesarcommerce/shared_invite/enQtNDU5OTU4ODIyMzUyLWU2NWRmMzI3MTMxYTlkODFkZTdmZTM4MjdiNWQ2NTg4MzIyNDE1Yzc0ZGY5ZmFkNDc2Njc5Y2NkNWQxNDk4ODM On Mon, Oct 15, 2018 at 12:55 AM Lortschi [email protected] wrote:
Great job @ceracera https://github.com/ceracera, please give a sign if you have made a pull request, thx!
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/cezerin/cezerin/issues/527#issuecomment-429744034, or mute the thread https://github.com/notifications/unsubscribe-auth/AA-oh9G8IiAz9GJ-WnvfAwiv3ZoFvqhhks5ulD9mgaJpZM4VqDX2 .
@dougkulak this not an answer to the issue, you already posted that you opened a slack channel. stop spamming the issues.
Hi guys, any further plans regarding language switcher? Thanks