GithubHelp home page GithubHelp logo

Comments (11)

ronnetzer avatar ronnetzer commented on May 18, 2024 3

Love the idea but unfortunately, it fails in our use cases.

  1. we receive our translations file from our client's backend, which stores them as CSV (so that the content guys can change and edit each key's value to whatever they want), and converts them to json when we request the translation. so your approach won't be readable for the guys responsible for the translations.
  2. in another project (this client also does the CSV thing), there's a "debug" mode which enables to view full translation path in a tooltip when you hover on a translated value. (this is used by QA and content guys)

and besides that, you kinda bind your code to the content instead of binding it to the translation key that will probably won't change as frequently as the content of that key

from transloco.

shaharkazaz avatar shaharkazaz commented on May 18, 2024 1

We can also support dynamic params:

{{ t.hash('some {{dynamic}} thing', { dynamic: propFromComponent }) }}

Will transpile to:

{{ t['1234567'] | translocoParams: { dynamic: propFromComponent} }}

from transloco.

CharlBest avatar CharlBest commented on May 18, 2024 1

@ronnetzer not sure if this is what you meant but let me try an example.
In the current implementation the key will be something like 'helloWorld' and the value 'Hello World'. But lets say the key doesn't describe the value but rather the use case like 'headerTitle' with value 'Hello World'. This means that translators can change the translation file (the 'Hello World' value) as many times as they want without any developer that has to go and update the template with some new key.

There is maybe an argument to be made there that isn't good practice because the key could be become unrelated to the value/text. An example could be key = 'headerTitle' and then its intial value is 'Welcome to our site' but the release v2 it becomes 'Company Brand Name'. Then the UI changes and from release v3 that text gets placed in the footer because it's value is the companies name but the key is still saying 'headerTitle'.

I hope I interpreted this conversation in the right way @ronnetzer and helped a bit.
@shaharkazaz you guys are doing such a cool job with this project. I'm really impressed and happy I found a good i18n library. Well done!

@NetanelBasal Good time so say I'm a really big fan of your work. Have read probably 90% of all you Medium blog posts and thanks for all you good tips, trick, practices and knowledge.

from transloco.

shaharkazaz avatar shaharkazaz commented on May 18, 2024

We can also support dynamic strings. For example:
In the template:

{{ t[dynamicProperty] }} 

And in the component:

import { hash } from '@ngneat/transloco';
...
this.dynamicProperty = condition ? hash('hello world') : hash('bye');

Will transpile to:

import { hash } from '@ngneat/transloco';
...
this.dynamicProperty = condition ? '261689226' :  '781689346';

from transloco.

shaharkazaz avatar shaharkazaz commented on May 18, 2024

@ronnetzer

  1. I'm not sure how this affects what you describe since what matters is the value and not the keys (they are not supposed to change otherwise it breaks the translations), so if they can see the translations I'm not sure where this fails.
  2. What is the usage of this debug mode? what's the value of seeing the key? we want to detach this entire process from the developer.

From my experience (working with a pretty large translated app) the content rarely changes, and even if you do need to change the content once in a while I'd rather use find replace and gain all the benefits of working this way.

from transloco.

ronnetzer avatar ronnetzer commented on May 18, 2024

@shaharkazaz

  1. The point is that the developers shouldn't be aware of content changes and the client should be free to edit the content whenever he wants without any development cost. And with your approach (if I understand correctly) when marketing decides to change "Hello World" to "Good Morning Planet" nothing breaks but now the template (t.hash('Hello world')) will return "Good Morning Planet".
    So now you have 2 options, keep it that way or align with the content and update t.hash value.
    most of us would probably go with option 2, which in the end creates a new translation file with this new hash (what happens to the previous hash?) that will need to be translated manually (again) to the rest of the languages (?).
  2. Mainly by marketing and QA team. The client demands that if a translation to a key is missing, we won't show any other fallback text (including the key) and only in debug mode you can see the missing translation keys (i know its weird but its not our decision).

Another use case that I think will break:
We have a toaster for displaying error messages returned from the backend based on endpoint and error code, let's say the endpoints are in the format of '.../page_name/action_name'.
for each action_name we have a default error message in case we don't have a translation for an error code and the same goes if we don't have translations for an action_name at all and the same for page_name. So how something like that can be done using your approach? (getting human error messages from the backend is not possible)

From my experience (working with a pretty large translated app) the content rarely changes, and even if you do need to change the content once in a while I'd rather use find replace and gain all the benefits of working this way.

The size of the app is not the issue, the issue is the companies and clients. Each client is different and as a 3rd party library, you cannot assume that the content won't change and sacrifice maintenance for performance.

from transloco.

shaharkazaz avatar shaharkazaz commented on May 18, 2024

@ronnetzer

(if I understand correctly) when marketing decides to change "Hello World" to "Good Morning Planet" nothing breaks but now the template (t.hash('Hello world')) will return "Good Morning Planet".

It seems that you misunderstood, if you want to change "Hello world" to "Good Morning Planet" t.hash('Hello world') must change to t.hash('Good Morning Planet')

which in the end creates a new translation file with this new hash (what happens to the previous hash?) that will need to be translated manually (again) to the rest of the languages (?).

I'm not sure how is this different from changing the value of a key? it won't need to be translated to every language as well? The idea is that the new translation file created will be merged with the previous one so just this new key needs translation ( as you would need to translate it if you just change an existing key's value).

Mainly by marketing and QA team. The client demands that if a translation to a key is missing, we won't show any other fallback text (including the key) and only in debug mode you can see the
missing translation keys (i know its weird but its not our decision).

This can be achieved, allowing you to pass a custom missing key handler via an injection token is practically ready so you could do whatever you want in case there is no key.

For each action_name we have a default error message in case we don't have a translation for an error code and the same goes if we don't have translations for an action_name at all and the same for page_name. So how something like that can be done using your approach? (getting human error messages from the backend is not possible)

This proposal is not all or nothing, the idea is to implement it where you can.
You can still use the regular key values to support these cases, where you will have all you server keys and the hashing solution is for the static translations in your app.

The size of the app is not the issue, the issue is the companies and clients. Each client is different and as a 3rd party library, you cannot assume that the content won't change and sacrifice maintenance for performance.

You don't have to use this feature if it's not meeting your needs, we are not going to force this on everyone who uses this library, it's a proposal that might fit other use cases but not yours.

from transloco.

ronnetzer avatar ronnetzer commented on May 18, 2024

@shaharkazaz

It seems that you misunderstood, if you want to change "Hello world" to "Good Morning Planet" t.hash('Hello world') must change to t.hash('Good Morning Planet')

So you're saying that for every small change required by the marketing the flow is:

  1. marketing needs to ask the dev team to change a value in the code.
  2. a new translation file created and sent back to the marketing (and a new version is released)
  3. marketing updates the rest of the translations with the new key along with the new translated value.

the current flow is:

  1. marketing updates the value of a key
    That's it.

Can you see the problem now? I don't think I have any other way to explain it.
From a client perspective, this is not practical, and from a dev perspective, this could become a maintenance nightmare. There is no way that I'm the only one who thinks that 🤔.

we are not going to force this on everyone who uses this library, it's a proposal that might fit other use cases but not yours.

That's good to hear and not what I've understood from your proposal.

from transloco.

shaharkazaz avatar shaharkazaz commented on May 18, 2024

@ronnetzer
Can you explain what is your company's process? I think this is the gap here.
Can you add an example of one of your templates and your translation file?

from transloco.

ronnetzer avatar ronnetzer commented on May 18, 2024

@shaharkazaz
@CharlBest got it right (thanks btw), as he said the keys describe the use case, I also explained most of our client's workflow in more details to Netanel over the phone.

In general, First we provide the translation file to the client (according to their design) and then during development, they change the content and we add new keys.

for example, a simplified configuration for a dynamic form (with ngx-dynamic-forms library):

[
	{
		"id": "name",
		"type": "INPUT",
		"labelTooltip": "",
		"controlTooltip": "",
		"label": "form.field.name.label",
		"placeholder": "",
		"validators": {
			"required": null
		}
	},
	{
		"id": "description",
		"type": "TEXTAREA",
		"labelTooltip": "form.field.description.labelTooltip",
		"controlTooltip": "form.field.description.controlTooltip",
		"label": "form.field.description.label",
		"placeholder": "form.field.description.placeholder"
	}
]

and the corresponding translation file:

"form": {
	"field": {
		"name": {
			"label": "Name",
			"labelTooltip": "",
			"controlTooltip": "",
			"placeholder": "",
			"errorMessage": {}
		},
		"displayName": {
			"label": "Display name",
			"labelTooltip": "",
			"controlTooltip": "",
			"placeholder": "",
			"errorMessage": {}
		}
	}
}

*the form's JSON configuration will be modified in the future by product/marketing/someone who's not tech-oriented.

So this gives the client the ability to build/edit forms and their translations (even new keys), without any further development.

In any case, there are downsides for both ways, your proposal is optional therefore it doesn't worth spending time trying to solve my rare (?) use cases, I will just stick with the current way for them :)

from transloco.

NetanelBasal avatar NetanelBasal commented on May 18, 2024

@CharlBest only 90% 😜? Thanks!

from transloco.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.