Skip to main content

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:

  • Your and , Please are 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.

Posting this as a translator again. Same setup as last time: I maintain the
German catalogues for FluentCommunity, FluentCommunity Pro, FluentMessaging and
FluentPlayer, around 5,000 strings.

This is not a bug in the sense that something breaks. It is a string that cannot
be translated correctly, because one source string has to serve several places
at once.


What happens

In the profile editor, the Short Bio field is a markdown editor without a
placeholder prop. The editor component falls back to its generic default:

placeholder: {
    text: this.placeholder || this.$t('Type your message here!'),
    mode: 'doc'
}

So the bio field prompts the member with Type your message here! – the same
sentence the editor shows everywhere else it is embedded without an explicit
placeholder.

The label above the field is fine: Short Bio, from
app/Services/TransStrings.php:1650. It is only the placeholder that is
borrowed.

Why it matters for translations

Type your message here! (app/Services/TransStrings.php:1892) is a single
catalogue entry shared by every editor instance that does not pass its own
placeholder. A translator therefore has exactly two options, and both are wrong
somewhere:

  • translate it generically, and the bio field gives the member no hint what the
    field is for, or
  • translate it for the field where it is most visible, and the same sentence
    turns up misplaced in the next editor.

Our German catalogue went through both. It used to read write your welcome
message here
– correct where a translator had seen it, wrong the moment the
same string appeared over the profile bio. It now reads generically again.

The profile form is a good candidate for its own placeholder, because it is the
one editor where members are least likely to know what is expected: a headline
of up to 60 characters sits directly above it, and without a prompt the
difference between the two fields is not obvious.

Suggestion

Give the bio editor an explicit placeholder, e.g.

'A sentence or two about yourself' => __('A sentence or two about yourself', 'fluent-community'),

and pass it as the placeholder prop on the profile editor instance. That
leaves Type your message here! for what it is, a generic default, and gives
translators a string they can render for its actual context.

The same pattern, second case

Username (app/Services/TransStrings.php:1973, Modules/Auth/AuthHelper.php:187)
serves three different places at once:

  • the field label in the signup form,
  • the placeholder of the username field in the profile editor, and
  • a column header in the CSV import preview, where the column is 110px wide.

Whatever a translator writes there has to fit a form label, a placeholder and a
narrow table header at the same time. Splitting the table column into its own
string would be enough; the signup form already has its own placeholder string
(No space or special characters), which is exactly the right shape.

Anything else on the fallback

The same applies to any other editor instance that currently relies on the
fallback – the welcome banner editor is the one we noticed.

Happy to send a PR if that is easier for you.

Hey all, anyone else having issues with notifications not saving? When my clients and I go to profiles and set notifications, they are not saving at all. Wondering if anyone else has seen this issue?

I have gone in and disabled all caching plugins, but it still did not work. What am I missing? Shahjahan JewelΒ 

Make please this box visible on Posts and Comments tabs aswell. I have different ordering and push prompt box is visible only on Bio tab.

1.00

I installed a plugin on my site, but I'm encountering a critical error that says, "There has been a critical error on this website." I removed all the plugins and tried again, but the issue persists.

Do you have any ideas on how to fix this? I can access the site when I'm not logged in, but when I log in, the error occurs.

Any help would be greatly appreciated!

The most requested feature in FluentCommunity's history ships today.

A community runs on replies. Someone answers, the asker comes back, a third person joins. Email breaks that loop: it arrives hours late, buried, or not at all. The thread goes cold and the person who answered feels ignored.

Push fixes it where it breaks. A reply lands, their phone buzzes in seconds, tab closed or not, and they are back while the thread is still alive. Every reply becomes a return; every return creates the next reply.

What you get

  • Push on desktop and mobile, powered by FluentNotify, our free plugin. Install from FluentCommunity settings, connect once, done.
  • No third-party service, no per-subscriber pricing. Your data stays on your site.
  • Members pick Email or Push per event: comments on my post, replies to my comment, mentions, and, new in 2.9.0, someone commented on a post I commented on.
  • You set the defaults for every member and place the "Never Miss a Reply" prompt in up to four spots.
  • One switch to turn push off community-wide if you ever need to.

Also in 2.9.0

  • Drag-and-drop ordering for topics and badges
  • Fluent Messaging 2.9.0: chat moderation, member search, emoji picker, endless scroll
  • Installed app now covers your whole site, pull-to-refresh on iOS
  • Full accessibility pass across portal and chat
  • Security hardening on every endpoint
  • Internal bug board at zero. Everything we know about is fixed and shipped.

Full notes: https://fluentcommunity.co/blog/fluentcommunity-2-9-0/

Full setup guide: https://docs.fluentcommunity.co/push-notifications-with-firebase

Update, turn on push notifications, and watch your threads come back to life. Please share your feedback on these new features in the comments.

Hello, is there an FC option or a plugin that allows you to share easily an FC post on social media (X, Facebook, WhatsApp, Telegram, etc.)?

Hi!
Would be nice to see the full title there. Is it possible for you to make it possible?
Thanks!

Show the full title on the Space Group

Has there finally been an official translation solution for fc that properly handles things like right-to-left alignment for Arabic , or are we still stuck in this same frustrating cycle?

I remember being here a year ago, and after looking into search again, I honestly can’t believe this still hasn’t been solved.

Hello, is there an option to report an FC post or comment to the admin as abusive, illegal, or spam?