Tweak a localization to remove any assumption on "+" localization#19473
Tweak a localization to remove any assumption on "+" localization#19473mokagio merged 4 commits intorelease/21.0from
Conversation
| switch (difference > 0, differencePercent != 0) { | ||
| case (true, true): // E.g.: +1.2k (5%) | ||
| stringFormat = NSLocalizedString( | ||
| "insights.visitorsLineChartCell.differenceLabelPosiviteWithPercentage", |
There was a problem hiding this comment.
| "insights.visitorsLineChartCell.differenceLabelPosiviteWithPercentage", | |
| "insights.visitorsLineChartCell.differenceLabelPositiveWithPercentage", |
| // We cannot assume every locale would translate an English string like "+1.2k" in the same way. | ||
| // So, even though we have only a "+" prefix, we ought to make this string localized. | ||
| stringFormat = NSLocalizedString( | ||
| "insights.visitorsLineChartCell.differenceLabelPosiviteWithoutPercentage", |
There was a problem hiding this comment.
| "insights.visitorsLineChartCell.differenceLabelPosiviteWithoutPercentage", | |
| "insights.visitorsLineChartCell.differenceLabelPositiveWithoutPercentage", |
| ) | ||
| case (false, true): // E.g. 1.2k (5%) | ||
| stringFormat = NSLocalizedString( | ||
| "insights.visitorsLineChartCell.differenceLabelNotPosiviteWithPercentage", |
There was a problem hiding this comment.
| "insights.visitorsLineChartCell.differenceLabelNotPosiviteWithPercentage", | |
| "insights.visitorsLineChartCell.differenceLabelNonPositiveWithPercentage", |
Or (depending on @staskus 's reply to your answer in the PR description about why we don't use negative sign in the copy):
| "insights.visitorsLineChartCell.differenceLabelNotPosiviteWithPercentage", | |
| "insights.visitorsLineChartCell.differenceLabelNegativeWithPercentage", |
|
Thank you for the fixes! I'll review it now.
We do show negative signs. Negative numbers, both absolute and percentages appear with a "-" automatically when they're negative numbers. So it wasn't explicitly included in the localization. However, to be explicit from the localization POV, we could pass |
| differenceSign, | ||
| difference.abbreviatedString() | ||
| ) | ||
| case (false, true): // E.g. 1.2k (5%) |
There was a problem hiding this comment.
So yes, if we want to be explicit about the localization negative case, then we should handle cases when difference == 0 and difference < 0 differently:
difference == 0no signdifference < 0negative sign in a localization, passabs(difference).abbreviatedString()
I think that would be the best course of action, consistent with the rationale applied for the It's too late in my day. If no one gets to this before me, I'll look at this ASAP tomorrow. |
Actually, I'm not sure if this would be a better approach compared to using a Actually, while we're at it, we should even use an For example, I think this should do it without even requiring manual (NSLocalizedString) localization at all, just letting it all to the system to handle all cases var differenceLabel: String {
var string: String
let formatter = NumberFormatter()
formatter.positivePrefix = formatter.plusSign // Enforce + sign if value is positive
string = formatter.string(from: difference as NSNumber) ?? ""
if differencePercent != 0 {
formatter.numberStyle = .percent
formatter.positivePrefix = "" // Reset the + prefix for the percentage value. Or should we?
string += formatter.string(from: differencePercent as NSNumber).map { " (\($0))" } ?? ""
}
return string
}[EDIT] Oh wait, doing so won't output Ok, so if you want the k you might rely on MeasurementFormatter instead……and a dimensionless @objc class VisitCount: Unit {
override init(symbol: String) { super.init(symbol: symbol) }
@available(*, unavailable)
required init(coder: NSCoder) { fatalError("Unimplemented") }
static func measurement(from count: Int) -> Measurement<VisitCount> {
switch abs(count) {
case 0..<1_000:
return Measurement(value: Double(count), unit: VisitCount(symbol: ""))
case ..<1_000_000:
let symbol = NSLocalizedString("visit.count.prefix.thousand", value: "k")
return Measurement(value: Double(count/1_000), unit: VisitCount(symbol: symbol)
default:
let symbol = NSLocalizedString("visit.count.prefix.millions", value: "M")
return Measurement(value: Double(count/1_000_000), unit: VisitCount(symbol: symbol))
}
}
}
struct StatsSegmentedControlData {
…
let difference: Int
let differencePercent: Int
…
var differenceLabel: String {
var string: String
let nf = NumberFormatter()
nf.positivePrefix = nf.plusSign // Enforce + sign if value is positive
let mf = MeasurementFormatter()
mf.numberFormatter = nf
let differenceMeasurement = VisitCount.measurement(from: difference)
string = mf.string(from: differenceMeasurement)
if differencePercent != 0 {
nf.numberStyle = .percent
// nf.positivePrefix = "" // Reset the + prefix for the percentage value. Or should we?
string += nf.string(from: Double(differencePercent)/100.0 as NSNumber).map { " (\($0))" } ?? ""
}
return string
}
}But going with that solution might start to go a bit astray from the current implementation and kind of re-inventing the If our |
Thanks for putting your thought into it 👍 I agree, handling all these additional cases manually seems like a stretch at the moment, especially given that a lot of the localization logic is already built in. We could:
Working code example |
|
Sounds like a good compromise. Only change I'd make to your code example is to use positional placeholders for the [See also internal ref pbMoDN-1Df-p2 for more documentation/tips about our suggested practices about localization and positional placeholder] |
Generated by 🚫 dangerJS |
| let stringFormat = NSLocalizedString( | ||
| "insights.visitorsLineChartCell.differenceLabelWithoutPercentage", | ||
| value: "%@%@", | ||
| comment: "Difference label for Insights Overview stat, indicating change from previous period. Example: +99.9K" | ||
| value: "%1$@%2$@", | ||
| comment: "Text for the Insights Overview stat difference label. Shows the change from the previous period. E.g.: +12.3K. %1$@ is the placeholder for the change sign ('-', '+', or none). %2$@ is the placeholder for the change numerical value." | ||
| ) | ||
| return String.localizedStringWithFormat( | ||
| stringFormat, | ||
| differenceSign, | ||
| plusSign, | ||
| difference.abbreviatedString() | ||
| ) |
There was a problem hiding this comment.
I based this off @staskus suggestion but I decided to use a localized string in the case without the percentage as well, so that translators can apply the appropriate RTL.
I'm not actually sure whether that's necessary, though.
Maybe we should lean into NumberFormatter more for this? There's definitely rooms for improvement and internal refactors. The new tests added in this diff will help us with that in the future.
There was a problem hiding this comment.
Thanks for the fix. 👍 I think the solution makes sense. We improved it by using numbered positions, localized plus signs, and most importantly, having localized strings static and not dynamic.
You can test the changes in Jetpack from this Pull Request by:
|
You can test the changes in WordPress from this Pull Request by:
|
staskus
left a comment
There was a problem hiding this comment.
Thank you for the work and additional tests 🙏
LGTM, I reviewed the code and tested the solution.
|
Dismissed Olivier's review because I did my best to address the existing concerns, have received another approval, and want to get the code freeze merged into Proceeding to merge now. If we missed anything, we can always issue a new round of localizations. |
Dismissed Olivier's review because I did my best to address the existing concerns, have received another approval, and want to get the code freeze merged into trunk (for which this PR is a required step) ASAP.
See discussion at #19472 (comment).
I opened a dedicated PR for this instead of committing directly to the release branch because the change is big and I didn't want to let a mistake land directly in the release branch.
Notice daec387 which successfully updates the
.stringsvia thegenerate_strings_file_for_glotpresslane. I made this as part of this PR to verify my changed was correct, as far as our tooling, or rathergenstring, goes.@staskus you have more context on this than I do. I think I implemented a 1-1 version of the end result that e3c3e41 would have produced. Still, why don't we show a minus sign,
-, when the difference is less than 0?