language.api.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. <?php
  2. /**
  3. * @file
  4. * Hooks provided by the base system for language support.
  5. */
  6. use Drupal\Core\Language\LanguageInterface;
  7. /**
  8. * @defgroup i18n Internationalization
  9. * @{
  10. * Internationalization and translation
  11. *
  12. * The principle of internationalization is that it should be possible to make a
  13. * Drupal site in any language (or a multi-lingual site), where only content in
  14. * the desired language is displayed for any particular page request. In order
  15. * to make this happen, developers of modules, themes, and installation profiles
  16. * need to make sure that all of the displayable content and user interface (UI)
  17. * text that their project deals with is internationalized properly, so that it
  18. * can be translated using the standard Drupal translation mechanisms.
  19. *
  20. * @section internationalization Internationalization
  21. * Different @link info_types types of information in Drupal @endlink have
  22. * different methods for internationalization, and different portions of the
  23. * UI also have different methods for internationalization. Here is a list of
  24. * the different mechanisms for internationalization, and some notes:
  25. * - UI text is always put into code and related files in English.
  26. * - Any time UI text is displayed using PHP code, it should be passed through
  27. * either the global t() function or a t() method on the class. If it
  28. * involves plurals, it should be passed through either the global
  29. * \Drupal\Core\StringTranslation\PluralTranslatableMarkup::createFromTranslatedString()
  30. * or a formatPlural() method on the class. Use
  31. * \Drupal\Core\StringTranslation\StringTranslationTrait to get these methods
  32. * into a class.
  33. * - Dates displayed in the UI should be passed through the 'date' service
  34. * class's format() method. Again see the Services topic; the method to
  35. * call is \Drupal\Core\Datetime\Date::format().
  36. * - Some YML files contain UI text that is automatically translatable:
  37. * - *.routing.yml files: route titles. This also applies to
  38. * *.links.task.yml, *.links.action.yml, and *.links.contextual.yml files.
  39. * - *.info.yml files: module names and descriptions.
  40. * - For configuration, make sure any configuration that is displayable to
  41. * users is marked as translatable in the configuration schema. Configuration
  42. * types label, text, and date_format are translatable; string is
  43. * non-translatable text. See the @link config_api Config API topic @endlink
  44. * for more information.
  45. * - For annotation, make sure that any text that is displayable in the UI
  46. * is wrapped in \@Translation(). See the
  47. * @link plugin_translatable Plugin translatables topic @endlink for more
  48. * information.
  49. * - Content entities are translatable if they have
  50. * @code
  51. * translatable = TRUE,
  52. * @endcode
  53. * in their annotation. The use of entities to store user-editable content to
  54. * be displayed in the site is highly recommended over creating your own
  55. * method for storing, retrieving, displaying, and internationalizing content.
  56. * - For Twig templates, use 't' or 'trans' filters to indicate translatable
  57. * text. See https://www.drupal.org/node/2133321 for more information.
  58. * - In JavaScript code, use the Drupal.t() and Drupal.formatPlural() functions
  59. * (defined in core/misc/drupal.js) to translate UI text.
  60. * - If you are using a custom module, theme, etc. that is not hosted on
  61. * Drupal.org, see
  62. * @link interface_translation_properties Interface translation properties topic @endlink
  63. * for information on how to make sure your UI text is translatable.
  64. *
  65. * @section translation Translation
  66. * Once your data and user interface are internationalized, the following Core
  67. * modules are used to translate it into different languages (machine names of
  68. * modules in parentheses):
  69. * - Language (language): Define which languages are active on the site.
  70. * - Interface Translation (locale): Translate UI text.
  71. * - Content Translation (content_translation): Translate content entities.
  72. * - Configuration Translation (config_translation): Translate configuration.
  73. *
  74. * The Interface Translation module deserves special mention, because besides
  75. * providing a UI for translating UI text, it also imports community
  76. * translations from the
  77. * @link https://localize.drupal.org Drupal translation server. @endlink If
  78. * UI text and provided configuration in Drupal Core and contributed modules,
  79. * themes, and installation profiles is properly internationalized (as described
  80. * above), the text is automatically added to the translation server for
  81. * community members to translate, via *.po files that are generated by
  82. * scanning the project files.
  83. *
  84. * @section context Translation string sharing and context
  85. * By default, translated strings are only translated once, no matter where
  86. * they are being used. For instance, there are many forms with Save
  87. * buttons on them, and they all would have t('Save') in their code. The
  88. * translation system will only store this string once in the translation
  89. * database, so that if the translation is updated, all forms using that text
  90. * will get the updated translation.
  91. *
  92. * Because the source of translation strings is English, and some words in
  93. * English have multiple meanings or uses, this centralized, shared translation
  94. * string storage can sometimes lead to ambiguous translations that are not
  95. * correct for every place the string is used. As an example, the English word
  96. * "May", in a string by itself, could be part of a list of full month names or
  97. * part of a list of 3-letter abbreviated month names. So, in languages where
  98. * the month name for May is longer than 3 letters, you'd need to translate May
  99. * differently depending on how it's being used. To address this problem, the
  100. * translation system includes the concept of the "context" of a translated
  101. * string, which can be used to disambiguate text for translators, and obtain
  102. * the correct translation for each usage of the string.
  103. *
  104. * Here are some examples of how to provide translation context with strings, so
  105. * that this information can be included in *.po files, displayed on the
  106. * localization server for translators, and used to obtain the correct
  107. * translation in the user interface:
  108. * @code
  109. * // PHP code
  110. * t('May', [], ['context' => 'Long month name']);
  111. * \Drupal::translation()->formatPlural($count, '1 something',
  112. * '@count somethings', [], ['context' => 'My context']);
  113. *
  114. * // JavaScript code
  115. * Drupal.t('May', {}, {'context': 'Long month name'});
  116. * Drupal.formatPlural(count, '1 something', '@count somethings', {},
  117. * {'context': 'My context'});
  118. *
  119. * // *.links.yml file
  120. * title: 'May'
  121. * title_context: 'Long month name'
  122. *
  123. * // *.routing.yml file
  124. * my.route.name:
  125. * pattern: '/something'
  126. * defaults:
  127. * _title: 'May'
  128. * _title_context: 'Long month name'
  129. *
  130. * // Config schema to say that a certain piece of configuration should be
  131. * // translatable using the Config Translation API. Note that the schema label
  132. * // is also translatable, but it cannot have context.
  133. * date_format:
  134. * type: string
  135. * label: 'PHP date format'
  136. * translatable: true
  137. * translation context: 'PHP date format'
  138. *
  139. * // Twig template
  140. * {% trans with {'context': 'Long month name'} %}
  141. * May
  142. * {% endtrans %}
  143. * @endcode
  144. *
  145. * @see transliteration
  146. * @see t()
  147. * @}
  148. */
  149. /**
  150. * @addtogroup hooks
  151. * @{
  152. */
  153. /**
  154. * Perform alterations on language switcher links.
  155. *
  156. * A language switcher link may need to point to a different path or use a
  157. * translated link text before going through the link generator, which will
  158. * just handle the path aliases.
  159. *
  160. * @param array $links
  161. * Nested array of links keyed by language code.
  162. * @param string $type
  163. * The language type the links will switch.
  164. * @param \Drupal\Core\Url $url
  165. * The URL the switch links will be relative to.
  166. */
  167. function hook_language_switch_links_alter(array &$links, $type, \Drupal\Core\Url $url) {
  168. $language_interface = \Drupal::languageManager()->getCurrentLanguage();
  169. if ($type == LanguageInterface::TYPE_CONTENT && isset($links[$language_interface->getId()])) {
  170. foreach ($links[$language_interface->getId()] as $link) {
  171. $link['attributes']['class'][] = 'active-language';
  172. }
  173. }
  174. }
  175. /**
  176. * @} End of "addtogroup hooks".
  177. */
  178. /**
  179. * @defgroup transliteration Transliteration
  180. * @{
  181. * Transliterate from Unicode to US-ASCII
  182. *
  183. * Transliteration is the process of translating individual non-US-ASCII
  184. * characters into ASCII characters, which specifically does not transform
  185. * non-printable and punctuation characters in any way. This process will always
  186. * be both inexact and language-dependent. For instance, the character Ö (O with
  187. * an umlaut) is commonly transliterated as O, but in German text, the
  188. * convention would be to transliterate it as Oe or OE, depending on the context
  189. * (beginning of a capitalized word, or in an all-capital letter context).
  190. *
  191. * The Drupal default transliteration process transliterates text character by
  192. * character using a database of generic character transliterations and
  193. * language-specific overrides. Character context (such as all-capitals
  194. * vs. initial capital letter only) is not taken into account, and in
  195. * transliterations of capital letters that result in two or more letters, by
  196. * convention only the first is capitalized in the Drupal transliteration
  197. * result. Also, only Unicode characters of 4 bytes or less can be
  198. * transliterated in the base system; language-specific overrides can be made
  199. * for longer Unicode characters. So, the process has limitations; however,
  200. * since the reason for transliteration is typically to create machine names or
  201. * file names, this should not really be a problem. After transliteration,
  202. * other transformation or validation may be necessary, such as converting
  203. * spaces to another character, removing non-printable characters,
  204. * lower-casing, etc.
  205. *
  206. * Here is a code snippet to transliterate some text:
  207. * @code
  208. * // Use the current default interface language.
  209. * $langcode = \Drupal::languageManager()->getCurrentLanguage()->getId();
  210. * // Instantiate the transliteration class.
  211. * $trans = \Drupal::transliteration();
  212. * // Use this to transliterate some text.
  213. * $transformed = $trans->transliterate($string, $langcode);
  214. * @endcode
  215. *
  216. * Drupal Core provides the generic transliteration character tables and
  217. * overrides for a few common languages; modules can implement
  218. * hook_transliteration_overrides_alter() to provide further language-specific
  219. * overrides (including providing transliteration for Unicode characters that
  220. * are longer than 4 bytes). Modules can also completely override the
  221. * transliteration classes in \Drupal\Core\CoreServiceProvider.
  222. */
  223. /**
  224. * Provide language-specific overrides for transliteration.
  225. *
  226. * If the overrides you want to provide are standard for your language, consider
  227. * providing a patch for the Drupal Core transliteration system instead of using
  228. * this hook. This hook can be used temporarily until Drupal Core's
  229. * transliteration tables are fixed, or for sites that want to use a
  230. * non-standard transliteration system.
  231. *
  232. * @param array $overrides
  233. * Associative array of language-specific overrides whose keys are integer
  234. * Unicode character codes, and whose values are the transliterations of those
  235. * characters in the given language, to override default transliterations.
  236. * @param string $langcode
  237. * The code for the language that is being transliterated.
  238. *
  239. * @ingroup hooks
  240. */
  241. function hook_transliteration_overrides_alter(&$overrides, $langcode) {
  242. // Provide special overrides for German for a custom site.
  243. if ($langcode == 'de') {
  244. // The core-provided transliteration of Ä is Ae, but we want just A.
  245. $overrides[0xC4] = 'A';
  246. }
  247. }
  248. /**
  249. * @} End of "defgroup transliteration".
  250. */