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

Localisation of phrase "Default" #605

Closed
deining opened this issue Jan 14, 2019 · 16 comments
Closed

Localisation of phrase "Default" #605

deining opened this issue Jan 14, 2019 · 16 comments

Comments

@deining
Copy link
Contributor

deining commented Jan 14, 2019

I have a simple command with showDefaultValues=true:

Usage: parent [-m=<number>]
  -m, --minimum=<number>     Default: 3

Is there a simple way to localize the phrase 'Default' via an entry in the resource bundle so that the output with German locale looks like this?

Usage: parent [-m=<number>]
  -m, --minimum=<number>     Voreinstellung: 3

Thanks for your support.

@remkop
Copy link
Owner

remkop commented Jan 14, 2019

You should be able to accomplish this with the current version of picocli by embedding the ${DEFAULT-VALUE} variable in the option description:

description = "The count (default: ${DEFAULT-VALUE})"

I believe this should also work when the description text is coming from a resource bundle. (This gives more flexibility, so you can use other text than "Default: ".)

@remkop
Copy link
Owner

remkop commented Jan 15, 2019

I confirmed this works:

package test;

import static org.junit.Assert.*;
import org.junit.Test;
import picocli.CommandLine;
import picocli.CommandLine.Command;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Vector;

public class I18nTest {

    @Test
    public void testI18nDemo() {

        CommandLine commandLine = new CommandLine(new I18nDemo());

        String actual = commandLine.getUsageMessage();
        String expected = String.format("" +
                "Usage: i18n [-x=<x>] [-y=<y>]%n" +
                "bundle text%n" +
                "  -x=<x>    日本語 34 for x%n" +
                "  -y=<y>    日本語 4444 for y%n");

        assertEquals(expected, actual);
    }

    @Command(name="i18n", resourceBundle = "test.I18nTest$MyBundle")
    static class I18nDemo {
        @CommandLine.Option(names = "-x", defaultValue = "34") int x;
        @CommandLine.Option(names = "-y") int y = 4444;
    }


    public static class MyBundle extends ResourceBundle {
        Map<String, String> map = new HashMap<String, String>();

        public MyBundle() {
            map.put("usage.description",  "bundle text");
            map.put("x",  "日本語 ${DEFAULT-VALUE} for x");
            map.put("y",  "日本語 ${DEFAULT-VALUE} for y");
        }

        protected Object handleGetObject(String s) {
            return map.get(s);
        }

        public Enumeration<String> getKeys() {
            return new Vector<String>(map.keySet()).elements();
        }
    }
}

@deining
Copy link
Contributor Author

deining commented Jan 15, 2019

Yes, I can confirm that this works, and this is a valid solution for sure.
Since this soluton is a bit more verbose than simply using 'showDefaultValues = true' I'm asking myself whether it would make sense to provide the opportunity to localize the string resource 'Default' used in that context. Reasonable proposal or feature creep?

Everything looks great now in my use case, except for one minor issue. I'm using:

@Command(subcommands = { CommandLine.HelpCommand.class, xx.class })
    static class Parent implements Runnable { ...

Requesting help for the parent command results in

Usage: Parent [-hvV] [COMMAND]
Description of parent command
  -h, --help      Show this help message and exit.
  -V, --version   Print version information and exit.
Commands:
  xx             Description of subcommand
  help           Displays help information about the specified command

Is there any easy way to localize the description for the 'help' subcommand ('Displays help information about the specified command')? Thanks for you answer!

@remkop
Copy link
Owner

remkop commented Jan 15, 2019

I think you can override by providing entries in your resource bundle:

# Example bundle for the “parent” command 
parent.help.usage.description=my description 

@deining
Copy link
Contributor Author

deining commented Jan 15, 2019

No, that didn't do the trick for me.

@remkop
Copy link
Owner

remkop commented Jan 15, 2019

Ok, I’ll try to test this tomorrow. Is the spelling of the key correct? Should it be capitalized “Parent” for your application?

@remkop
Copy link
Owner

remkop commented Jan 15, 2019

Localizing the built-in help subcommand

I found it. The resource bundle keys for the built-in help command are:

# for a specific subcommand, e.g., `parent help`
parent.help.usage.header=Dit is de `help` subcommand van de `parent` command
parent.help.help=Dit beschrijft de --help option van de `help` subcommand van de `parent` command
parent.help.version=Dit beschrijft de --version option van de `help` subcommand van de `parent` command

# or have one global entry for the `help` subcommand
help.usage.header=Dit is de `help` subcommand
help.help=Dit beschrijft de --help option van de `help` subcommand
help.version=Dit beschrijft de --version option van de `help` subcommand

@remkop
Copy link
Owner

remkop commented Jan 15, 2019

About using showDefaultValues = true vs ${DEFAULT-VALUE}: I recommend using the variable since it gives the most flexibility and easily lends itself to internationalization and localization.

Going forward I plan to add more variables like this. (If I had thought of the variables first I would not have provided the showDefaultValues = true mechanism. But hindsight is perfect, as they say...) :-)

@remkop
Copy link
Owner

remkop commented Jan 16, 2019

The I18nTest has examples of localizing the built-in help command.

@remkop remkop added this to the 3.9.2 milestone Jan 16, 2019
@remkop
Copy link
Owner

remkop commented Jan 16, 2019

I will update the Internationalization section of the user manual to clarify:

  • How to localize descriptions for the built-in help subcommand and its options
  • That the showDefaultValues=true directive doesn’t lend itself to easy localization and that the recommended alternative is to embed the ${DEFAULT-VALUE} variable in the localized text in the resource bundle messages

@deining
Copy link
Contributor Author

deining commented Jan 16, 2019

The I18nTest has examples of localizing the built-in help command.

Yes indeed, that's helpful. Since this file is not obvious to novice users, it would be even better to have a fully working example in the 'examples' section. I'm willing to contribute, if you don't mind. Two questions:

  • What would be the appropriate place for the example (inside the examples folder)? Since none of the existing subdirs (customhelp, mixin, models, subcommands) fits, I would propose to add a new subdir 'i18n'. Do you agree?
  • I intend to add one .java example file and 2 properties file (default + German). Is that fine?

@remkop
Copy link
Owner

remkop commented Jan 16, 2019

That would be great, thank you!
Agreed on both proposals.

@remkop
Copy link
Owner

remkop commented Jan 19, 2019

@deining, how is it going? Let me know if you need any help.

@remkop
Copy link
Owner

remkop commented Jan 19, 2019

I added an extra test and updated the Internationalization section of the user manual.

@deining
Copy link
Contributor Author

deining commented Jan 19, 2019

Thanks for your efforts, everything is fine for me now.
I try to add a fully working example soon.

@remkop
Copy link
Owner

remkop commented Feb 1, 2019

If you don't mind I will close this ticket.
Additional PRs are always welcome! :-)

@remkop remkop closed this as completed Feb 1, 2019
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

2 participants