Closed vvvvalvalval closed 10 years ago
Hi Valentin,
typically from an HTTP Accept-languages header
Sure. Note that taoensso.tower.utils/parse-http-accept-header
may be useful, in case you weren't aware that it's there (it's used for the default Ring middleware).
And I cannot add that functionality in a proper way in my own application because I'd need access to the loc-tree function which is private.
The loc-tree
fn just splits a locale into constituent parts. If I've understood what you'd like to do correctly, most of the relevant fallback logic is actually in make-t-uncached
.
What do you think? Shall I give it a try and make a pull request from it?
What you're trying to do seems quite reasonable, and would be difficult with Tower currently - so in principle I am on board with adding support if we can do it in a way that's sensible...
Let me think about this a little and I'll get back to you!
Cheers :-)
Thanks for the walkthrough, I'd been looking for parse-http-request-header
.
Anyway, I'd be glad to contribute, let me know if I can help :).
However, I couldn't find make-t-uncached anywhere... what have I missed?
There's a large update pending on the dev branch. Any work on this will have to target that.
There's some breaking API changes, so I've been reluctant to merge into master until I'm sure I'm satisfied with the changes.
Anyway, I'd be glad to contribute, let me know if I can help.
I appreciate that, thank you. Am actually experimenting with this right now. It might be possible to get this working with only a minor change, but I'd like to confirm. Will definitely come back to you if there's something you could assist with.
Okay, I've updated v2.1.0-SNAPSHOT
so that translation fns can now take a vector of descending-preference locales. https://github.com/ptaoussanis/tower/commit/46f21ce015d015f5ca37b8fe89a71ba48b8f821d
These'll be searched intelligently. From the updated README:
And even fallback locales. `(t [:fr-FR :en-US] :example/foo)` searches:
1. `:example/foo` in the `:fr-FR` locale.
2. `:example/foo` in the `:en-US` locale.
3. `:example/foo` in the `:fr` locale.
4. `:example/foo` in the `:en` locale.
5. `:example/foo` in the fallback locale.
6. `:missing` in any of the above locales.
This works in both Clojure and ClojureScript versions of Tower.
Also modified the Ring middleware to use all Accept-Language header languages in this way: dictionaries will automatically be searched for translation entries intelligently.
Haven't tested this much (esp. the middleware), so feedback and/or bug reports welcome.
Cheers! :-)
Thank you, but I think the preference order is not quite right. In your example, I believe 1-3-2-4-5-6 is more relevant (If you value :fr-Fr
more than :en-US
, then you probably prefer :fr
to :en-US
too. That's my use case at least).
The examples in my first post can give you an idea of what I have in mind, if you want I can come up with a more complete one.
Cheers,
Note that this search strategy does handle some forms of Accept-Language a bit strangely. For example, a ["en-GB" "en-US" "en"]
browser preference will become a [:en-GB :en :en-US]
locale preference.
I don't personally think that's a big issue though, since the Accept-Language choices are rarely intentionally specific to that extent.
That's what I was thinking about when I said "more complete example", and indeed I think it's an issue. But I agree it's not an emergency, I suggest to file it as an improvement and take the time to think about it.
Also, if we go down that road, that suggests changing the Ring middleware too, don't you think?
But I agree it's not an emergency, I suggest to file it as an improvement and take the time to think about it.
Sure.
Also, if we go down that road, that suggests changing the Ring middleware too, don't you think?
I don't follow, sorry?
Well, for example we could make the Ring middleware attach to the request a translation (partial) function that uses the Locales list extracted from its accept-language header.
From what I understand, the current Ring middleware selects "blindly" a best locale for the translations that will result from the request, and attaches a partial translation function for that purpose.
But that new implementation of t
allows for a more pessimistic behavior, which is using the whole sequence of accepted as a partial argument, i.e something like
(handler (assoc request :locale (tower/locale-key loc)
:tconfig tconfig
:t (if tconfig
(partial tower/t accepted-locs tconfig)
(partial tower/t accepted-locs))))
in taoensso.tower.ring/wrap-tower-middleware
.
From what I understand, the current Ring middleware selects "blindly" a best locale for the translations that will result from the request, and attaches a partial translation function for that purpose.
Ahh, gotcha. Yes, I actually made the change as part of the earlier 2.1.0 snapshot: https://github.com/ptaoussanis/tower/commit/0265b7d21effdbd1f7cd48625beb9bbc2a6fbce2 :-)
All the commits on the dev
branch are here: https://github.com/ptaoussanis/tower/commits/dev
My mistake, I wasn't looking at the right place. Fine then:) Thanks very much for reacting so quickly on this. Bests,
I find myself in a situation where I do not anticipate what locales are available to me (i.e the config is unanticipated) and I have a list of accepted locales in preference order (typically from an HTTP Accept-languages header). So I'd like to know, for a particular message, which is the best locale to choose from those that are bore available in my config and accepted. I posted on StackOverflow about this.
In other words, it'd be nice to be able to do something like
but you can't. And I cannot add that functionality in a proper way in my own application because I'd need access to the
loc-tree
function which is private.So I propose as a first step towards this to implement a
preferred-lang
function that may look like this :What do you think? Shall I give it a try and make a pull request from it?