Skip to content

Commit

Permalink
Split application translation strings and QU strings (fixes #1705)
Browse files Browse the repository at this point in the history
  • Loading branch information
berrnd committed Feb 6, 2022
1 parent 28f7700 commit 12e5377
Show file tree
Hide file tree
Showing 26 changed files with 81 additions and 58 deletions.
1 change: 1 addition & 0 deletions changelog/66_UNRELEASED_xxxx-xx-xx.md
Expand Up @@ -11,6 +11,7 @@
- Fixed that when adding missing recipe ingredients, with the option "Only check if any amount is in stock" enabled, to the shopping list, unit conversions (if any) weren't considered
- Fixed that the recipe stock fulfillment information about shopping list amounts was not correct when the ingredient had a decimal amount
- Fixed that the meal plan showed the total calories per recipe (instead of per serving as stated by the suffix)
- Fixed that when having a quantity unit matching any application string, the translation of that string was used to display that unit
- Fixed that formatted (HTML) text for the (hidden by default) product description column on the stock overview page was not correctly displayed
- Fixed that numeric and date-time sorting of table columns on the stock entries page did not work correctly (thanks @MasterofJOKers)
- Fixed that the barcode lookup for the "Stock by-barcode" API endpoints was case sensitive
Expand Down
5 changes: 3 additions & 2 deletions controllers/BaseController.php
Expand Up @@ -126,10 +126,11 @@ protected function render($response, $page, $data = [])
$this->View->set('__t', function (string $text, ...$placeholderValues) use ($localizationService) {
return $localizationService->__t($text, $placeholderValues);
});
$this->View->set('__n', function ($number, $singularForm, $pluralForm) use ($localizationService) {
return $localizationService->__n($number, $singularForm, $pluralForm);
$this->View->set('__n', function ($number, $singularForm, $pluralForm, $isQu = false) use ($localizationService) {
return $localizationService->__n($number, $singularForm, $pluralForm, $isQu);
});
$this->View->set('LocalizationStrings', $localizationService->GetPoAsJsonString());
$this->View->set('LocalizationStringsQu', $localizationService->GetPoAsJsonStringQu());

// TODO: Better handle this generically based on the current language (header in .po file?)
$dir = 'ltr';
Expand Down
12 changes: 10 additions & 2 deletions public/js/grocy.js
Expand Up @@ -232,6 +232,7 @@ U = function(relativePath)
}

Grocy.Translator = new Translator(Grocy.LocalizationStrings);
Grocy.TranslatorQu = new Translator(Grocy.LocalizationStringsQu);
__t = function(text, ...placeholderValues)
{
if (Grocy.Mode === "dev")
Expand All @@ -245,7 +246,7 @@ __t = function(text, ...placeholderValues)

return Grocy.Translator.__(text, ...placeholderValues)
}
__n = function(number, singularForm, pluralForm)
__n = function(number, singularForm, pluralForm, isQu = false)
{
if (Grocy.Mode === "dev")
{
Expand All @@ -256,7 +257,14 @@ __n = function(number, singularForm, pluralForm)
}
}

return Grocy.Translator.n__(singularForm, pluralForm, Math.abs(number), Math.abs(number))
if (isQu)
{
return Grocy.TranslatorQu.n__(singularForm, pluralForm, Math.abs(number), Math.abs(number))
}
else
{
return Grocy.Translator.n__(singularForm, pluralForm, Math.abs(number), Math.abs(number))
}
}

if (!Grocy.ActiveNav.isEmpty())
Expand Down
2 changes: 1 addition & 1 deletion public/viewjs/components/productamountpicker.js
Expand Up @@ -94,7 +94,7 @@ $(".input-group-productamountpicker").on("change", function()
var quFactor = $("#qu_id option:selected").attr("data-qu-factor");
var amount = $("#display_amount").val();
var destinationAmount = amount / quFactor;
var destinationQuName = __n(destinationAmount, $("#qu_id").attr("data-destination-qu-name"), $("#qu_id").attr("data-destination-qu-name-plural"))
var destinationQuName = __n(destinationAmount, $("#qu_id").attr("data-destination-qu-name"), $("#qu_id").attr("data-destination-qu-name-plural"), true);

if ($("#qu_id").attr("data-destination-qu-name") == selectedQuName || Grocy.Components.ProductAmountPicker.AllowAnyQuEnabled || amount.toString().isEmpty() || selectedQuName.toString().isEmpty())
{
Expand Down
4 changes: 2 additions & 2 deletions public/viewjs/components/productcard.js
Expand Up @@ -11,7 +11,7 @@ Grocy.Components.ProductCard.Refresh = function(productId)
$('#productcard-product-name').text(productDetails.product.name);
$('#productcard-product-description').html(productDetails.product.description);
$('#productcard-product-stock-amount').text(stockAmount);
$('#productcard-product-stock-qu-name').text(__n(stockAmount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural));
$('#productcard-product-stock-qu-name').text(__n(stockAmount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural, true));
$('#productcard-product-stock-value').text(stockValue + ' ' + Grocy.Currency);
$('#productcard-product-last-purchased').text((productDetails.last_purchased || '2999-12-31').substring(0, 10));
$('#productcard-product-last-purchased-timeago').attr("datetime", productDetails.last_purchased || '2999-12-31');
Expand All @@ -26,7 +26,7 @@ Grocy.Components.ProductCard.Refresh = function(productId)
if (productDetails.is_aggregated_amount == 1)
{
$('#productcard-product-stock-amount-aggregated').text(productDetails.stock_amount_aggregated);
$('#productcard-product-stock-qu-name-aggregated').text(__n(productDetails.stock_amount_aggregated, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural));
$('#productcard-product-stock-qu-name-aggregated').text(__n(productDetails.stock_amount_aggregated, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural, true));

if (productDetails.stock_amount_opened_aggregated > 0)
{
Expand Down
6 changes: 3 additions & 3 deletions public/viewjs/consume.js
Expand Up @@ -77,11 +77,11 @@

if (productDetails.product.enable_tare_weight_handling == 1 && !jsonData.exact_amount)
{
var successMessage = __t('Removed %1$s of %2$s from stock', Math.abs(jsonForm.amount - (parseFloat(productDetails.product.tare_weight) + parseFloat(productDetails.stock_amount))) + " " + __n(jsonForm.amount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural), productDetails.product.name) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoStockTransaction(\'' + bookingResponse[0].transaction_id + '\')"><i class="fas fa-undo"></i> ' + __t("Undo") + '</a>';
var successMessage = __t('Removed %1$s of %2$s from stock', Math.abs(jsonForm.amount - (parseFloat(productDetails.product.tare_weight) + parseFloat(productDetails.stock_amount))) + " " + __n(jsonForm.amount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural, true), productDetails.product.name) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoStockTransaction(\'' + bookingResponse[0].transaction_id + '\')"><i class="fas fa-undo"></i> ' + __t("Undo") + '</a>';
}
else
{
var successMessage = __t('Removed %1$s of %2$s from stock', Math.abs(jsonForm.amount) + " " + __n(jsonForm.amount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural), productDetails.product.name) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoStockTransaction(\'' + bookingResponse[0].transaction_id + '\')"><i class="fas fa-undo"></i> ' + __t("Undo") + '</a>';
var successMessage = __t('Removed %1$s of %2$s from stock', Math.abs(jsonForm.amount) + " " + __n(jsonForm.amount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural, true), productDetails.product.name) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoStockTransaction(\'' + bookingResponse[0].transaction_id + '\')"><i class="fas fa-undo"></i> ' + __t("Undo") + '</a>';
}

if (GetUriParam("embedded") !== undefined)
Expand Down Expand Up @@ -177,7 +177,7 @@ $('#save-mark-as-open-button').on('click', function(e)
}

Grocy.FrontendHelpers.EndUiBusy("consume-form");
toastr.success(__t('Marked %1$s of %2$s as opened', parseFloat(jsonForm.amount).toLocaleString({ minimumFractionDigits: 0, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_amounts }) + " " + __n(jsonForm.amount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural), productDetails.product.name) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoStockTransaction(\'' + result[0].transaction_id + '\')"><i class="fas fa-undo"></i> ' + __t("Undo") + '</a>');
toastr.success(__t('Marked %1$s of %2$s as opened', parseFloat(jsonForm.amount).toLocaleString({ minimumFractionDigits: 0, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_amounts }) + " " + __n(jsonForm.amount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural, true), productDetails.product.name) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoStockTransaction(\'' + result[0].transaction_id + '\')"><i class="fas fa-undo"></i> ' + __t("Undo") + '</a>');

if (BoolVal(Grocy.UserSettings.stock_default_consume_amount_use_quick_consume_amount))
{
Expand Down
6 changes: 3 additions & 3 deletions public/viewjs/inventory.js
Expand Up @@ -114,7 +114,7 @@
Grocy.Api.Get('stock/products/' + jsonForm.product_id,
function(result)
{
var successMessage = __t('Stock amount of %1$s is now %2$s', result.product.name, result.stock_amount + " " + __n(result.stock_amount, result.quantity_unit_stock.name, result.quantity_unit_stock.name_plural)) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoStockTransaction(\'' + bookingResponse[0].transaction_id + '\')"><i class="fas fa-undo"></i> ' + __t("Undo") + '</a>';
var successMessage = __t('Stock amount of %1$s is now %2$s', result.product.name, result.stock_amount + " " + __n(result.stock_amount, result.quantity_unit_stock.name, result.quantity_unit_stock.name_plural, true)) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoStockTransaction(\'' + bookingResponse[0].transaction_id + '\')"><i class="fas fa-undo"></i> ' + __t("Undo") + '</a>';

if (GetUriParam("embedded") !== undefined)
{
Expand Down Expand Up @@ -384,7 +384,7 @@ $('#display_amount').on('keyup', function(e)
}
else if (newAmount > productStockAmount + containerWeight)
{
$('#inventory-change-info').text(__t('This means %s will be added to stock', estimatedBookingAmount.toLocaleString() + ' ' + __n(estimatedBookingAmount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural)));
$('#inventory-change-info').text(__t('This means %s will be added to stock', estimatedBookingAmount.toLocaleString() + ' ' + __n(estimatedBookingAmount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural, true)));
Grocy.Components.DateTimePicker.GetInputElement().attr('required', '');
if (Grocy.FeatureFlags.GROCY_FEATURE_FLAG_STOCK_LOCATION_TRACKING)
{
Expand All @@ -393,7 +393,7 @@ $('#display_amount').on('keyup', function(e)
}
else if (newAmount < productStockAmount + containerWeight)
{
$('#inventory-change-info').text(__t('This means %s will be removed from stock', estimatedBookingAmount.toLocaleString() + ' ' + __n(estimatedBookingAmount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural)));
$('#inventory-change-info').text(__t('This means %s will be removed from stock', estimatedBookingAmount.toLocaleString() + ' ' + __n(estimatedBookingAmount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural, true)));
Grocy.Components.DateTimePicker.GetInputElement().removeAttr('required');
if (Grocy.FeatureFlags.GROCY_FEATURE_FLAG_STOCK_LOCATION_TRACKING)
{
Expand Down
6 changes: 3 additions & 3 deletions public/viewjs/mealplan.js
Expand Up @@ -252,13 +252,13 @@ $(".calendar").each(function()
element.html('\
<div> \
<h5 class="text-truncate mb-1 cursor-link display-product-button ' + additionalTitleCssClasses + '" data-toggle="tooltip" title="' + __t("Display product") + '" data-product-id="' + productDetails.product.id.toString() + '">' + productDetails.product.name + '</h5> \
<h5 class="small text-truncate mb-1"><span class="locale-number locale-number-quantity-amount">' + mealPlanEntry.product_amount + "</span> " + __n(mealPlanEntry.product_amount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural) + '</h5> \
<h5 class="small text-truncate mb-1"><span class="locale-number locale-number-quantity-amount">' + mealPlanEntry.product_amount + "</span> " + __n(mealPlanEntry.product_amount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural, true) + '</h5> \
<h5 class="small timeago-contextual text-truncate mb-1">' + fulfillmentIconHtml + " " + fulfillmentInfoHtml + '</h5> \
' + costsAndCaloriesPerServing + ' \
<h5 class="d-print-none"> \
<a class="ml-1 btn btn-outline-danger btn-xs remove-product-button" href="#" data-toggle="tooltip" title="' + __t("Delete this item") + '"><i class="fas fa-trash"></i></a> \
<a class="btn btn-outline-info btn-xs edit-meal-plan-entry-button" href="#" data-toggle="tooltip" title="' + __t("Edit this item") + '"><i class="fas fa-edit"></i></a> \
<a class="ml-1 btn btn-outline-success btn-xs product-consume-button ' + productConsumeButtonDisabledClasses + '" href="#" data-toggle="tooltip" title="' + __t("Consume %1$s of %2$s", parseFloat(mealPlanEntry.product_amount).toLocaleString() + ' ' + __n(mealPlanEntry.product_amount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural), productDetails.product.name) + '" data-product-id="' + productDetails.product.id.toString() + '" data-product-name="' + productDetails.product.name + '" data-product-amount="' + mealPlanEntry.product_amount + '" data-mealplan-entry-id="' + mealPlanEntry.id.toString() + '"><i class="fas fa-utensils"></i></a> \
<a class="ml-1 btn btn-outline-success btn-xs product-consume-button ' + productConsumeButtonDisabledClasses + '" href="#" data-toggle="tooltip" title="' + __t("Consume %1$s of %2$s", parseFloat(mealPlanEntry.product_amount).toLocaleString() + ' ' + __n(mealPlanEntry.product_amount, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural, true), productDetails.product.name) + '" data-product-id="' + productDetails.product.id.toString() + '" data-product-name="' + productDetails.product.name + '" data-product-amount="' + mealPlanEntry.product_amount + '" data-mealplan-entry-id="' + mealPlanEntry.id.toString() + '"><i class="fas fa-utensils"></i></a> \
' + shoppingListButtonHtml + ' \
' + doneButtonHtml + ' \
</h5> \
Expand Down Expand Up @@ -800,7 +800,7 @@ $(document).on('click', '.product-consume-button', function(e)
Grocy.Api.Get('stock/products/' + productId,
function(result)
{
var toastMessage = __t('Removed %1$s of %2$s from stock', consumeAmount.toString() + " " + __n(consumeAmount, result.quantity_unit_stock.name, result.quantity_unit_stock.name_plural), result.product.name) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoStockTransaction(\'' + bookingResponse[0].transaction_id + '\')"><i class="fas fa-undo"></i> ' + __t("Undo") + '</a>';
var toastMessage = __t('Removed %1$s of %2$s from stock', consumeAmount.toString() + " " + __n(consumeAmount, result.quantity_unit_stock.name, result.quantity_unit_stock.name_plural, true), result.product.name) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoStockTransaction(\'' + bookingResponse[0].transaction_id + '\')"><i class="fas fa-undo"></i> ' + __t("Undo") + '</a>';

Grocy.Api.Put('objects/meal_plan/' + mealPlanEntryId, { "done": 1 },
function(result)
Expand Down
2 changes: 1 addition & 1 deletion public/viewjs/productform.js
Expand Up @@ -177,7 +177,7 @@ $('.input-group-qu').on('change', function(e)

if (factor > 1 || quIdPurchase != quIdStock)
{
$('#qu-conversion-info').text(__t('This means 1 %1$s purchased will be converted into %2$s %3$s in stock', $("#qu_id_purchase option:selected").text(), (1 * factor).toString(), __n((1 * factor).toString(), $("#qu_id_stock option:selected").text(), $("#qu_id_stock option:selected").data("plural-form"))));
$('#qu-conversion-info').text(__t('This means 1 %1$s purchased will be converted into %2$s %3$s in stock', $("#qu_id_purchase option:selected").text(), (1 * factor).toString(), __n((1 * factor).toString(), $("#qu_id_stock option:selected").text(), $("#qu_id_stock option:selected").data("plural-form"), true)));
$('#qu-conversion-info').removeClass('d-none');
}
else
Expand Down
2 changes: 1 addition & 1 deletion public/viewjs/purchase.js
Expand Up @@ -115,7 +115,7 @@ $('#save-purchase-button').on('click', function(e)
{
amountMessage = parseFloat(jsonForm.amount) - parseFloat(productDetails.stock_amount) - parseFloat(productDetails.product.tare_weight);
}
var successMessage = __t('Added %1$s of %2$s to stock', amountMessage + " " + __n(amountMessage, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural), productDetails.product.name) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoStockTransaction(\'' + result[0].transaction_id + '\')"><i class="fas fa-undo"></i> ' + __t("Undo") + '</a>';
var successMessage = __t('Added %1$s of %2$s to stock', amountMessage + " " + __n(amountMessage, productDetails.quantity_unit_stock.name, productDetails.quantity_unit_stock.name_plural, true), productDetails.product.name) + '<br><a class="btn btn-secondary btn-sm mt-2" href="#" onclick="UndoStockTransaction(\'' + result[0].transaction_id + '\')"><i class="fas fa-undo"></i> ' + __t("Undo") + '</a>';

if (Grocy.FeatureFlags.GROCY_FEATURE_FLAG_LABEL_PRINTER)
{
Expand Down
4 changes: 2 additions & 2 deletions public/viewjs/quantityunitconversionform.js
Expand Up @@ -179,12 +179,12 @@ $('.input-group-qu').on('change', function(e)

if (fromQuId && toQuId)
{
$('#qu-conversion-info').text(__t('This means 1 %1$s is the same as %2$s %3$s', $("#from_qu_id option:selected").text(), parseFloat((1 * factor)).toLocaleString({ minimumFractionDigits: 0, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_amounts }), __n((1 * factor).toLocaleString({ minimumFractionDigits: 0, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_amounts }), $("#to_qu_id option:selected").text(), $("#to_qu_id option:selected").data("plural-form"))));
$('#qu-conversion-info').text(__t('This means 1 %1$s is the same as %2$s %3$s', $("#from_qu_id option:selected").text(), parseFloat((1 * factor)).toLocaleString({ minimumFractionDigits: 0, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_amounts }), __n((1 * factor).toLocaleString({ minimumFractionDigits: 0, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_amounts }), $("#to_qu_id option:selected").text(), $("#to_qu_id option:selected").data("plural-form"), true)));
$('#qu-conversion-info').removeClass('d-none');

if (Grocy.EditMode === 'create')
{
$('#qu-conversion-inverse-info').text(__t('This means 1 %1$s is the same as %2$s %3$s', $("#to_qu_id option:selected").text(), parseFloat((1 / factor)).toLocaleString({ minimumFractionDigits: 0, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_amounts }), __n((1 / factor).toString(), $("#from_qu_id option:selected").text(), $("#from_qu_id option:selected").data("plural-form"))));
$('#qu-conversion-inverse-info').text(__t('This means 1 %1$s is the same as %2$s %3$s', $("#to_qu_id option:selected").text(), parseFloat((1 / factor)).toLocaleString({ minimumFractionDigits: 0, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_amounts }), __n((1 / factor).toString(), $("#from_qu_id option:selected").text(), $("#from_qu_id option:selected").data("plural-form"), true)));
$('#qu-conversion-inverse-info').removeClass('d-none');
}
}
Expand Down
2 changes: 1 addition & 1 deletion public/viewjs/quantityunitpluraltesting.js
Expand Up @@ -25,7 +25,7 @@ function RefreshQuPluralTestingResult()
}

animateCSS("h2", "shake");
$("#result").text(__n(amount, singularForm, pluralForm));
$("#result").text(__n(amount, singularForm, pluralForm, true));
}

if (GetUriParam("qu") !== undefined)
Expand Down

0 comments on commit 12e5377

Please sign in to comment.