yalo 3.0.0 copy "yalo: ^3.0.0" to clipboard
yalo: ^3.0.0 copied to clipboard

Yalo (Yaml localizations) - is a package, which give you a simplest way to get localizations from yaml files

Yaml localizations (and assets codegen) #

[yalo:loc] How to use #

1. Localization files #

After installing this package you can use .yaml files with localization content. You can place these files in this order

  • assets/**/language_code/intl.yaml
  • assets/**/language_code.intl.yaml
  • assets/**/language_code_intl.yaml

Where language_code is a ua / en / de, etc. Like in example

  • assets/localizations/ua/intl.yaml
  • assets/en/intl.yaml
  • assets/content/de_intl.yaml
  • assets/zh.intl.yaml

2. Describe path to the assets folder #

Of course, you must also specify the path to the assets folder in pubspec.yaml

# pubspec.yaml
# ...
flutter:
  # ...
  assets:
    - assets/
  # ...

3. Run the command #

When you created all localization files, then run command

flutter pub run yalo:loc

4. Add generated localization dependency to your project #

This command will generate a .yalo_locale folder in your project's root directory. Then, add this package as a dependency to your pubspec.yaml file

# ...
dependencies:
  # ...
  yalo_locale:
    path: ./.yalo_locale
  # ...
# ...

5. Use and enjoy #

Now you can use generated localization delegate in your app! Yalo provides you to use a simple variable localizationsDelegates, which you can use in your MaterialApp or CupertinoApp. And also, you can use generated variable supportedLocales, which contains all your locales

import 'package:yalo_locale/lib.dart';

class PresidentsApp extends StatelessWidget {
  const PresidentsApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: localizationsDelegates,
      supportedLocales: supportedLocales,
      locale: DevicePreview.locale(context),
      onGenerateTitle: (BuildContext context) =>
      Messages
          .of(context)
          .app
          .title,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      useInheritedMediaQuery: true,
      builder: DevicePreview.appBuilder,
      home: const MyHomePage(),
    );
  }
}

To get access to current localization content, use Messages.of(context). This method will return your current's locale content

Widget build(BuildContext context) {
  final LocalizationMessages loc = Messages.of(context);

  return Scaffold(
    appBar: AppBar(
      title: Text(loc.app.description),
    ),
    body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.only(bottom: 20),
            child: Text(
              loc.books(user: loc.presidents.getContent('p$_counter'), howMany: _counter),
              textAlign: TextAlign.center,
            ),
          ),
        ],
      ),
    ),
    floatingActionButton: FloatingActionButton(
      onPressed: _incrementCounter,
      tooltip: loc.tooltips.increment,
      child: const Icon(Icons.add),
    ),
  );
}

Also, you can use a static fields of Messages with localized content too. For every language will be generated a static field. For example:

class Messages {
  static LocalizationMessages of(BuildContext context) => Localizations.of(context, LocalizationMessages);

  static LocalizationMessages get de => LocalizationDelegate()._languageMap['de']!;

  static LocalizationMessages get en => LocalizationDelegate()._languageMap['en']!;
}

Localization files format #

1. Simple message #

# The simplest possible message type [SimpleMessage]
cancel: Cancel
  /// Description: ""
/// Example: "Cancel"
@override
final String cancel = Intl.message(
  '''Cancel''',
  name: 'cancel',
  desc: '',
);

2. Simple message with description #

# Simple message type with description [SimpleMessage]
save:
  value: Save
  desc: Saving something
/// Description: "Saving something"
/// Example: "Save"
@override
final String save = Intl.message(
  '''Save''',
  name: 'save',
  desc: 'Saving something',
);

3. Simple message with substitution #

# [SimpleMessage] with additional substitution params
greetings: Hello ${userName}! We are glad to see you at our ${hotelName} hotel!
/// Description: ""
/// Example: "Hello $userName! We are glad to see you at our $hotelName hotel!"
@override
String greetings({
  required String userName,
  required String hotelName,
}) =>
    Intl.message(
      '''Hello $userName! We are glad to see you at our $hotelName hotel!''',
      name: 'greetings',
      desc: '',
    );

4. Simple message with description and substitution #

# [SimpleMessage] with description and substitution params
weather:
  value: It's ${temperature} degrees outside today!
  desc: "Title on the main weather screen (see here: https://www.figma.com/community/file/974352831498882628)"
/// Description: "Title on the main weather screen (see here: https://www.figma.com/community/file/974352831498882628)"
/// Example: "It's $temperature degrees outside today!"
@override
String weather({
  required String temperature,
}) =>
    Intl.message(
      '''It's $temperature degrees outside today!''',
      name: 'weather',
      desc: 'Title on the main weather screen (see here: https://www.figma.com/community/file/974352831498882628)',
    );

5. Plural message #

For additional info about plural rules go here

# [PluralMessage]
book:
  # Required parameter of plural message
  zero: books
  # Required parameter of plural message
  one: book
  # Optional parameter of plural message
  two: books
  # Optional parameter of plural message
  few: books
  # Optional parameter of plural message
  many: books
  # Required parameter of plural message
  other: books
  # Optional parameter of plural message
  desc: Uses for description of books count
/// Description: "Uses for description of books count"
/// Example: "zero: books, one: book, two: books, few: books, many: books, other: books"
@override
String book(int howMany, {int? precision}) =>
    Intl.plural(
      howMany,
      name: '''book''',
      zero: '''books''',
      one: '''book''',
      two: '''books''',
      few: '''books''',
      many: '''books''',
      other: '''books''',
      desc: '''Uses for description of books count''',
      precision: precision,
    );

6. Plural message with using of quantity in the text #

# [PluralMessage]
people:
  zero: I saw no people there
  one: I saw only one man there
  two: I saw two people there
  # Message with substitution of quantity of something
  few: I saw ${howMany} people there
  many: I saw ${howMany} or more people there
  other: I think, I saw ${howMany} people there
  desc: An example with numeric substitution in plural strings
/// Description: "An example with numeric substitution in plural strings"
/// Example: "zero: I saw no people there, one: I saw only one man there, two: I saw two people there, few: I saw $howMany people there, many: I saw $howMany or more people there, other: I think, I saw $howMany people there"
@override
String people(int howMany, {int? precision}) =>
    Intl.plural(
      howMany,
      name: '''people''',
      zero: '''I saw no people there''',
      one: '''I saw only one man there''',
      two: '''I saw two people there''',
      few: '''I saw $howMany people there''',
      many: '''I saw $howMany or more people there''',
      other: '''I think, I saw $howMany people there''',
      desc: '''An example with numeric substitution in plural strings''',
      precision: precision,
    );

7. Plural message with extra substitution params #

# [PluralMessage] with additional substitution params and quantity substitution param
shop:
  zero: There are no any ${shopName} shops
  one: There are exactly one ${shopName} shop
  two: There are two ${shopName} shops
  few: There are ${howMany} ${shopName} shops and we have plans to open additional at the ${city}!
  many: There are ${howMany} shops. Sorry, I didn't remember that shop name.
  other: Well, I tired to count these shops. I can say that there are only ${howMany} shops!
/// Description: ""
/// Example: "zero: There are no any $shopName shops, one: There are exactly one $shopName shop, two: There are two $shopName shops, few: There are $howMany $shopName shops and we have plans to open additional at the $city!, many: There are $howMany shops. Sorry, I didn't remember that shop name., other: Well, I tired to count these shops. I can say that there are only $howMany shops!"
@override
String shop({
  required String shopName,
  required int howMany,
  required String city,
  int? precision,
}) =>
    Intl.plural(
      howMany,
      name: '''shop''',
      zero: '''There are no any $shopName shops''',
      one: '''There are exactly one $shopName shop''',
      two: '''There are two $shopName shops''',
      few: '''There are $howMany $shopName shops and we have plans to open additional at the $city!''',
      many: '''There are $howMany shops. Sorry, I didn't remember that shop name.''',
      other: '''Well, I tired to count these shops. I can say that there are only $howMany shops!''',
      desc: '''''',
      precision: precision,
    );

8. Namespaced content #

# Namespace of group of messages [MessagesNamespace]
namespacedZone:
  # [SimpleMessage]
  title: Title of Namespaced zone
  # [SimpleMessage]
  description: Description of Namespaced zone
  # [MessagesNamespace]
  checkout:
    # [SimpleMessage]
    title: Checkout for additional page
  # [MessagesNamespace]
  innerNamespacedZone:
    # [SimpleMessage]
    title: Deeper title of Inner namespaced zone with name ${name}
    # [SimpleMessage]
    description: Deeper description of Inner namespaced zone
    # [PluralMessage]
    book:
      # Required parameter of plural message
      zero: books
      # Required parameter of plural message
      one: book
      # Optional parameter of plural message
      two: books
      # Optional parameter of plural message
      few: books
      # Optional parameter of plural message
      many: books
      # Required parameter of plural message
      other: books
      # Optional parameter of plural message
      desc: Uses for description of books count
# ...
# [MessagesNamespace]
app:
  # [SimpleMessage]
  title: Yalo app
  # [SimpleMessage]
  description: This app will show you how to use yalo package
/// This is an example of how namespaces works
final String bookTitle = Messages
    .of(context)
    .namespacedZone
    .innerNamespacedZone
    .book(booksQuantity);
final String checkoutTitle = Messages
    .of(context)
    .namespacedZone
    .checkout
    .title;
// ...
final String appTitle = Messages
    .of(context)
    .app
    .title;

It may happen that some block of content will be the same in all languages. In such a case, you can only define this content in one language and link to it in other languages. For example like this:

# en.intl.yaml
presidents:
  p1: George Washington
  p2: John Adams
  p3: Thomas Jefferson
  p4: James Madison
  # ...
# de.intl.yaml
presidents: ~en.presidents

An important note about this feature: at the moment, only first-level (root) elements can be referenced this way.

Dynamic access #

In addition to accessing content in a class style, you can also access it dynamically using the T getContent<T>(String key) method of any namespace-class or root LocalizationMessages entity. Thus, you can both move along the chain of class-namespaces, and simply get something dynamically. See here:

mainView:
  firstTab:
    secondStory:
      example:
        title: This is a title
        description: This is a description
---
presidents:
  p1: George Washington
  p2: John Adams
  p3: Thomas Jefferson
  p4: James Madison
  # ...

final String title = loc
    .getContent<MainView>('mainView')
    .getContent<MainViewFirstTab>('firstTab')
    .getContent<FirstTabSecondStory>('secondStory')
    .getContent<SecondStoryExample>('example')
    .getContent('title');

final Widget widget = Padding(
  padding: const EdgeInsets.only(bottom: 20),
  child: Text(
    loc.books(user: loc.presidents.getContent('p$_counter'), howMany: _counter),
    textAlign: TextAlign.center,
  ),
);

Examples #

You can see additional examples of generated code, its usage, as well as localization source files in GitHub.


Assets #

To generate code with your assets paths, you should run this command:

flutter pub run yalo:asset

This command will generate a .yalo_assets folder in your project's root. Also, as written above, you must add this folder as a dependency of your project:

# ...
dependencies:
  # ...
  yalo_assets:
    path: ./.yalo_assets
  # ...
# ...

After that, you can use Assets class with static and usual fields in your project:

import 'package:yalo_assets/lib.dart';

// MyHomePageState.dart
@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          _buildText('Assets example: ${Assets.rigDemoS}'), // <-- this static field contains "assets/rive/Rig Demo.flr2d" string
          _buildText('Assets example: ${Assets().rigDemo}'), // <-- this field contains "assets/rive/Rig Demo.flr2d" string
        ],
      ),
    ),
    floatingActionButton: FloatingActionButton(
      onPressed: _incrementCounter,
      tooltip: 'Increment',
      child: Icon(Icons.add),
    ),
  );
}
5
likes
130
pub points
55%
popularity

Publisher

verified publisheralphamikle.dev

Yalo (Yaml localizations) - is a package, which give you a simplest way to get localizations from yaml files

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

analyzer, dart_style, flutter, intl, path, yaml

More

Packages that depend on yalo