Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accessing attributes via getString #282

Open
alnvdl opened this issue Aug 30, 2018 · 5 comments
Open

Accessing attributes via getString #282

alnvdl opened this issue Aug 30, 2018 · 5 comments

Comments

@alnvdl
Copy link

alnvdl commented Aug 30, 2018

Right now, at least from looking at the source, I think there's no clean way to access attributes when using getString via withLocalization.

Would it be too ugly to change getString so that it can also (optionally) return formatted attributes?

I'm asking because I want to have the following setup:

Having this as input:

MyReactComponent =
    .label1 = Label 1
    .btn-allow = allow
    .btn-deny = deny

I want to be able to use it like this:

class MyReactComponent extends Component {
    render() {
        return <button>{this.props.getAttribute("btn-allow")}</button>;
    }
}
customLocalization(MyReactComponent);

customLocalization would be a HOC that stores the wrapped component name
(MyReactComponent) and exposes the getAttribute function:

getAttribute(attrId, args, fallback) {
    return this.props.getString(wrappedComponentName, args, fallback, [attrId]);
}

The reason I want do to that is to avoid having to repeat component names in the translation files (e.g.: MyReactComponent-label1, MyReactComponent-btn-allow, etc.)

I could submit a pull request to change getString in the way I'm proposing, but before I do that I want to know if this too much of a corruption of the original design and shouldn't be done at all, or if I'm missing something and this is already possible.

@stasm
Copy link
Contributor

stasm commented Aug 31, 2018

Thank you for opening an issue before submitting code :) Your timing is great; I've been thinking about making changes to getString, too. It's part of a larger change we're planning to make to other Fluent APIs. #208 is about changing the low-level FluentBundle.format() method to accept:

  • message identifiers: format("my-react-component"), and
  • attribute paths: format("my-react-component.btn-allow").

Once we implement this change, it will make sense to change getString to simply follow the same pattern. This also means that I'd suggest to wait with changing getString now to avoid duplicating code. We're planning to make the change to format by the end of September.

@stasm
Copy link
Contributor

stasm commented Aug 31, 2018

I would also like to suggest using the <Localized> component for your use-case. Given the following message:

my-react-component =
    .label1 = Label 1
    .btn-allow = allow
    .btn-deny = deny

…you can use <Localized> like this:

// Probably worth abstracting it as MyLocalizedComponent
<Localized id="my-react-component" attrs={{label1: true, "btn-allow": true, "btn-deny": true}}>
    <MyReactComponent />
</Localized>

MyReactComponent will now receive the translations as props. It might make sense to come up with a convention to name localizable props consistently, e.g. l10nButtonAllow or button_allow_. Just be aware the the syntax is currently pretty strict about characters allowed as attribute names:

identifier ::= [a-zA-Z] [a-zA-Z0-9_-]*

In the longer term, we plan to relax this restriction. See projectfluent/fluent#117 and projectfluent/fluent#173.

@alnvdl
Copy link
Author

alnvdl commented Sep 1, 2018

Ok, I will wait for the new identifier syntax then! I will leave this issue open in case you want to track it somehow.

As for using <Localized>, I prefer to avoid the declarative syntax and use explicit function calls instead (no technical reason, I just like it better). In the specific case of Fluent, I don't like that one has to declare each attribute in attrs, but I understand the technical reasons behind it. But that's fine, since getString is there for annoying users like me :)

At the moment I'm using react-intl with injectIntl, and then calling their formatMessage each time I need a string. I also developed a solution very similar to FTL for specifying messages (but mine is way less powerful and interesting).

Fluent is the kind of crucial work that receives less attention than it should, so thanks for doing it!

@ImUrX
Copy link

ImUrX commented Dec 27, 2022

So how is this going to end up happening?

@eemeli
Copy link
Member

eemeli commented Jan 2, 2023

@ImUrX A PR adding functionality to this to getString() would be welcome, if you're interested? Probably something like looking for a . character in the id at the start of the function, and adjusting behaviour accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants