Unverified Commit 3e4bf575 authored by Shi-Hao Hong's avatar Shi-Hao Hong Committed by GitHub

Update Stocks example using i18n tool (#44223)

* Use l10n tool to generate stocks i18n files

* Rename *_en_EN.arb to *_en_US.arb

* Fix l10n script
parent 383e90eb
......@@ -36,7 +36,7 @@ analyzer:
- "bin/cache/**"
# the following two are relative to the stocks example and the flutter package respectively
# see https://github.com/dart-lang/sdk/issues/28463
- "lib/i18n/stock_messages_*.dart"
- "lib/i18n/messages_*.dart"
- "lib/src/http/**"
linter:
......
......@@ -99,7 +99,7 @@ class _@classNameDelegate extends LocalizationsDelegate<@className> {
Future<@className> load(Locale locale) => @className.load(locale);
@override
bool isSupported(Locale locale) => [@supportedLanguageCodes].contains(locale.languageCode);
bool isSupported(Locale locale) => <String>[@supportedLanguageCodes].contains(locale.languageCode);
@override
bool shouldReload(_@classNameDelegate old) => false;
......@@ -236,7 +236,7 @@ String genPluralMethod(Map<String, dynamic> bundle, String key) {
}
String genSupportedLocaleProperty(Set<LocaleInfo> supportedLocales) {
const String prefix = 'static const List<Locale> supportedLocales = <Locale>[ \n Locale(''';
const String prefix = 'static const List<Locale> supportedLocales = <Locale>[\n Locale(''';
const String suffix = '),\n ];';
String resultingProperty = prefix;
......@@ -289,7 +289,7 @@ bool _isDirectoryReadableAndWritable(String statString) {
String _importFilePath(String path, String fileName) {
final String replaceLib = path.replaceAll('lib/', '');
return '$replaceLib/$fileName.dart';
return '$replaceLib/$fileName';
}
Future<void> main(List<String> args) async {
......
......@@ -2,28 +2,34 @@
// This is a library that looks up messages for specific locales by
// delegating to the appropriate library.
// Ignore issues from commonly used lints in this file.
// ignore_for_file:implementation_imports, file_names, unnecessary_new
// ignore_for_file:unnecessary_brace_in_string_interps, directives_ordering
// ignore_for_file:argument_type_not_assignable, invalid_assignment
// ignore_for_file:prefer_single_quotes, prefer_generic_function_type_aliases
// ignore_for_file:comment_references
import 'dart:async';
import 'package:intl/intl.dart';
import 'package:intl/message_lookup_by_library.dart';
// ignore: implementation_imports
import 'package:intl/src/intl_helpers.dart';
import 'stock_messages_en.dart' as messages_en;
import 'stock_messages_es.dart' as messages_es;
import 'messages_en_US.dart' as messages_en_us;
import 'messages_es_ES.dart' as messages_es_es;
typedef Future<dynamic> LibraryLoader();
Map<String, LibraryLoader> _deferredLibraries = {
'en': () => new Future.value(null),
'es': () => new Future.value(null),
'en_US': () => new Future.value(null),
'es_ES': () => new Future.value(null),
};
MessageLookupByLibrary _findExact(localeName) {
MessageLookupByLibrary _findExact(String localeName) {
switch (localeName) {
case 'en':
return messages_en.messages;
case 'es':
return messages_es.messages;
case 'en_US':
return messages_en_us.messages;
case 'es_ES':
return messages_es_es.messages;
default:
return null;
}
......@@ -53,7 +59,7 @@ bool _messagesExistFor(String locale) {
}
}
MessageLookupByLibrary _findGeneratedMessagesFor(locale) {
MessageLookupByLibrary _findGeneratedMessagesFor(String locale) {
var actualLocale = Intl.verifiedLocale(locale, _messagesExistFor,
onFailure: (_) => null);
if (actualLocale == null) return null;
......
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
// This is a library that provides messages for a en locale. All the
// This is a library that provides messages for a en_US locale. All the
// messages from the main program should be duplicated here with the same
// function name.
// Ignore issues from commonly used lints in this file.
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
// ignore_for_file:unused_import, file_names
import 'package:intl/intl.dart';
import 'package:intl/message_lookup_by_library.dart';
final messages = new MessageLookup();
// ignore: unused_element
final _keepAnalysisHappy = Intl.defaultLocale;
// ignore: non_constant_identifier_names
typedef MessageIfAbsent(String message_str, List args);
typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
class MessageLookup extends MessageLookupByLibrary {
get localeName => 'en';
String get localeName => 'en_US';
final messages = _notInlinedMessages(_notInlinedMessages);
static _notInlinedMessages(_) => <String, Function> {
"market" : MessageLookupByLibrary.simpleMessage("MARKET"),
"portfolio" : MessageLookupByLibrary.simpleMessage("PORTFOLIO"),
"title" : MessageLookupByLibrary.simpleMessage("Stocks"),
"title" : MessageLookupByLibrary.simpleMessage("Stocks")
};
}
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
// This is a library that provides messages for a es locale. All the
// This is a library that provides messages for a es_ES locale. All the
// messages from the main program should be duplicated here with the same
// function name.
// Ignore issues from commonly used lints in this file.
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
// ignore_for_file:unused_import, file_names
import 'package:intl/intl.dart';
import 'package:intl/message_lookup_by_library.dart';
final messages = new MessageLookup();
// ignore: unused_element
final _keepAnalysisHappy = Intl.defaultLocale;
// ignore: non_constant_identifier_names
typedef MessageIfAbsent(String message_str, List args);
typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
class MessageLookup extends MessageLookupByLibrary {
get localeName => 'es';
String get localeName => 'es_ES';
final messages = _notInlinedMessages(_notInlinedMessages);
static _notInlinedMessages(_) => <String, Function> {
"market" : MessageLookupByLibrary.simpleMessage("MERCADO"),
"portfolio" : MessageLookupByLibrary.simpleMessage("CARTERA"),
"title" : MessageLookupByLibrary.simpleMessage("Acciones"),
"title" : MessageLookupByLibrary.simpleMessage("Acciones")
};
}
## Regenerating the i18n files
# Regenerating the i18n files
The files in this directory are based on ../lib/stock_strings.dart
which defines all of the localizable strings used by the stocks
app. The stocks app uses
the [Dart `intl` package](https://github.com/dart-lang/intl).
The files in this directory are used to generate `stock_strings.dart`, which
is used by the stocks application to look up localized message strings. The
stocks app uses the [Dart `intl` package](https://github.com/dart-lang/intl).
Rebuilding everything requires two steps.
With the `examples/stocks` as the current directory, generate
`intl_messages.arb` from `lib/stock_strings.dart`:
```
flutter pub pub run intl_translation:extract_to_arb --output-dir=lib/i18n lib/stock_strings.dart
```
The `intl_messages.arb` file is a JSON format map with one entry for
each `Intl.message()` function defined in `stock_strings.dart`. This
file was used to create the English and Spanish localizations,
`stocks_en.arb` and `stocks_es.arb`. The `intl_messages.arb` wasn't
checked into the repository, since it only serves as a template for
the other `.arb` files.
1. Create or update the English and Spanish localizations, `stocks_en_US.arb`
and `stocks_es_ES.arb`. See the [ARB specification](https://github.com/google/app-resource-bundle/wiki/ApplicationResourceBundleSpecification)
for more info.
2. With `examples/stocks` as the current directory, generate a
`messages_<locale>.dart` for each `stocks_<locale>.arb` file,
`messages_all.dart`, and `stock_strings.dart` with the following command:
With the `examples/stocks` as the current directory, generate a
`stock_messages_<locale>.dart` for each `stocks_<locale>.arb` file and
`stock_messages_all.dart`, which imports all of the messages files:
```
flutter pub pub run intl_translation:generate_from_arb --output-dir=lib/i18n \
--generated-file-prefix=stock_ --no-use-deferred-loading lib/*.dart lib/i18n/stocks_*.arb
```dart
dart ${FLUTTER_PATH}/dev/tools/localization/gen_l10n.dart --arb-dir=lib/i18n
--template-arb-file=stocks_en_EN.arb --output-localization-file=stock_strings.dart
--output-class=StockStrings
```
The `StockStrings` class uses the generated `initializeMessages()`
function (`stock_messages_all.dart`) to load the localized messages
and `Intl.message()` to look them up.
The `StockStrings` class uses the generated `initializeMessages()`function
(`messages_all.dart`) to load the localized messages and `Intl.message()`
to look them up. The generated class's API documentation explains how to add
the new localizations delegate and supported locales to the Flutter application.
import 'dart:async';
import 'package:flutter/widgets.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart';
import 'messages_all.dart';
/// Callers can lookup localized strings with an instance of StockStrings returned
/// by `StockStrings.of(context)`.
///
/// Applications need to include `StockStrings.delegate()` in their app's
/// localizationDelegates list, and the locales they support in the app's
/// supportedLocales list. For example:
///
/// ```
/// import 'i18n/stock_strings.dart';
///
/// return MaterialApp(
/// localizationsDelegates: StockStrings.localizationsDelegates,
/// supportedLocales: StockStrings.supportedLocales,
/// home: MyApplicationHome(),
/// );
/// ```
///
/// ## iOS Applications
///
/// iOS applications define key application metadata, including supported
/// locales, in an Info.plist file that is built into the application bundle.
/// To configure the locales supported by your app, you’ll need to edit this
/// file.
///
/// First, open your project’s ios/Runner.xcworkspace Xcode workspace file.
/// Then, in the Project Navigator, open the Info.plist file under the Runner
/// project’s Runner folder.
///
/// Next, select the Information Property List item, select Add Item from the
/// Editor menu, then select Localizations from the pop-up menu.
///
/// Select and expand the newly-created Localizations item then, for each
/// locale your application supports, add a new item and select the locale
/// you wish to add from the pop-up menu in the Value field. This list should
/// be consistent with the languages listed in the StockStrings.supportedLocales
/// property.
class StockStrings {
StockStrings(Locale locale) : _localeName = locale.toString();
final String _localeName;
static Future<StockStrings> load(Locale locale) {
return initializeMessages(locale.toString())
.then<StockStrings>((void _) => StockStrings(locale));
}
static StockStrings of(BuildContext context) {
return Localizations.of<StockStrings>(context, StockStrings);
}
static const LocalizationsDelegate<StockStrings> delegate = _StockStringsDelegate();
/// A list of this localizations delegate along with the default localizations
/// delegates.
///
/// Returns a list of localizations delegates containing this delegate along with
/// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
/// and GlobalWidgetsLocalizations.delegate.
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates = <LocalizationsDelegate<dynamic>>[
delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
];
/// A list of this localizations delegate's supported locales.
static const List<Locale> supportedLocales = <Locale>[
Locale('en', 'US'),
Locale('es', 'ES'),
];
String title() {
return Intl.message(
r'Stocks',
locale: _localeName,
name: 'title',
desc: 'Title for the Stocks application',
args: <Object>[]
);
}
String market() {
return Intl.message(
r'MARKET',
locale: _localeName,
name: 'market',
desc: 'Label for the Market tab',
args: <Object>[]
);
}
String portfolio() {
return Intl.message(
r'PORTFOLIO',
locale: _localeName,
name: 'portfolio',
desc: 'Label for the Portfolio tab',
args: <Object>[]
);
}
}
class _StockStringsDelegate extends LocalizationsDelegate<StockStrings> {
const _StockStringsDelegate();
@override
Future<StockStrings> load(Locale locale) => StockStrings.load(locale);
@override
bool isSupported(Locale locale) => <String>['en', 'es'].contains(locale.languageCode);
@override
bool shouldReload(_StockStringsDelegate old) => false;
}
......@@ -4,8 +4,6 @@
library stocks;
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart' show
debugPaintSizeEnabled,
......@@ -13,26 +11,14 @@ import 'package:flutter/rendering.dart' show
debugPaintLayerBordersEnabled,
debugPaintPointersEnabled,
debugRepaintRainbowEnabled;
import 'package:flutter_localizations/flutter_localizations.dart';
import 'i18n/stock_strings.dart';
import 'stock_data.dart';
import 'stock_home.dart';
import 'stock_settings.dart';
import 'stock_strings.dart';
import 'stock_symbol_viewer.dart';
import 'stock_types.dart';
class _StocksLocalizationsDelegate extends LocalizationsDelegate<StockStrings> {
@override
Future<StockStrings> load(Locale locale) => StockStrings.load(locale);
@override
bool isSupported(Locale locale) => locale.languageCode == 'es' || locale.languageCode == 'en';
@override
bool shouldReload(_StocksLocalizationsDelegate old) => false;
}
class StocksApp extends StatefulWidget {
@override
StocksAppState createState() => StocksAppState();
......@@ -108,15 +94,8 @@ class StocksAppState extends State<StocksApp> {
return MaterialApp(
title: 'Stocks',
theme: theme,
localizationsDelegates: <LocalizationsDelegate<dynamic>>[
_StocksLocalizationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: const <Locale>[
Locale('en', 'US'),
Locale('es', 'ES'),
],
localizationsDelegates: StockStrings.localizationsDelegates,
supportedLocales: StockStrings.supportedLocales,
debugShowMaterialGrid: _configuration.debugShowGrid,
showPerformanceOverlay: _configuration.showPerformanceOverlay,
showSemanticsDebugger: _configuration.showSemanticsDebugger,
......
......@@ -6,9 +6,10 @@ import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart' show debugDumpRenderTree, debugDumpLayerTree, debugDumpSemanticsTree, DebugSemanticsDumpOrder;
import 'package:flutter/scheduler.dart' show timeDilation;
import 'package:flutter/gestures.dart' show DragStartBehavior;
import 'i18n/stock_strings.dart';
import 'stock_data.dart';
import 'stock_list.dart';
import 'stock_strings.dart';
import 'stock_symbol_viewer.dart';
import 'stock_types.dart';
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:intl/intl.dart';
import 'package:flutter/widgets.dart';
import 'i18n/stock_messages_all.dart';
// Information about how this file relates to i18n/stock_messages_all.dart and how the i18n files
// were generated can be found in i18n/regenerate.md.
class StockStrings {
StockStrings(Locale locale) : _localeName = locale.toString();
final String _localeName;
static Future<StockStrings> load(Locale locale) {
return initializeMessages(locale.toString())
.then<StockStrings>((Object _) {
return StockStrings(locale);
});
}
static StockStrings of(BuildContext context) {
return Localizations.of<StockStrings>(context, StockStrings);
}
String title() {
return Intl.message(
'<Stocks>',
name: 'title',
desc: 'Title for the Stocks application',
locale: _localeName,
);
}
String market() => Intl.message(
'MARKET',
name: 'market',
desc: 'Label for the Market tab',
locale: _localeName,
);
String portfolio() => Intl.message(
'PORTFOLIO',
name: 'portfolio',
desc: 'Label for the Portfolio tab',
locale: _localeName,
);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment