Guias
Formato de mensagens
Uma sintaxe pequena, com Intl nativo por baixo: plurais, gênero e formatação sem aprender ICU completo.
Interpolação
Os valores formatam-se sozinhos pelo tipo: números com Intl.NumberFormat, datas com Intl.DateTimeFormat, textos tal como estão. Um número é lido como o idioma o escreve, então 2026 sai como 2,026 em inglês: passe String(year) quando o valor é um rótulo, como o ano de uma linha de copyright, e não uma quantidade. Um param que falta mostra o marcador literal e avisa uma vez nomeando a mensagem, por isso vê-se logo e nunca rebenta.
Formatters
Adicione :formatter (com /arg opcional) a um param:
| Sintaxe | Resultado |
|---|---|
| {n:number} | Número do locale: 1,234.56 / 1234,56 |
| {n:integer} | Arredondado, sem decimais |
| {n:percent} | 0.5 → 50% |
| {n:currency/EUR} | Moeda com código ISO |
| {d:date/long} | dateStyle: short · medium · long · full |
| {d:time/short} | Variantes de timeStyle |
Os formatters custom se conectam na criação da instância. A assinatura completa é (value, locale, arg?) => string, onde locale é o idioma ativo e arg é o que vem depois do / no placeholder:
Tempo relativo, listas e unidades
O formato cobre o resto do Intl moderno, ainda com zero dependências:
relative: passe umDatee a unidade se escolhe sozinha em relação a agora (Intl.RelativeTimeFormatcomnumeric: 'auto', então você recebe ontem, não há 1 dia); passe um número com unidade explícita (relative/hour).list: arrays localizam viaIntl.ListFormat, conjunção por padrão,/orpara disjunção,/unitpara listas de unidades. Cada item se auto-formata por locale.unit: qualquer id de unidade CLDR (kilometer,megabyte,liter…) viaIntl.NumberFormat.- Os dados maus nunca deitam abaixo um render, e também não passam ao lado. Um formato desconhecido, uma unidade inválida, um espaço sem o seu argumento, uma lista que não é uma lista: cada um avisa uma vez, nomeando a mensagem, e recorre a
String(value).
Plurais e selects: uma só sintaxe
- Números casam primeiro os valores exatos
=N, depois as categorias deIntl.PluralRules(zero one two few many other). - Strings casam sua variante, com fallback para
other. #renderiza o número formatado ao locale. As variantes aninham placeholders livremente.- Inclua sempre
othernum bloco plural. É o caso geral, por isso um bloco sem ele não renderiza nada para qualquer contagem que não liste. Overbaly checkfalha por isso, e também avisa quando um idioma precisa de formas que faltam à sua mensagem: o polonês chega afewemanyonde o inglês só precisa deoneeother. Se um catálogo chegar à sua app sem passar pelo build, de um loader lazy ou de um CMS, o runtime avisa no console nomeando a mensagem em vez de renderizar uma string vazia em silêncio. Um bloco de gênero ou de papel é diferente: deixarotherde fora ali é a sua decisão, e o Verbaly não mexe nisso.
Escape-hatch ICU
Tem strings ICU MessageFormat existentes, ou precisa da sintaxe exata dele? Escreva ICU e o Verbaly detecta automaticamente e o parseia no mesmo motor, com zero dependências extras.
- Auto-detectado por mensagem: sem config, sem marcador. Mensagens nativas e ICU coexistem no mesmo catálogo.
- Suporta
plural,select,selectordinal(regras ordinais reais),{n, number/date/time, style},#,=N, aninhamento e quoting com'…'. - É verificado como qualquer outra mensagem. Uma tradução que achatou um plural de ICU para texto simples, ou que lhe tirou um parâmetro, falha no
verbaly checktal como uma nativa. A mesma guarda roda sobre o que uma tradução de máquina devolve e sobre o que você importa. - Prefira a sintaxe nativa por padrão; recorra ao ICU só quando precisar.
- Você só paga se usar. O Verbaly lê os seus catálogos ao construir, e o parser de ICU entra no seu aplicativo só quando alguma das suas mensagens precisa dele. São uns 544 bytes, e não há nada para ligar. O tempo relativo funciona igual: outros 318 bytes que só viajam quando uma mensagem os pede.
Escapes
| Você escreve | Você obtém |
|---|---|
| {{ | { literal |
| }} | } literal |
| || | | literal dentro de variantes |
| ## | # literal dentro de variantes |
Num catálogo, os caracteres { e } literais sempre se escrevem dobrados. O texto escrito no seu código já vem assim, porque o extract os dobra por você; um catálogo escrito à mão tem que fazer isso sozinho, traduções incluídas.
Em mensagens rich (data-verbaly-rich ou <Trans>) a entidade numérica { também mostra uma chave literal: ela decodifica depois do parse, então nunca toca a sintaxe de placeholders.