Page 1 of 3

Translation on server side based on current player, not client?

Posted: 04 November 2020, 14:24
by MikeIsHere
I am translating something before it gets sent to the notification. However this is what BGA recommends and other projects use as a design pattern

en.doc.boardgamearena.com/Translations#On_server_side_.28PHP.29

notif=clienttranslate("foo");
self::notifyAllPlayers( 'log', notif); // GOOD

cribbage code

Code: Select all

$this->translations = array(
"pair_score_info" => clienttranslate('${player_name} scores a pair for 2 points'),
"trips_score_info" => clienttranslate('${player_name} scores trips for 6 points'),
"quads_score_info" => clienttranslate('${player_name} scores quads for 12 points'),
"run_score_info" => clienttranslate('${player_name} scores a run for ${points} points'),
"fifteen_score_info" => clienttranslate('${player_name} scores a 15 for 2 points'),
"thirtyone_score_info" =>clienttranslate('${player_name} scores a 31 for 2 points'),

"pair_score_text" => clienttranslate('Pair for 2 points'),
"trips_score_text" => clienttranslate('Trips for 6 points'),
"quads_score_text" => clienttranslate('Quads for 12 points'),
"run_score_text" => self::_("Run for %s points"),
"fifteen_score_text" => clienttranslate('15 for 2 points'),
"thirtyone_score_text" => clienttranslate('31 for 2 points'),
"runningTotal" => clienttranslate('Running Total ${total}'),

"flush_hand" => self::_("Flush for %s "),
"nobs_hand" => self::_("Nobs for %s "),
"fifteen_hand" => self::_("15 for %s "),
"pair_hand" => self::_("Pair for %s "),
"run_hand" => self::_("Run for %s "),
"hand_total" => clienttranslate('Player ${player_name} has scored ${points} points with their ${hand}:<br/>${details}'),

"crib"=>clienttranslate('Crib'),
"hand"=>clienttranslate('Hand'),
"cutCard"=>clienttranslate('Cut Card'),

"cutDraw" => clienttranslate('... it\'s a tie, redraw'),
"cutWin" => self::_("%s wins"),
"cutDetail" => clienttranslate('${Player1Name} cut ${card1}, ${Player2Name} cut ${card2}, ${message}')


);
Some are clienttranslate if it is a pass through
some are _ if it is a variable replacement

An example of variable replacement is

Code: Select all

            $run_points = self::findRun($copy_cards);
            if ($run_points > 0) {
                // score
                self::notifyAllPlayers('score', $this->translations["run_score_info"], array (                
                    'player_id' => $player_id,                
                    'player_name' => self::getActivePlayerName(),
                    'points' => $run_points,
                    'score_text' => sprintf($this->translations["run_score_text"], $run_points)
                ));
                $pointsScored += $run_points;
 
However something unexpected is happening, the same text is only being translated based on the player who made the play. Not the player who gets the notification.

https://imgur.com/a/UR1bfov

As I am typing I am thinking the javascript may be the issue

Code: Select all

dojo.place(
                    this.format_block('jstpl_scorePeg', {
                        id: id,
                        scoreText:notify.args.score_text + ' '
                    } ), 'playertablename_'+notify.args.player_id);

What am I doing wrong and what is the correct way to pass text from server to client THEN translate it (if that is the issue)

Re: Translation on server side based on current player, not client?

Posted: 04 November 2020, 14:56
by RicardoRix
If you want a variable then you can do the same as you've done with ${player_name}.

See card_name below:

Code: Select all

  self::notifyAllPlayers( "cardPlayed", clienttranslate( '${player_name} plays ${card_name}' ), array(
            'player_id' => $player_id,
            'player_name' => self::getActivePlayerName(),
            'card_name' => $card_name,
You could probably simplify all the different scoring strings, just do a translate for each of, 'pair' 'triple', 'quads'.

Re: Translation on server side based on current player, not client?

Posted: 04 November 2020, 14:58
by MikeIsHere
But what about a variable name, in the args, that are not part of the original notification

in my example
$this->translations["run_score_info"]
is fine because that is the log notification

but

'score_text' => sprintf($this->translations["run_score_text"], $run_points)

is an arg that is used to create an html element

Re: Translation on server side based on current player, not client?

Posted: 04 November 2020, 15:46
by RicardoRix
I think you should just be able to pass an additional variable in the notification.
'score_text' => clienttranslate('test')
and get it on the JS side with notig.args.score_text


I would also think you can ditch the sprintf and just use a ${score}

Re: Translation on server side based on current player, not client?

Posted: 06 November 2020, 14:30
by MikeIsHere
not sure substitution works out side of the main parameter

Example

Code: Select all

$this->translations = array(          
             "cutWin" => clienttranslate('{$playerCutName} wins'),
             "cutDetail" => clienttranslate('${Player1Name} cut ${card1}, ${Player2Name} cut ${card2}, ${message}')
             

        );
...
$message = $this->translations["cutWin"]; 
...
self::notifyAllPlayers('cutDeal', $this->translations["cutDetail"], array(
            'Player1Name' => self::getPlayerNameById($card1['location_arg']),
            'card1' => self::cardValue($card1),
            'Player2Name' => self::getPlayerNameById($card2['location_arg']),
            'card2' => self::cardValue($card2),
            'message' => $message
        ));
Result is
${playerCutName} wins (w/o substitution)


similarly

Code: Select all

$this->translations = array(          
"run_score_text" => clienttranslate('Run for ${run_points} points'),

);


$run_points = self::findRun($copy_cards);
            if ($run_points > 0) {
                // score
                self::notifyAllPlayers('score', $this->translations["run_score_info"], array (                
                    'player_id' => $player_id,                
                    'player_name' => self::getActivePlayerName(),
                    'points' => $run_points,
                    'score_text' => $this->translations["run_score_text"]
                ));
                $pointsScored += $run_points;

                // break
                break;
            } 
            

Result is
Run for ${run_points} points

using double quotes creates a compile error because the variable is not defined yet.

If this is the way to go then I can't globally define my strings?

Re: Translation on server side based on current player, not client?

Posted: 06 November 2020, 15:24
by Tisaac
But you are not giving the value of the variable in the arg as RIcardoRix suggested !
The name of the variable should match the one in the data !

Code: Select all

$this->translations = [
  "run_score_text" => clienttranslate('Run for ${run_points} points'),
];

$run_points = self::findRun($copy_cards);
if ($run_points > 0) {
   self::notifyAllPlayers('score', $this->translations["run_score_info"], [
     'player_id' => $player_id,                
     'player_name' => self::getActivePlayerName(),
     'run_points' => $run_points,  // Use run_poins as the key here !!!
     'score_text' => $this->translations["run_score_text"]
  ]);

Re: Translation on server side based on current player, not client?

Posted: 17 November 2020, 00:07
by MikeIsHere
Yeah that still did not work

only
"run_score_text" => clienttranslate('Run for %s points'),
...
sprintf($this->translations["run_score_text"], $run_points)

works

"run_score_text" => clienttranslate('Run for ${points}, points'),

self::notifyAllPlayers('score', $this->translations["run_score_info"], array (
'player_id' => $player_id,
'player_name' => self::getActivePlayerName(),
'points' => $run_points,
'score_text' => $this->translations["run_score_text"]
));
does not,
but I have a bigger issue, none of the client messages are getting translated

so even the simple
"fifteen_score_text" => clienttranslate("15 for 2 points"),

self::notifyAllPlayers('score', $this->translations["fifteen_score_info"], array (
'player_id' => $player_id,
'player_name' => self::getActivePlayerName(),
'points' => 2,
'score_text' => $this->translations["fifteen_score_text"]
));

does not have the << >> around them in studio, representing that, that text would be translated.

Re: Translation on server side based on current player, not client?

Posted: 17 November 2020, 00:33
by XCID
So, in your last example, what is the content of
$this->translations["fifteen_score_info"]?

Re: Translation on server side based on current player, not client?

Posted: 17 November 2020, 15:09
by shadowphiar
MikeIsHere wrote: 17 November 2020, 00:07 does not have the << >> around them in studio, representing that, that text would be translated.
To translate some of the arguments sent in a notification, you need to add an entry to the args array which tells the client which of the other args contain text which must be translated. i.e.


self::notifyAllPlayers('score', $this->translations["fifteen_score_info"], array (
'player_id' => $player_id,
'player_name' => self::getActivePlayerName(),
'points' => 2,
'score_text' => $this->translations["fifteen_score_text"],
'i18n' => ['score_text']

));

Re: Translation on server side based on current player, not client?

Posted: 18 November 2020, 01:18
by MikeIsHere
Thanks that worked for the most part, there are two that still do not work


Some code

Code: Select all

        $this->translations = array(
...
            "pair_score_text" => clienttranslate('Pair for 2 points'),
            "trips_score_text" => clienttranslate('Trips for 6 points'),
            "quads_score_text" => clienttranslate('Quads for 12 points'),
            "run3_score_text" => clienttranslate('Run for 3 points'),
            "run4_score_text" => clienttranslate('Run for 4 points'),
            "run5_score_text" => clienttranslate('Run for 5 points'),
            "run6_score_text" => clienttranslate('Run for 6 points'),
            "run7_score_text" => clienttranslate('Run for 7 points'),
...

            "crib"=> clienttranslate('Crib'),
            "hand"=> clienttranslate('Hand'),
            "cribText"=> clienttranslate('Crib +${points} points'),
            "handText"=> clienttranslate('Hand +${points} points'),            
This gets translated

Code: Select all

            $score_text = ($pairs == 1) ? $this->translations["pair_score_text"] : (($pairs==2) ? $this->translations["trips_score_text"] : $this->translations["quads_score_text"] );
            $info_text = ($pairs == 1) ? $this->translations["pair_score_info"] : (($pairs==2) ? $this->translations["trips_score_info"] : $this->translations["quads_score_info"] );
            self::notifyAllPlayers('score', $info_text, array (                
                'player_id' => $player_id,                
                'player_name' => self::getActivePlayerName(),
                'points' => $value,
                'pairs' => $pairs,
                'score_text' => $score_text,
                'i18n' => array('score_text')
            ));
And this

Code: Select all

        self::notifyAllPlayers('scoreHand', $this->translations["hand_total"], array(
            'player_id' => $player_id,
            'player_name' => $player_name,
            'points' => $points,
            'hand' => ($crib ? $this->translations["crib"] : $this->translations["hand"]),
            'details' => implode("<br/>", $scoringDetail),
            'i18n' => array('hand')
        ));
But not this

Code: Select all

                $run_text = $this->translations["run" . $run_points . "_score_text"];
                self::notifyAllPlayers('score', $this->translations["run_score_info"], array (                
                    'player_id' => $player_id,                
                    'player_name' => self::getActivePlayerName(),
                    'points' => $run_points,
                    'score_text' => $run_text,
                    'i18n' => array('score_text')
                ));
Nor this

Code: Select all

        $handString = ($crib ? $this->translations["cribText"] : $this->translations["handText"]);
        self::notifyAllPlayers('showHand', '', array(
            'cards'=> $cards,
            'player_id' => $player_id,
            'player_name' => $player_name,
            'player_color' => $player_color,
            'handText' => $handString,
            'points' => $points,
            'i18n' => array('handText')
        ));