Please upgrade here. These earlier versions are no longer being updated and have security issues.
HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

Translation Issues

edited September 2009 in Vanilla 2.0 - 2.8
Hi Vanilla Team + folks,
I am trying the Vanilla 2 beta on my server, and wanted to translate it to German.

Following the post I figured out how to get the strings for the translation. I changed all definitions within definitions.php to my language, e. g. $Definition['Welcome, %s!'] = 'Willkommen, %s!';

It works fine, however:

Issue 1

Some language strings are missing, I cannot find them (and thus don't know how to overwrite them in definitions.php):

- [in Activity] -> "changed your profile picture".
- [Search-Box input field] -> "Search"
- [discussion] "Cancel" button
- [activity] "Comment" button
- [profile] tab 'Activity'
- and "Remember me on this computer"

Edit: See solutions below!

Issue 2

BUG "Tab-Link-Bug caused by translation": I put this into the issue tracker at

Issue 3

How can I actually change the time format from am/pm to 24 hours? Could not find an option.

Thanks guys for the great beta!
If we fix some more things, beta will be gone soon ;)


  • for issue 3:

    Maybe by changing the configuration:

    The default parameters are:
    $Configuration['Garden']['DefaultDateFormat'] = 'F j, Y'; $Configuration['Garden']['DefaultDayFormat'] = 'F j'; $Configuration['Garden']['DefaultYearFormat'] = 'F Y'; $Configuration['Garden']['DefaultTimeFormat'] = 'g:ia';

  • edited September 2009
    @bean: Thanks, issue 3 solved!

    Add the following lines to \vanilla\conf\config.php

    German format would look like this:

    $Configuration['Garden']['DefaultDateFormat'] = 'j. F Y'; $Configuration['Garden']['DefaultDayFormat'] = 'j. F'; $Configuration['Garden']['DefaultYearFormat'] = 'F Y'; $Configuration['Garden']['DefaultTimeFormat'] = 'H:i';

    This helps on more formats:
  • @kaikajus: You should put your changes in config.php, not in config-defaults.php as this file is part of the release.

  • edited September 2009
    Can somebody help on translation issue 1?
  • Solved link bug, the solution is here

    @Mark + Vanilla team: Could you consider this for the next release please?

    Good morning greetings from Berlin!
    Kai Kajus
  • edited September 2009
    Alright, I found way more translations that have to be implemented:

    1. registerbasic.php | registercaptcha.php | registerinvitation.php
    OLD: echo $this->Form->CheckBox('RememberMe', 'Remember me on this computer', array('value' => '1'));
    NEW: echo $this->Form->CheckBox('RememberMe', Gdn::Translate('Remember me on this computer'), array('value' => '1'));

    2. signin.php
    OLD: echo $this->Form->CheckBox('RememberMe', 'Remember me on this computer', array('value' => '1', 'id' => 'SignInRememberMe'));
    NEW: echo $this->Form->CheckBox('RememberMe', Gdn::Translate('Remember me on this computer'), array('value' => '1', 'id' => 'SignInRememberMe'));

    3. guest.php | index.php (vanilla/views/discussion)
    OLD: echo Anchor('Register For Membership', $Url, 'Button');
    NEW: echo Anchor(Gdn::Translate('Register for Membership'), $Url, 'Button');

    4. guest.php
    OLD: <?php echo Anchor('Sign In', Gdn::Authenticator()->SignInUrl($this->_Sender->SelfUrl), 'Button'); ?>
    NEW: <?php echo Anchor(Gdn::Translate('Sign In'), Gdn::Authenticator()->SignInUrl($this->_Sender->SelfUrl), 'Button'); ?>

    5. discussion.php (vanilla/views/post)
    OLD: echo Anchor('Cancel', $CancelUrl, 'Cancel');
    NEW: echo Anchor(Gdn::Translate('Cancel'), $CancelUrl, 'Cancel');

    6. vanilla_post_reply.php
    OLD: echo Anchor('Cancel', '/vanilla/discussion/'.$this->ReplyComment->DiscussionID, 'Cancel');
    NEW: echo Anchor(Gdn::Translate('Cancel'), '/vanilla/discussion/'.$this->ReplyComment->DiscussionID, 'Cancel');

    7. class.usermodel.php
    OLD: $this->Validation->AddValidationResult('Name', 'The name you entered is already in use by another member.');
    NEW: $this->Validation->AddValidationResult('Name', Gdn::Translate('The name you entered is already in use by another member.') );

    OLD: $this->Validation->AddValidationResult('Email', 'The email you entered in use by another member.');
    NEW: $this->Validation->AddValidationResult('Email', Gdn::Translate('The email you entered in use by another member.') );

    8. class.invitationmodel.php
    OLD: $this->Validation->AddValidationResult('Email', 'The email you have entered is already related to an existing account.');
    NEW: $this->Validation->AddValidationResult('Email', Gdn::Translate('The email you have entered is already related to an existing account.') );

    OLD: $this->Validation->AddValidationResult('Email', 'An invitation has already been sent to the email you entered.');
    NEW: $this->Validation->AddValidationResult('Email', Gdn::Translate('An invitation has already been sent to the email you entered.'));

    9. newconversation.php
    OLD: echo Anchor('Start a New Conversation', '/messages/add', 'NewConversation');
    NEW: echo Anchor(Gdn::Translate('Start a New Conversation'), '/messages/add', 'NewConversation');

    10. user.php
    OLD: echo ' - ' . Anchor('Clear', '/profile/clear/'.$Session->TransientKey());
    NEW: echo ' - ' . Anchor(Gdn::Translate('Clear'), '/profile/clear/'.$Session->TransientKey());

    11. clearhistory.php
    OLD: echo Anchor('Clear Conversation History', '/messages/clear/'.$this->ConversationID, 'ClearConversation');
    NEW: echo Anchor(Gdn::Translate('Clear Conversation History'), '/messages/clear/'.$this->ConversationID, 'ClearConversation');

    12. global.js (3 times)
    OLD: var searchText = definition('Search', 'Search');
    NEW: var searchText = definition('Search', 'yourTRANSLATION');
    Regarding the global.js, the question arose if there is a javascript way to access the translations from definitions.php?!

    Hope the work will be of help!
  • edited September 2009
    For the translation injection for the Activities I encountered a problem, file structure.php in applications/garden/settings:

    e.g. there is no effect after changing:

    $SQL->Insert('ActivityType', array('AllowComments' => '1', 'Name' => 'PictureChange', 'FullHeadline' => '%1$s changed %6$s profile picture.', 'ProfileHeadline' => '%1$s changed %6$s profile picture.'));
    // TO
    $SQL->Insert('ActivityType', array('AllowComments' => '1', 'Name' => 'PictureChange', 'FullHeadline' => Gdn::Translate('%1$s changed %6$s profile picture.'), 'ProfileHeadline' => Gdn::Translate('%1$s changed %6$s profile picture.') ));
    Checking the SQL database shows me that "GDN_ActivityType" is holding all strings that have to be translated.

    So how can we solve that?
  • MarkMark Vanilla Staff
    Awesome work! Any chance of getting it in the form of a pull request on github?

    As for the activity type strings, we can translate them before spitting them out (in the Format class).
  • edited October 2009
    @Mark: "translate them before spitting them out (in the Format class)." - awesome tip :) have done that.

    OLD: return sprintf($ProfileUserID == $Activity->ActivityUserID || $ProfileUserID == '' ? $Activity->FullHeadline : $Activity->ProfileHeadline, $ActivityName, $ActivityNameP, $RegardingName, $RegardingNameP, $RegardingWall, $Gender, $Gender2, $Route); NEW: return sprintf($ProfileUserID == $Activity->ActivityUserID || $ProfileUserID == '' ? Gdn::Translate($Activity->FullHeadline) : Gdn::Translate($Activity->ProfileHeadline), $ActivityName, $ActivityNameP, $RegardingName, $RegardingNameP, $RegardingWall, $Gender, $Gender2, $Route);

    One remark: Since Vanilla-2 is using placeholders within the syntax, e.g.
    %1$s changed %6$s profile picture.
    their might be problems with other languages. In German the verb is changing as well:

    user1 changed his profile picture → user1 hat sein Profilbild geändert

    you changed your profile picture → du hast dein Profilbild

    I can find workarounds for that, but you like to consider other languages that are even more problematic!


    Regarding the "request on github"

    I have to check github, it's new for me. But will try so on the weekend.

    Have a great day,
  • edited October 2009
    Additional changes (I guess we are nearly done):

    1. library/core/class.format.php

    OLD: $Gender = Translate($Activity->ActivityGender == 'm' ? 'his' : 'her'); $Gender2 = Translate($Activity->ActivityGender == 'm' ? 'he' : 'she'); NEW: $Gender = Translate($Activity->ActivityGender == 'm' ? Gdn::Translate('his') : Gdn::Translate('her') ); $Gender2 = Translate($Activity->ActivityGender == 'm' ? Gdn::Translate('he') : Gdn::Translate('she') ); OLD: $Gender = $Gender2 = 'your'; NEW: $Gender = $Gender2 = Gdn::Translate('your'); OLD: $Route = Anchor($Activity->RouteCode, $Activity->Route); NEW: $Route = Anchor(Gdn::Translate($Activity->RouteCode), $Activity->Route);

    2. applications/garden/views/activity/helper_functions.php

    OLD: echo Anchor('Delete', 'garden/activity/delete/'.$Activity->ActivityID.'/'.$Session->TransientKey().'?Return='.urlencode(Gdn_Url::Request()), 'Delete'); NEW: echo Anchor(Gdn::Translate('Delete'), 'garden/activity/delete/'.$Activity->ActivityID.'/'.$Session->TransientKey().'?Return='.urlencode(Gdn_Url::Request()), 'Delete'); OLD: echo $Activity->AllowComments == '1' && $Session->IsValid() ? '<span>&bull;</span>'.Anchor('Comment', '#CommentForm_'.$Activity->ActivityID, 'CommentOption') : ''; NEW: echo $Activity->AllowComments == '1' && $Session->IsValid() ? '<span>&bull;</span>'.Anchor(Gdn::Translate('Comment'), '#CommentForm_'.$Activity->ActivityID, 'CommentOption') : ''; OLD: echo $Activity->AllowComments == '1' && $Session->IsValid() ? '<span>&bull;</span>'.Anchor('Comment', '#CommentForm_'.$Activity->ActivityID, 'CommentOption') : ''; NEW: echo $Activity->AllowComments == '1' && $Session->IsValid() ? '<span>&bull;</span>'.Anchor(Gdn::Translate('Comment'), '#CommentForm_'.$Activity->ActivityID, 'CommentOption') : ''; OLD: echo $Session->UserID == $Comment->InsertUserID || $Session->CheckPermission('Garden.Activity.Delete') ? '<span>&bull;</span>'.Anchor('Delete', 'garden/activity/delete/'.$Comment->ActivityID.'/'.$Session->TransientKey().'?Return='.urlencode(Gdn_Url::Request())) : ''; NEW: echo $Session->UserID == $Comment->InsertUserID || $Session->CheckPermission('Garden.Activity.Delete') ? '<span>&bull;</span>'.Anchor(Gdn::Translate('Delete'), 'garden/activity/delete/'.$Comment->ActivityID.'/'.$Session->TransientKey().'?Return='.urlencode(Gdn_Url::Request())) : '';
  • edited October 2009
    yeah we need german text!!!!!!!!!!
    edit: I am ready for support.
  • MarkMark Vanilla Staff
    @kaikajus - Thanks so much for your input. We really need help with the translations as neither of the core developers are multi-lingual.
  • I'm still a bit sick so cannot promise the "github work" for this week :(
    Hope to be fit again next week.
  • edited October 2009
    hi all can i translate the script to kurdish

    because it is the greate script
    vanilla vs punbb and phpbb

    vanilla is win
  • helo who can answar me
  • MarkMark Vanilla Staff
    @kurdistanboy - We haven't got the translation site built yet. Once it is, you'll be able to access it from the menu up above, and you'll be able to add your translation right here on this site.
  • SS ✭✭
    Form::CheckBox with $Label param. $Label is not tranlslating
  • I thinke fixing Form::CheckBox is the best way!
    OLD: if ($Label != '') $Input = '<label for="' . ArrayValueI('id', $Attributes, $this->EscapeID($FieldName, FALSE)) . '" class="CheckBoxLabel">' . $Input . ' ' . $Label . '</label>'; NEW: if ($Label != '') $Input = '<label for="' . ArrayValueI('id', $Attributes, $this->EscapeID($FieldName, FALSE)) . '" class="CheckBoxLabel">' . $Input . ' ' . Translate($Label) . '</label>';
  • SS ✭✭
    edited November 2009
    I like this construction:
    Translate('Hello, %s. Your email is %s', $Username, $Email)

    instead of sprintf(Translate('Hello, %s. Your email is %s'), $Username, $Email)
  • edited November 2009
    to Translate the Activities add: class.format.php
    public static function ActivityHeadline($Activity, $ProfileUserID = '') { $Session = Gdn::Session(); + // translate the Types + $Activity->FullHeadline = Gdn::Translate($Activity->FullHeadline); + $Activity->ProfileHeadline = Gdn::Translate($Activity->ProfileHeadline); - $RegardingWall = Anchor('wall', '/profile/activity/' . $Activity->RegardingUserID . '/' . $RegardingNameD . '#Activity_' . $Activity->ActivityID); + $RegardingWall = Anchor(Gdn::Translate('wall'), '/profile/activity/' . $Activity->RegardingUserID . '/' . $RegardingNameD . '#Activity_' . $Activity->ActivityID); - $Route = Anchor($Activity->RouteCode, $Activity->Route); + $Route = Anchor(Translate($Activity->RouteCode), $Activity->Route);
Sign In or Register to comment.