GENL / matice

Use your Laravel translations in JavaScript.
MIT License
98 stars 14 forks source link

Pluralization with two parts (singular and plural) breaks when a comma is part of the translated text #40

Open mpenna opened 1 year ago

mpenna commented 1 year ago

Expected behavior

When relying on the "two parts" pluralization logic, the pluralized part of the translated string should be the one returned whenever the count parameter is greater than 1. At least this is how I understand how this logic should work.

Current behavior

Whenever there's a comma on the translated expression, the logic breaks and the first part (singular) is the one always returned, regardless the value of the count parameter.

Versions

Transalations

// lang/pt_BR/welcome.php
[
    'greet' => [
        // ...
        'people' => "Olá, Marcos!|Olá para todos!",
    ],
]

__('welcome.greet.people', { args: { count: 2 }, pluralize: true }) // Olá, Marcos

Contents of Matice.translations

{ "en_US": { "auth": { "failed": "These credentials do not match our records.", "password": "The provided password is incorrect.", "throttle": "Too many login attempts. Please try again in :seconds seconds." }, "localization": { "locale": { "en_US": "English", "pt_BR": "Portuguese" } }, "pagination": { "previous": "« Previous", "next": "Next »" }, "passwords": { "reset": "Your password has been reset!", "sent": "We have emailed your password reset link!", "throttled": "Please wait before retrying.", "token": "This password reset token is invalid.", "user": "We can't find a user with that email address." }, "validation": { "accepted": "The :attribute must be accepted.", "accepted_if": "The :attribute must be accepted when :other is :value.", "active_url": "The :attribute is not a valid URL.", "after": "The :attribute must be a date after :date.", "after_or_equal": "The :attribute must be a date after or equal to :date.", "alpha": "The :attribute must only contain letters.", "alpha_dash": "The :attribute must only contain letters, numbers, dashes and underscores.", "alpha_num": "The :attribute must only contain letters and numbers.", "array": "The :attribute must be an array.", "before": "The :attribute must be a date before :date.", "before_or_equal": "The :attribute must be a date before or equal to :date.", "between": { "numeric": "The :attribute must be between :min and :max.", "file": "The :attribute must be between :min and :max kilobytes.", "string": "The :attribute must be between :min and :max characters.", "array": "The :attribute must have between :min and :max items." }, "boolean": "The :attribute field must be true or false.", "confirmed": "The :attribute confirmation does not match.", "current_password": "The password is incorrect.", "date": "The :attribute is not a valid date.", "date_equals": "The :attribute must be a date equal to :date.", "date_format": "The :attribute does not match the format :format.", "declined": "The :attribute must be declined.", "declined_if": "The :attribute must be declined when :other is :value.", "different": "The :attribute and :other must be different.", "digits": "The :attribute must be :digits digits.", "digits_between": "The :attribute must be between :min and :max digits.", "dimensions": "The :attribute has invalid image dimensions.", "distinct": "The :attribute field has a duplicate value.", "email": "The :attribute must be a valid email address.", "ends_with": "The :attribute must end with one of the following: :values.", "enum": "The selected :attribute is invalid.", "exists": "The selected :attribute is invalid.", "file": "The :attribute must be a file.", "filled": "The :attribute field must have a value.", "gt": { "numeric": "The :attribute must be greater than :value.", "file": "The :attribute must be greater than :value kilobytes.", "string": "The :attribute must be greater than :value characters.", "array": "The :attribute must have more than :value items." }, "gte": { "numeric": "The :attribute must be greater than or equal to :value.", "file": "The :attribute must be greater than or equal to :value kilobytes.", "string": "The :attribute must be greater than or equal to :value characters.", "array": "The :attribute must have :value items or more." }, "image": "The :attribute must be an image.", "in": "The selected :attribute is invalid.", "in_array": "The :attribute field does not exist in :other.", "integer": "The :attribute must be an integer.", "ip": "The :attribute must be a valid IP address.", "ipv4": "The :attribute must be a valid IPv4 address.", "ipv6": "The :attribute must be a valid IPv6 address.", "mac_address": "The :attribute must be a valid MAC address.", "json": "The :attribute must be a valid JSON string.", "lt": { "numeric": "The :attribute must be less than :value.", "file": "The :attribute must be less than :value kilobytes.", "string": "The :attribute must be less than :value characters.", "array": "The :attribute must have less than :value items." }, "lte": { "numeric": "The :attribute must be less than or equal to :value.", "file": "The :attribute must be less than or equal to :value kilobytes.", "string": "The :attribute must be less than or equal to :value characters.", "array": "The :attribute must not have more than :value items." }, "max": { "numeric": "The :attribute must not be greater than :max.", "file": "The :attribute must not be greater than :max kilobytes.", "string": "The :attribute must not be greater than :max characters.", "array": "The :attribute must not have more than :max items." }, "mimes": "The :attribute must be a file of type: :values.", "mimetypes": "The :attribute must be a file of type: :values.", "min": { "numeric": "The :attribute must be at least :min.", "file": "The :attribute must be at least :min kilobytes.", "string": "The :attribute must be at least :min characters.", "array": "The :attribute must have at least :min items." }, "multiple_of": "The :attribute must be a multiple of :value.", "not_in": "The selected :attribute is invalid.", "not_regex": "The :attribute format is invalid.", "numeric": "The :attribute must be a number.", "password": "The password is incorrect.", "present": "The :attribute field must be present.", "prohibited": "The :attribute field is prohibited.", "prohibited_if": "The :attribute field is prohibited when :other is :value.", "prohibited_unless": "The :attribute field is prohibited unless :other is in :values.", "prohibits": "The :attribute field prohibits :other from being present.", "regex": "The :attribute format is invalid.", "required": "The :attribute field is required.", "required_if": "The :attribute field is required when :other is :value.", "required_unless": "The :attribute field is required unless :other is in :values.", "required_with": "The :attribute field is required when :values is present.", "required_with_all": "The :attribute field is required when :values are present.", "required_without": "The :attribute field is required when :values is not present.", "required_without_all": "The :attribute field is required when none of :values are present.", "same": "The :attribute and :other must match.", "size": { "numeric": "The :attribute must be :size.", "file": "The :attribute must be :size kilobytes.", "string": "The :attribute must be :size characters.", "array": "The :attribute must contain :size items." }, "starts_with": "The :attribute must start with one of the following: :values.", "string": "The :attribute must be a string.", "timezone": "The :attribute must be a valid timezone.", "unique": "The :attribute has already been taken.", "uploaded": "The :attribute failed to upload.", "url": "The :attribute must be a valid URL.", "uuid": "The :attribute must be a valid UUID.", "custom": { "attribute-name": { "rule-name": "custom-message" } }, "attributes": [] }, "welcome": { "greet": { "me": "Hello!", "someone": "Hello, :name!", "me_more": "Hello, Ekcel Henrich!", "people": "Hello, Ekcel!|Hello, everyone!" }, "last_login": "{0} First login|[1,] Last login was :count minutes ago", "balance": "{0} You're broke|[1000, 5000] a middle man|[1000000,] You are awesome :name, :count Million Dollars" }, "Welcome!": "Welcome, my friend!", "Welcome, :name!": "Welcome, :name! Make yourself at home." }, "pt_BR": { "auth": { "failed": "Essas credenciais não correspondem aos nossos registros.", "password": "A senha fornecida está incorreta.", "throttle": "Muitas tentativas de login. Tente novamente em :seconds segundos." }, "localization": { "locale": { "en_US": "Inglês", "pt_BR": "Português" } }, "pagination": { "previous": "« Anterior", "next": "Próxima »" }, "passwords": { "reset": "Sua senha foi alterada!", "sent": "Enviamos seu link de redefinição de senha por e-mail!", "throttled": "Aguarde antes de tentar novamente.", "token": "Este token de redefinição de senha é inválido.", "user": "Não encontramos um usuário com esse endereço de e-mail." }, "validation": { "accepted": "O :attribute deve ser aceito.", "accepted_if": "O :attribute deve ser aceito quando :other for :value.", "active_url": "O :attribute não é um URL válido.", "after": "O :attribute deve ser uma data posterior a :date.", "after_or_equal": "O :attribute deve ser uma data posterior ou igual a :date.", "alpha": "O :attribute deve conter apenas letras.", "alpha_dash": "O :attribute deve conter apenas letras, números, traços e sublinhados.", "alpha_num": "O :attribute deve conter apenas letras e números.", "array": "O :attribute deve ser um array.", "before": "O :attribute deve ser uma data anterior a :date.", "before_or_equal": "O :attribute deve ser uma data anterior ou igual a :date.", "between": { "numeric": "O :attribute deve estar entre :min e :max.", "file": "O :attribute deve estar entre :min e :max kilobytes.", "string": "O :attribute deve estar entre :min e :max caracteres.", "array": "O :attribute deve ter entre :min e :max itens." }, "boolean": "O campo :attribute deve ser verdadeiro ou falso.", "confirmed": "A confirmação :attribute não corresponde.", "current_password": "A senha está incorreta.", "date": "O :attribute não é uma data válida.", "date_equals": "O :attribute deve ser uma data igual a :date.", "date_format": "O :attribute não corresponde ao formato :format.", "declined": "O :attribute deve ser recusado.", "declined_if": "O :attribute deve ser recusado quando :other for :value.", "different": "O :attribute e :other devem ser diferentes.", "digits": "O :attribute deve ser :digits dígitos.", "digits_between": "O :attribute deve estar entre :min e :max dígitos.", "dimensions": "O :attribute tem dimensões de imagem inválidas.", "distinct": "O campo :attribute tem um valor duplicado.", "email": "O :attribute deve ser um endereço de e-mail válido.", "ends_with": "O :attribute deve terminar com um dos seguintes: :values.", "enum": "O :attribute selecionado é inválido.", "exists": "O :attribute selecionado é inválido.", "file": "O :attribute deve ser um arquivo.", "filled": "O campo :attribute deve ter um valor.", "gt": { "numeric": "O :attribute deve ser maior que :value.", "file": "O :attribute deve ser maior que :value kilobytes.", "string": "O :attribute deve ser maior que os caracteres :value.", "array": "O :attribute deve ter mais de :value itens." }, "gte": { "numeric": "O :attribute deve ser maior ou igual a :value.", "file": "O :attribute deve ser maior ou igual a :value kilobytes.", "string": "O :attribute deve ser maior ou igual a :value caracteres.", "array": "O :attribute deve ter itens :value ou mais." }, "image": "O :attribute deve ser uma imagem.", "in": "O :attribute selecionado é inválido.", "in_array": "O campo :attribute não existe em :other.", "integer": "O :attribute deve ser um número inteiro.", "ip": "O :attribute deve ser um endereço IP válido.", "ipv4": "O :attribute deve ser um endereço IPv4 válido.", "ipv6": "O :attribute deve ser um endereço IPv6 válido.", "mac_address": "O :attribute deve ser um endereço MAC válido.", "json": "O :attribute deve ser uma string JSON válida.", "lt": { "numeric": "O :attribute deve ser menor que :value.", "file": "O :attribute deve ser menor que :value kilobytes.", "string": "O :attribute deve ser menor que :value caracteres.", "array": "O :attribute deve ter itens menores que :value." }, "lte": { "numeric": "O :attribute deve ser menor ou igual a :value.", "file": "O :attribute deve ser menor ou igual a :value kilobytes.", "string": "O :attribute deve ser menor ou igual a :value caracteres.", "array": "O :attribute não deve ter mais do que :value itens." }, "max": { "numeric": "O :attribute não deve ser maior que :max.", "file": "O :attribute não deve ser maior que :max kilobytes.", "string": "O :attribute não deve ser maior que :max caracteres.", "array": "O :attribute não deve ter mais do que :max itens." }, "mimes": "O :attribute deve ser um arquivo do tipo: :values.", "mimetypes": "O :attribute deve ser um arquivo do tipo: :values.", "min": { "numeric": "O :attribute deve ser pelo menos :min.", "file": "O :attribute deve ter pelo menos :min kilobytes.", "string": "O :attribute deve ter pelo menos :min caracteres.", "array": "O :attribute deve ter pelo menos :min itens." }, "multiple_of": "O :attribute deve ser um múltiplo de :value.", "not_in": "O :attribute selecionado é inválido.", "not_regex": "O formato :attribute é inválido.", "numeric": "O :attribute deve ser um número.", "password": "A senha está incorreta.", "present": "O campo :attribute deve estar presente.", "prohibited": "O campo :attribute é proibido.", "prohibited_if": "O campo :attribute é proibido quando :other é :value.", "prohibited_unless": "O campo :attribute é proibido a menos que :other esteja em :values.", "prohibits": "O campo :attribute proíbe :other de estar presente.", "regex": "O formato :attribute é inválido.", "required": "O campo :attribute é obrigatório.", "required_if": "O campo :attribute é obrigatório quando :other é :value.", "required_unless": "O campo :attribute é obrigatório, a menos que :other esteja em :values.", "required_with": "O campo :attribute é obrigatório quando :values ​​está presente.", "required_with_all": "O campo :attribute é obrigatório quando :values ​​estão presentes.", "required_without": "O campo :attribute é obrigatório quando :values ​​não está presente.", "required_without_all": "O campo :attribute é obrigatório quando nenhum dos :values ​​está presente.", "same": "O :attribute e :other devem corresponder.", "size": { "numeric": "O :attribute deve ser :size.", "file": "O :attribute deve ser :size kilobytes.", "string": "O :attribute deve ser :size caracteres.", "array": "O :attribute deve conter :size itens." }, "starts_with": "O :attribute deve começar com um dos seguintes: :values.", "string": "O :attribute deve ser uma string.", "timezone": "O :attribute deve ser um fuso horário válido.", "unique": "O :attribute já foi usado.", "uploaded": "O :attribute falhou ao carregar.", "url": "O :attribute deve ser um URL válido.", "uuid": "O :attribute deve ser um UUID válido.", "custom": { "attribute-name": { "rule-name": "custom-message" } }, "attributes": [] }, "welcome": { "greet": { "me": "Olá!", "someone": "Olá, :name!", "me_more": "Olá, Marcos Penna!", "people": "Olá, Marcos!|Olá para todos!" }, "last_login": "{0} Primeiro login|[1,] Último login há :count minutos", "balance": "{0} Você está quebrado|[1000, 5000] classe média|[1000000,] Você é incível, :name, :count milhões de dólares" }, "Welcome!": "Bem-vindo!", "Welcome, :name!": "Bem-vindo, :name!", "Appointments": "Agendamentos", "Date": "Data", "Scheduled": "Horário", "Registered": "Registrado", "Patient Arrival": "Chegada Paciente", "Examination Start": "Início Exame", "Patient": "Paciente", "Examination": "Exame", "Actions": "Ações", "Rows per page": "Registros por página", "Search": "Buscar", "arrival": "Chegada", "exam": "Exame" } }