Skip to content

i18n Code Style ​

В данной статье описаны как надо и как не надо менять файлы .i18n.json

Формат ключей ​

Ключи называем в snake_case

TIP

При генерации кода, генерируются геттеры в snake_case и потом невозможно найти источник локализации поиском по геттеру, потому что в json ключи хранятся в другом формате

json
// [!code class:bad]
"profileWidget": {
  "sammaVodkaStart": "To start, begin",
  "sammaVodkaPrefix": "Sammagonka — ",
  "sammaVodkaContinuePostfix": "'.\nKeep going!",
}
json
// [!code class:good]
"profile_widget": {
  "samma_vodka_start": "To start, begin",
  "samma_vodka_prefix": "Sammagonka — ",
  "samma_vodka_continue_postfix": "'.\nKeep going!",
}

**_text в ключах ​

Старайся избегать _text в ключах. Ты и так используешь инструмент для текстов, это понятно из контекста

json
// [!code class:bad]
"profile_widget": {
  "samma_vodka_start_text": "To start, begin"
}
json
// [!code class:good]
"profile_widget": {
  "samma_vodka_start": "To start, begin"
}

Можно использовать одинарный ключ "text", если ничего больше не подходит по смыслу

json
// [!code class:good]
"profile_widget": {
  "text": {
    "no_progress": "...",
    "has_progress": "..."
  }
}

Составной текст ​

Старайся использовать только один ключ в коде для одного кейса вместо составных текстов

json
// [!code class:bad]
"profile": {
  "samma_vodka_start": "Для начала — начни",
  "samma_vodka_prefix": "Саммагонка — $duration",
  "samma_vodka_continue_postfix": "'.\nKeep going!",
}
dart
// [!code class:bad]
final isActive = progress != 0 && progress != 1;
final duration = durationRaw.let((it) => DateTimeUtils.formatDuration(context, it));

final result = durationRaw == null || durationRaw == 0
  ? context.t.knowledge_sprint.profile_widget.samma_vodka_start_text
  : context.t.knowledge_sprint.profile_widget.samma_vodka_prefix +
    duration +
    (isActive ? context.t.knowledge_sprint.profile_widget.samma_vodka_continue_postfix : '');

return Text(result)
json
// [!code class:good]
"profile": {
  "text": {
    "no_progress": "Для начала — начни",
    "has_progress": "Саммагонка — $duration",
    "active": "@:knowledge_sprint.profile.text.has_progress.\nПродолжай!"
  }
}
dart
// [!code class:good]
final isActive = progress != 0 && progress != 1;
final duration = durationRaw.let((it) => DateTimeUtils.formatDuration(context, it));

final String text;
if (durationRaw == null || durationRaw == 0) {
  text = context.t.knowledge_sprint.profile_widget.text.no_progress;
} else if (isActive) {
  text = context.t.knowledge_sprint.profile_widget.text.active(duration: duration!);
} else {
  text = context.t.knowledge_sprint.profile_widget.text.has_progress(duration: duration!);
}

return Text(text);

Понятный нейминг ​

Используй понятный и легкочитаемый нейминг. Старайся избегать двойного отрицания

json
// [!code class:bad]
"bottom_sheet": {
  "empty_result": {
    "title": "Опа, $name не в саммагонке!"
  },
  "not_empty_result": {
    "title": "$name бьет рекорды:\n $days подряд!"
  }
}
json
// [!code class:good]
"bottom_sheet": {
  "no_results": {
    "title": "Опа, $name не в саммагонке!"
  },
  "has_results": {
    "title": "$name бьет рекорды:\n $days подряд!"
  }
}

Авторы

The avatar of contributor named as melvspace melvspace
The avatar of contributor named as Pavel Nochevnoy Pavel Nochevnoy
The avatar of contributor named as Arutyun Gevorkyan Arutyun Gevorkyan
The avatar of contributor named as Vadim Melnikov Vadim Melnikov

История