Two things a translator cannot fix (FluentCommunity 2.9.0, FluentPlayer Pro 1.4.0)
Posting this as a translator again. Same setup as before: I maintain the German
catalogues for FluentCommunity, FluentCommunity Pro, FluentMessaging and
FluentPlayer, a little over 5,000 strings, and I check every string against the
rendered page rather than against the return value of __().
Two findings from going through 2.9.0. The first is a small UI slip, the second
is a string that cannot be translated correctly in any language, and it affects
two of your products with the same code.
1. A preference row that renders with no control at all
Where: member profile, notification preferences.
The table has one row per event. Four of the five rows offer an email checkbox,
a push checkbox, or both. The fifth offers neither, and looks like a bug to the
member.
The row is co_comment β Someone also comments on a post I commented on. It
is push-only by design, and that design is consistent in both layers:
// app/Services/NotificationPref.php:31-36
const NOTIFICATION_EVENTS = [
'comment' => ['mail' => 'com_my_post_mail', 'push' => 'com_my_post_push'],
'reply' => ['mail' => 'reply_my_com_mail', 'push' => 'reply_my_com_push'],
'mention' => ['mail' => 'mention_mail', 'push' => 'mention_push'],
'co_comment' => ['push' => 'co_com_push'],
'digest' => ['mail' => 'digest_mail']
];
// app.js, NotificationPref component, computed channelRows
{ key: "co_comment",
label: this.$t("Someone also comments on a post I commented on"),
push: "co_com_push" } // no mail key, unlike the other four
The template renders the email cell only when row.mail is set, which is right.
The push column, however, is hidden as a whole when push is not available:
showPush() { return this.push_available }
and push_available comes from PushNotificationModule::isAvailable(), which
requires FluentNotify to be installed and configured, on top of
push_enabled being yes in FluentCommunity:
public static function isAvailable()
{
$pushEnabledInCommunity = Arr::get(Utility::getPushNotificationSettings(), 'push_enabled') === 'yes';
return self::isFluentNotifyActive() && $pushEnabledInCommunity;
}
So on every site that has not set up FluentNotify β which is every site right
after updating to 2.9.0, since push_enabled already defaults to yes β that
row appears with its label and two empty cells. Nothing to click, no
explanation.
Suggestion: drop rows from channelRows that have no visible channel left.
Something like
visibleChannelRows() {
return this.channelRows.filter(row => row.mail || (row.push && this.showPush))
}
and render that instead. If you would rather keep the row visible as a teaser
for push, a short hint in the empty cell would do the same job and would tell
the member what is missing.
I mention it here because from the outside it reads as a translation problem β
"the German label is there but the checkbox is gone" β and it is the kind of
thing a site owner reports to the translator first.
2. The expired-license message is assembled from hardcoded English
Where: FluentLicensing::getExpireMessage(), in both
fluent-player-pro and fluent-community-pro.
// fluent-player-pro/app/Services/PluginManager/FluentLicensing.php:316-322
$expired = $expiresAt
? __('expired at', 'fluent-player-pro') . ' ' . gmdate('d M Y', $expiresAt)
: __('expired', 'fluent-player-pro');
return '<p>Your ' . $this->getConfig('plugin_title') . ' ' . __('license has been', 'fluent-player-pro') . ' <b>' . $expired . '</b>, Please ' .
'<a href="' . esc_url($renewUrl) . '"><b>' . __('Click Here to Renew Your License', 'fluent-player-pro') . '</b></a>' . '</p>';
fluent-community-pro/app/Services/PluginManager/FluentLicensing.php:316 is the
same line with a different text domain.
Three separate problems in one sentence:
Yourand, Pleaseare not translatable. Whatever the fragments become,
the sentence stays half English.- The word order is fixed by concatenation. German puts the date and the
participle in a different place than English does; there is no arrangement of
license has been+expired at <date>that produces a correct German
sentence, because the pieces cannot move past each other. gmdate('d M Y')always renders English month abbreviations, regardless of
locale.date_i18n()is the drop-in replacement.
This is not hypothetical, and it is not only about German. Your own bundled
Spanish pack translates the fragments faithfully:
'license has been' => 'la licencia ha sido',
'expired at' => 'expirado el',
which renders as:
Your FluentCommunity Pro la licencia ha sido expirado el 12 Jan 2026,
Please Click aquΓ para renovar tu licencia
Every translator who touches these four fragments produces something like that,
because there is no other option available to them.
Suggestion: one string per case, with placeholders, so the translator owns
the whole sentence:
$renewLink = '<a href="' . esc_url($renewUrl) . '"><b>' .
__('Renew your license', 'fluent-player-pro') . '</b></a>';
if ($expiresAt) {
// translators: 1: product name, 2: expiry date, 3: link that says "Renew your license"
$message = sprintf(
__('Your %1$s license expired on %2$s. Please %3$s.', 'fluent-player-pro'),
$this->getConfig('plugin_title'),
date_i18n(get_option('date_format'), $expiresAt),
$renewLink
);
} else {
// translators: 1: product name, 2: link that says "Renew your license"
$message = sprintf(
__('Your %1$s license has expired. Please %2$s.', 'fluent-player-pro'),
$this->getConfig('plugin_title'),
$renewLink
);
}
That is four fragments replaced by two full sentences and one link label, and it
costs the existing translations nothing worth keeping.
One thing worth checking while you are in that file: the FluentCommunity Pro
version calls strtotime($licenseData['expires']) unguarded, where the
FluentPlayer Pro version has learned to handle an empty expires for lifetime
licenses. A lifetime FluentCommunity Pro license would render 01 Jan 1970.
Happy to send a PR for either of these if that is easier for you.
Forwarded both to the team. Will be fixed/improved in the next version.
Wo kann ich Deine Γbersetzungen bekommen?
Moin Julian Brinke, ich werde ein ΓΆffentliches GitHub-Repo dafΓΌr einrichten.
Ich lΓΆse das mit einem WordPress-Plugin, weil bestimmte Strings nicht direkt ΓΌbersetzbar sind und meine Γbersetzung statt der aus der WordPress-Community angezeigt werden soll.
Merkmale: Du-Anrede, Space wird als Forum ΓΌbersetzt.
Alles ΓΌbersetzt, KI-gestΓΌtzt ein eigenes Glossar angelegt, damit die Γbersetzung konsistent bleibt. Viele Texte verbessert und verstΓ€ndlicher formuliert.
Peter Claus LamprechtΒ mega - Danke
weiΓt Du ob sowas oder in Γ€nlich auch schon fΓΌr FluentCart gibt?
Julian Brinke, ich pflege eine Γbersetzung fΓΌr FluentCart, da gibt es aber noch ein paar Dinge, die nicht ΓΌbersetzbar sind; Bug-Reports sind drauΓen. Zwei Varianten: Du- und Sie-Form. Da zΓΆgere ich, das freizugeben, weil das teilweise Texte mit rechtlicher Bedeutung sind.
Peter Claus LamprechtΒ verstehe,
hatte mal fΓΌr ein Projekt alles in Du-Form nur die Rechtstexte in Sie- Formβ¦
ist meiner Meinung nach die sauberste aber nicht die einfachste LΓΆsung :)
Julian Brinke, schau mal hier: https://github.com/blocoder/pcl-fluent-de.
Peter Claus LamprechtΒ Ich liebe es
Du mit groΓem D - einfach geil
Danke!!!!
Julian Brinke, vielen Dank. Wenn Dir etwas auffΓ€llt oder Du WΓΌnsche hast, melde Dich gern.
Julian Brinke, ich habe noch ein Update nachgelegt (1.5.0). Damit kannst Du direkt im WordPress-Backend kΓΌnftige Updates nachladen.
sehr schΓΆn