gen_l10n_templates.dart 7.6 KB
Newer Older
1 2 3 4
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5
const String fileTemplate = '''
6
@(header)
7 8
import 'dart:async';

9
// ignore: unused_import
10
import 'package:flutter/foundation.dart';
11 12
import 'package:flutter/widgets.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
13
import 'package:intl/intl.dart' as intl;
14

15 16
@(messageClassImports)

17 18
/// Callers can lookup localized strings with an instance of @(class) returned
/// by `@(class).of(context)`.
19
///
20 21
/// Applications need to include `@(class).delegate()` in their app\'s
/// localizationDelegates list, and the locales they support in the app\'s
22 23 24 25 26 27
/// supportedLocales list. For example:
///
/// ```
/// import '@(importFile)';
///
/// return MaterialApp(
28 29
///   localizationsDelegates: @(class).localizationsDelegates,
///   supportedLocales: @(class).supportedLocales,
30 31 32 33 34 35 36 37 38 39 40 41 42 43
///   home: MyApplicationHome(),
/// );
/// ```
///
/// ## Update pubspec.yaml
///
/// Please make sure to update your pubspec.yaml to include the following
/// packages:
///
/// ```
/// dependencies:
///   # Internationalization support.
///   flutter_localizations:
///     sdk: flutter
44
///   intl: 0.16.1
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
///
///   # rest of dependencies
/// ```
///
/// ## 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
66
/// be consistent with the languages listed in the @(class).supportedLocales
67
/// property.
68
abstract class @(class) {
69
  @(class)(String locale) : assert(locale != null), localeName = intl.Intl.canonicalizedLocale(locale.toString());
70

71
  // ignore: unused_field
72
  final String localeName;
73

74 75
  static @(class) of(BuildContext context) {
    return Localizations.of<@(class)>(context, @(class));
76 77
  }

78
  static const LocalizationsDelegate<@(class)> delegate = _@(class)Delegate();
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97

  /// 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.
  ///
  /// Additional delegates can be added by appending to this list in
  /// MaterialApp. This list does not have to be used at all if a custom list
  /// of delegates is preferred or required.
  static const List<LocalizationsDelegate<dynamic>> localizationsDelegates = <LocalizationsDelegate<dynamic>>[
    delegate,
    GlobalMaterialLocalizations.delegate,
    GlobalCupertinoLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
  ];

  /// A list of this localizations delegate's supported locales.
98 99 100
  static const List<Locale> supportedLocales = <Locale>[
    @(supportedLocales)
  ];
101

102
@(methods)}
103

104
@(delegateClass)
105 106 107 108
''';

const String numberFormatTemplate = '''
    final intl.NumberFormat @(placeholder)NumberFormat = intl.NumberFormat.@(format)(
109
      locale: localeName,
110 111 112 113 114 115
      @(parameters)
    );
    final String @(placeholder)String = @(placeholder)NumberFormat.format(@(placeholder));
''';

const String dateFormatTemplate = '''
116
    final intl.DateFormat @(placeholder)DateFormat = intl.DateFormat.@(format)(localeName);
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
    final String @(placeholder)String = @(placeholder)DateFormat.format(@(placeholder));
''';

const String getterTemplate = '''
  @override
  String get @(name) => @(message);''';

const String methodTemplate = '''
  @override
  String @(name)(@(parameters)) {
    return @(message);
  }''';

const String formatMethodTemplate = '''
  @override
  String @(name)(@(parameters)) {
@(dateFormatting)
@(numberFormatting)
    return @(message);
  }''';

const String pluralMethodTemplate = '''
  @override
  String @(name)(@(parameters)) {
@(dateFormatting)
@(numberFormatting)
    return intl.Intl.pluralLogic(
      @(count),
145
      locale: localeName,
146 147 148 149
@(pluralLogicArgs),
    );
  }''';

150 151 152 153 154 155 156 157
const String classFileTemplate = '''
@(header)
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import '@(fileName)';

// ignore_for_file: unnecessary_brace_in_string_interps

158 159 160 161 162
/// The translations for @(language) (`@(localeName)`).
class @(class) extends @(baseClass) {
  @(class)([String locale = '@(localeName)']) : super(locale);

@(methods)
163 164 165 166 167 168 169 170 171 172 173 174
}
@(subclasses)''';

const String subclassTemplate = '''

/// The translations for @(language) (`@(localeName)`).
class @(class) extends @(baseLanguageClassName) {
  @(class)(): super('@(localeName)');

@(methods)
}
''';
175 176 177 178

const String baseClassGetterTemplate = '''
  // @(comment)
  String get @(name);
179
''';
180 181 182 183 184 185

const String baseClassMethodTemplate = '''
  // @(comment)
  String @(name)(@(parameters));
''';

186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
// DELEGATE CLASS TEMPLATES

const String delegateClassTemplate = '''
class _@(class)Delegate extends LocalizationsDelegate<@(class)> {
  const _@(class)Delegate();

  @override
  Future<@(class)> load(Locale locale) {
    @(loadBody)
  }

  @override
  bool isSupported(Locale locale) => <String>[@(supportedLanguageCodes)].contains(locale.languageCode);

  @override
  bool shouldReload(_@(class)Delegate old) => false;
}

@(lookupFunction)''';

const String loadBodyTemplate = '''return SynchronousFuture<@(class)>(@(lookupName)(locale));''';

const String loadBodyDeferredLoadingTemplate = '''return @(lookupName)(locale);''';

210 211
// DELEGATE LOOKUP TEMPLATES

212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
const String lookupFunctionTemplate = '''
@(class) @(lookupName)(Locale locale) {
  @(lookupBody)
  assert(false, '@(class).delegate failed to load unsupported locale "\$locale"');
  return null;
}''';

const String lookupFunctionDeferredLoadingTemplate = '''
/// Lazy load the library for web, on other platforms we return the
/// localizations synchronously.
Future<@(class)> _loadLibraryForWeb(
  Future<dynamic> Function() loadLibrary,
  @(class) Function() localizationClosure,
) {
  if (kIsWeb) {
    return loadLibrary().then((dynamic _) => localizationClosure());
  } else {
    return SynchronousFuture<@(class)>(localizationClosure());
  }
}

Future<@(class)> @(lookupName)(Locale locale) {
  @(lookupBody)
  assert(false, '@(class).delegate failed to load unsupported locale "\$locale"');
  return null;
}''';

239 240 241 242 243
const String lookupBodyTemplate = '''@(lookupAllCodesSpecified)
  @(lookupScriptCodeSpecified)
  @(lookupCountryCodeSpecified)
  @(lookupLanguageCodeSpecified)''';

244 245 246
const String switchClauseTemplate = '''case '@(case)': return @(localeClass)();''';

const String switchClauseDeferredLoadingTemplate = '''case '@(case)': return _loadLibraryForWeb(@(library).loadLibrary, () => @(library).@(localeClass)());''';
247

248 249
const String nestedSwitchTemplate = '''case '@(languageCode)': {
      switch (locale.@(code)) {
250 251
        @(switchClauses)
      }
252
      break;
253
    }''';
254 255 256 257 258 259 260 261 262 263 264 265

const String languageCodeSwitchTemplate = '''@(comment)
  switch (locale.languageCode) {
    @(switchClauses)
  }
''';

const String allCodesLookupTemplate = '''// Lookup logic when language+script+country codes are specified.
  switch (locale.toString()) {
    @(allCodesSwitchClauses)
  }
''';