I18n within resources
Hi!
Is there a way to replicate the functionality of something like Trans (https://hexdocs.pm/trans/Trans.html) in Ash? It provides a simple way to translate fields of a schema without needing extra db tables and joins.
What is the idomatic way to handle I18n within resources in Ash?
23 Replies
Hey there! There is no set pattern for it currently, but you can do it with calculations, for example
If you wanted the translations stored in the database you could basically do exactly what that tool does
and define an embedded attribute
Could we possibly have a working example, even if you point something out.
This looks like an extension to me
where you would write:
I'm building a page builder and have blocks not sure how would i write out the way you've described for each block?
Is this possible, could you point me in the right direction?
which would result in this structure in db
Hey there, sorry about that
Been a bit busy lately π
My initial example was a bit off
Actually...maybe not so much π
It groups translations effectively the way you want
I updated the example to show roughly how it would look with a real field
So with that you'd have a record like:
So then what you'd do is add all the language code as attributes
Awesome, thank you, so this means i need to define all the modules by hand to have this work properly. Do you imagine a way i could write an extension or macro to do this automatically?
so in the end the resource would look like:
I see what you mean. Yes that is possible. Not in the way youβve shown, but it could be done with a separate DSL section.
i18n_attributes [:slug, :name]
ahh that's nice!
I'm currently thinking about migrating my octafest.com from the old laravel php stack to phoenix liveview and ash seems like the perfect bridge
well if you'd like to work on
ash_i18n
I'm more than happy to help πwhere would i start?
Step one would be to get familiar with spark dsl extensions. Not a lot of guides out there, but a great example of a lightweight extension is ash_archival
ok on it
The idea would be to add a dsl extension to describe the changes, and then to use transformers to apply changes the resource
where can i find a simple example implementing DSL.Entity
as i want to do this:
here's my field:
but this fails with
auto_set_fields
is meant to be a keyword list of explicit field values
you probably don't need it πok got this to build π
now on to figuring out how to embed this, any pointers?
Does this look like i'm moving in the right direction?
Or is there a better/cleaner way to insert embeded schemas?
I'm thinking if it's worth the effort it's not that hard to do what you've shown and this adds quite a bit of magic that you can't see.
because this is just for adding the translated fields.
I then need to modify the create changeset to include the embeds with validations
add read actions which accept locale and move the fields into top level access
It really depends how you want to do this:
Is the translation template static for all instances of the resource? In this case, you're better off using something like
Gettext
(included by default with Phoenix) and then returning the interpolated string using a calculation.
Are the translations something that need to be modifiable from a frontend, i.e. they should live in the database and not in code? Then there are a lot of options, and which is best still depends on whether individual resources need to have arbitrary strings or there is a single template for each locale that needs to be user-modifiable but applies to all instances of that resource.Yeah, if youβre looking to store translations in the database then that is a strategy that would work, and defining the module like that is pretty much the only way
Yeah the whole point is to have client facing editable content for pages etc.
I can't get this to render the form though i've tried adding forms: [auto?: true] but nothing happens:
Any help is greatly appreciated.
You likely need to do an
add_form
when you create the initial form
because we don't assume that a value should be populated for translations
by default
I can look at it a bit more this weekend, but if you want an empty value provided for a given thing you'd need to add_form
once at the beginning
and then likely for each locale translation you could have a little plus button that adds an additional locale translationIt should have an empty value for each locale as i have a tabs thing where you can switch between languages. I'll have a look at the add_form thing π thank you! Ash is amazing π
Hmm ok back at this, i have an interesting case and trying to figure out how to best do this:
Octafest is a multi-tenant thing. And translations are really tenant bound and dynamic.
For e.g.
Tenant A has two languages English and Lithuanian. Default is Lithuanian.
Tenant B has three languages English, Italian and German. Default is english.
Since json columns don't really need a defined structure the way i've done it in php land is just have json columns for the translated stuff and then show the ui according to the tenants settings.
Tenant settings define what languages they support and the default language.
That in turn determines what get's populated in the translated field column form.
Also i've switched out the relationship, so it's not:
But:
Any help is greatly appreciated
Ok so created a shared embed like so:
But the problem is still having the hardcoded locales.
I mean as a workaround i can have that as a list of all available locales which for now is limited and then only show the relevant ones for the tenant?
This is the usage:
And this is how a basic form for creating looks like:
You strategy of supporting all locales would work
You can also make it a calculation that produces a map, and then use a custom type in
ash_graphql
.
oh, you might not even be using ash_graphql
?
anyway, a custom map type could also do it π