انگلیسی پرکاربردترین زبان جهان است ، اما از هر هفت نفر فقط یک نفر به آن صحبت می کند. این زبان اولین (بومی) 379 میلیون نفر است ، اما 917 میلیون به چینی ماندارین صحبت می كنند ، 460 میلیون به اسپانیایی صحبت می كنند و 341 میلیون به هندی صحبت می كنند.

بسیاری از افراد غیر انگلیسی زبان در بازارهای در حال ظهور با رشد تصاعدی اینترنت اقامت دارند. اگر برنامه وب شما قابل ترجمه جهانی باشد ، بازار هدف بالقوه شما می تواند 700٪ افزایش یابد!

JavaScript Internationalization API (i18n نیز شناخته می شود) به شما امکان می دهد صفحات وب و برنامه ها را به گونه ای طراحی کنید که بتوانند به راحتی برای پشتیبانی از نیازهای کاربرانی که به زبان های مختلف صحبت می کنند سازگار شوند.

در این مقاله ، ما به روش های مختلفی که API ارائه می دهد و اینکه چگونه می توانید آنها را در کد خود پیاده سازی کنید تا مخاطبان بین المللی و گسترده تری را بررسی کنیم ، بررسی خواهیم کرد.

بین المللی سازی (I18n) می تواند مشکل باشد

بین المللی سازی آسان به نظر می رسد … تا زمانی که سعی کنید آن را انجام دهید.

زبانهای مبتنی بر لاتین می توانند از نظر سطحی مشابه باشند. به عنوان مثال ، فرم درخواست نام ، ایمیل و تاریخ به صورت زیر ترجمه می شود:

  • اسپانیایی: نام ، ایمیل ، تاریخ
  • فرانسوی: nom ، ایمیل ، تاریخ
  • آلمانی: نام ، ایمیل ، داده

دریافت متن چندین دهه است که سیستم بین المللی سازی و محلی سازی وجود دارد و کتابخانه ها برای اکثر زبان های برنامه نویسی در دسترس هستند.

در موارد ساده تر ، می توانید از نوعی توکن سازی استفاده کنید. به عنوان مثال ، یک الگوی HTML حاوی موارد زیر بگیرید:

<label for="name">{{ NAME }}</label>

این به صورت پویا جایگزین می شود ‘نام’ هنگامی که یک کاربر انگلیسی را به عنوان زبان اصلی خود تنظیم می کند. متأسفانه ، این همان جایی است که مشکلات برای رابط کاربری شما شروع می شود:

  1. تنوع مختلفی از یک زبان وجود دارد. اسپانیایی که در اسپانیا صحبت می شود با آمریکای جنوبی یکسان نیست.
  2. کلمات در یک زبان می توانند در زبانهای دیگر طولانی تر باشند. به عنوان مثال ، “ایمیل” در روسی به “электронное письмо” ترجمه می شود.
  3. متن همیشه از چپ به راست نیست. بعضی از آنها از راست به چپ نوشته شده است – مانند عربی ، عبری ، کردی و ییدیش. سایر موارد را می توان از بالا به پایین نوشت ، مانند چینی ، کره ای ، ژاپنی و تایوانی.

با به حداقل رساندن متن و اتخاذ خصوصیات CSS مانند موارد دیگر می توان برطرف کرد direction، writing-mode، و ابعاد منطقی برای چیدمان

آشفتگی اصطلاحات

هنگامی که در برنامه شما نیاز به نمایش تاریخ ، زمان ، تعداد ، ارز یا واحد باشد ، سردرگمی بیشتر ایجاد خواهد شد.

تاریخی را در نظر بگیرید که به عنوان “24/12/03” نشان داده شده است. به صورت زیر خوانده خواهد شد:

  • “3 دسامبر 2024” توسط ساکنان ایالات متحده که از قالب MDY استفاده می کنند
  • “12 مارس 2024” توسط ساکنان اروپایی ، آمریکای جنوبی و آسیایی که از قالب DMY استفاده می کنند ، و
  • “24 مارس 2012” توسط ساکنان کانادا ، چین ، ژاپن و مجارستان که قالب عملی تر YMD را انتخاب می کنند.

(توجه داشته باشید که بریدگی های جداساز خرما در همه زبان ها رایج نیست!)

عدد “1،000” به این صورت خوانده می شود:

  • “یک هزار” توسط کسانی که در ایالات متحده ، انگلستان ، کانادا ، چین و ژاپن و
  • “یک (نقطه صفر)” توسط کسانی که در اسپانیا ، فرانسه ، آلمان و روسیه قرار دارند که کسر اعشاری یک عدد را با کاما جدا می کند.

این شرایط حتی می تواند فقط در زبان انگلیسی پیچیده باشد. اصطلاح “1000 متر” به معنی:

  • 1 کیلومتر (یا 0.62 مایل) تا ساکنان ایالات متحده
  • مجموعه ای از هزار ابزار اندازه گیری برای کسانی که در انگلیس ، کانادا و استرالیا هستند!

JavaScript Intl API

جاوا اسکریپت که کمتر شناخته شده است Intl هدف – شی ECMAScript Internationalization API را در اکثر مرورگرها و زمانهای استفاده مدرن پیاده سازی می کند. پشتیبانی به طور کلی خوب است، و حتی IE11 بسیاری از روش های مفید تر را دارد. برای مرورگرهای قدیمی ، یک مورد وجود دارد پرکن، و API می تواند به همین ترتیب شناسایی شود:

if (window.Intl) {
  
}

API کمی غیر معمول است. چندین سازنده شی برای تاریخ ها ، زمان ها ، اعداد و لیست ها فراهم می کند که از یک مکان و یک شی اختیاری حاوی پارامترهای پیکربندی عبور می کنند. به عنوان مثال ، در اینجا یک DateTime شی specif انگلیسی انگلیسی را مشخص می کند:

const dateFormatter = new Intl.DateTimeFormat('en-US');

این شی را می توان به تعداد دفعاتی برای فراخوانی روشهای مختلفی که از آنها عبور می کند استفاده کرد Date() مقدار (یا ES6 Temporal در صورت موجود بودن). format روش معمولاً عملی ترین گزینه است. مثلا:

const valentinesDay = dateFormatter.format( new Date('2022-02-14') );


const starwarsDay = dateFormatter.format( new Date('2022-05-04') );

متناوباً ، می توانید Intl شی و اجرای یک روش در یک خط کد:

const starwarsDay = new Intl.DateTimeFormat('en-US').format( new Date('2022-05-04') );

به همان خوبی format() روش ، برخی از اشیا these از این پشتیبانی می کنند:

  • formatToParts(): آرایه ای از اشیا containing حاوی رشته های قالب بندی شده را برمی گرداند ، مانند { type: 'weekday', value: 'Monday' }
  • resolvedOptions(): یک شی new جدید را با خصوصیات منعکس کننده محلی و گزینه های قالب بندی استفاده شده ، مانند dateFormatter.resolvedOptions().locale.

تعریف مکانها

همه Intl اشیا require نیاز به a بحث محلی. این یک رشته است که شناسایی می کند:

  • زیر شاخه زبان
  • یک زیر شاخه اسکریپت (اختیاری)
  • زیر برچسب یک منطقه (یا کشور) (اختیاری)
  • یک یا چند زیرشاخه نوع (اختیاری)
  • یک یا چند توالی پسوند BCP 47 (اختیاری)
  • دنباله استفاده شخصی (اختیاری)

زبان و منطقه اغلب کافی است. مثلا، "en-US"، "fr-FR"، و غیره

و همچنین با استفاده از یک رشته ، یک Intl.locale از این شی می توان برای ساختن مکان ها استفاده کرد ، مانند انگلیسی ایالات متحده با قالب زمان 12 ساعته:

const us = new Intl.Locale('en', {
  region: 'US', hourCycle: 'h12', calendar: 'gregory'
});

این را می توان در مورد دیگری استفاده کرد Intl سازنده مثلا:

new Intl.DateTimeFormat(us, { timeStyle: 'medium' })
  .format( new Date('2022-05-04T13:00:00') );


در صورت عدم تعریف محلی ، از تنظیمات زبان و منطقه فعلی دستگاه استفاده می شود. مثلا:

new Intl.DateTimeFormat().format( new Date('2022-05-04') );

این برمی گردد "5/4/2022" در دستگاهی با تنظیمات ایالات متحده و "04/05/2022" در دستگاهی با تنظیمات UK.

تاریخ و زمان

ابزار زیر نمونه هایی از تاریخ ها و زمان های قالب بندی شده با استفاده را نشان می دهد Intl.DateTimeFormat() (اگر زبان یا منطقه شما در لیست نیست پوزش می طلبد!):

قلم را ببینید
i18n ابزار قالب بندی تاریخ و زمان
توسط SitePoint (SitePoint)
بر CodePen.

سازنده از محلی و محلی عبور می کند گزینه های شی. این ویژگی های بسیاری دارد ، اگرچه به ندرت به بیش از نیاز دارید dateStyle و یا timeStyle:

ویژگی شرح
dateStyle سبک تاریخ: "full" "long" "medium" "short"
timeStyle سبک زمان: "full" "long" "medium" "short"
calendar گزینه ها عبارتند از: "chinese" "gregory" "hebrew" "indian" "islamic" و غیره.
dayPeriod عبارات دوره: "narrow" "short" "long"
numberingSystem سیستم شماره گذاری: "arab" "beng" "fullwide" "latn" و غیره.
localeMatcher الگوریتم تطبیق محلی: "lookup" "best fit"
timeZone منطقه زمانی: "America/New_York" "Europe/Paris" و غیره.
hour12 تنظیم true برای استفاده از علامت گذاری 12 ساعته
hourCycle چرخه ساعت: "h11" "h12" "h23" "h24"
formatMatcher الگوریتم تطبیق قالب: "basic" "best fit"
weekday قالب روز هفته: "long" "short" "narrow"
era تشکیل شد: "long" "short" "narrow"
year قالب سال: "numeric" "2-digit"
month قالب ماه: "numeric" "2-digit" "long" "short" "narrow"
day قالب روز: "numeric" "2-digit"
hour قالب ساعت: "numeric" "2-digit"
minute قالب دقیقه: "numeric" "2-digit"
second قالب دوم: "numeric" "2-digit"
timeZoneName یا: "long" "short"

مثال ها:


new Intl.DateTimeFormat("ja-JP", { dateStyle: "short" })
  .format( new Date("2022-05-04T13:00") );


new Intl.DateTimeFormat("en-US", { dateStyle: "short", timeStyle: "short" })
  .format( new Date("2022-05-04T13:00") );


new Intl.DateTimeFormat("en-GB", { dateStyle: "long", timeStyle: "short" })
  .format( new Date("2022-05-04T13:00") );



new Intl.DateTimeFormat("es-ES", { dateStyle: "full", timeStyle: "full" })
  .format( new Date("2022-05-04T13:00") );

محدوده های تاریخ

آ formatRange() این روش دو تاریخ را می گیرد و بسته به محلی و گزینه ها ، دوره را به مختصر ترین حالت قالب بندی می کند. مثلا:


new Intl.DateTimeFormat("en-US", { dateStyle: "long", timeStyle: "short" })
  .formatRange(new Date("2022-05-04T13:00"), new Date("2022-05-04T14:00"))

این روش پشتیبانی محدودتری از مرورگر دارد اما در Chrome 76 پیاده سازی شده است.

دوره های نسبی

Intl.RelativeTimeFormat() شی می تواند دوره ها را نسبت به این لحظه از زمان نشان دهد. گزینه های شی گزینه های کمتری دارد:

ویژگی شرح
localeMatcher الگوریتم تطبیق محلی: "lookup" "best fit"
numeric یا "always"، به عنوان مثال "1 day ago" یا "auto"، به عنوان مثال "yesterday"
style قالب: "long" "short" "narrow"

format() روش یک مقدار عددی و یک واحد ارسال می شود: "year", "quarter", "month", "week", "day", "hour", "minute", or "second". مثال ها:


new Intl.RelativeTimeFormat("en-US")
  .format( -1, "day" );


new Intl.RelativeTimeFormat("en-US", { numeric: "auto" })
  .format( -1, "day" );


new Intl.RelativeTimeFormat("de-DE", { numeric: "auto" })
  .format( 1, "month" );

اعداد ، ارزها ، درصد ها و واحدها

ابزار زیر نمونه هایی را با استفاده از نشان می دهد Intl.NumberFormat() برای قالب بندی اعداد ، ارزها ، درصد ها و واحدهای اندازه گیری:

قلم را ببینید
شماره و قالب قالب ارز i18n
توسط SitePoint (SitePoint)
بر CodePen.

سازنده از محلی و محلی عبور می کند گزینه های شی:

ویژگی شرح
numberingSystem گزینه ها شامل "arab" "beng" "deva" "fullwide" "latn" و غیره.
notation نوع: "standard" "scientific" "engineering" "compact"
style قالب بندی: "decimal" "currency" "percent" "unit" – این تعیین می کند که کدام گزینه های دیگر را می توان تنظیم کرد
currency کد ارز: "USD" "EUR" "GBP" و غیره.
currencyDisplay قالب بندی ارز: "symbol" "narrowSymbol" "code" "name"
currencySign برای ارزشهای ارز منفی ، "standard" علامت منهای یا "accounting" برای پرانتز
unit آ نوع واحد: "centimeter" "inch" "hour" و غیره.
unitDisplay قالب واحد: "long" "short" "narrow"
useGrouping برای غیرفعال کردن هزاران جداکننده ، false تنظیم کنید
minimumIntegerDigits حداقل تعداد ارقام صحیح
minimumFractionDigits حداقل تعداد رقم کسر
maximumFractionDigits حداکثر تعداد رقم کسر
minimumSignificantDigits حداقل تعداد ارقام قابل توجه
maximumSignificantDigits حداکثر تعداد ارقام قابل توجه

مثال ها:


new Intl.NumberFormat("en-US", { maximumSignificantDigits: 2 })
  .format( 12345.6789 );


new Intl.NumberFormat("fr-FR", { maximumSignificantDigits: 3 })
  .format( 12345.6789 );


new Intl.NumberFormat("en-US", { notation: "compact", maximumSignificantDigits: 0 })
  .format( 12345.6789 );


new Intl.NumberFormat("es-ES", {
  style: "currency",
  currency: "USD",
  currencyDisplay: "symbol"
})
  .format( 12345.6789 );


new Intl.NumberFormat("en-GB", {
  maximumSignificantDigits: 0,
  style: "unit",
  unit: "meter",
  unitDisplay: "long"
})
  .format( 12345.6789 );

لیست ها

آ Intl.ListFormat() شی می تواند آرایه ای از موارد را در یک لیست حساس به زبان قالب بندی کند. در انگلیسی ، این به طور معمول به یک نیاز دارد “و” یا “یا” قبل از آخرین مورد

گزینه های شی می تواند ویژگی های زیر را تنظیم کند:

ویژگی شرح
type فرمت خروجی: "conjunction" برای ولیست های مبتنی بر "disjunction" برای یالیست های مبتنی بر
style قالب بندی: "long" "short" "narrow"

مثال ها:

const browsers = ['Chrome', 'Firefox', 'Edge', 'Safari'];


new Intl.ListFormat("en-US", { type: "conjunction" }).format(browsers);


new Intl.ListFormat("en-US", { type: "disjunction" }).format(browsers);


new Intl.ListFormat("fr-FR", { type: "conjunction" }).format(browsers);


new Intl.ListFormat("fr-FR", { type: "disjunction" }).format(browsers);

جمع جمع

کمی عجیب و غریب Intl.PluralRules() شی rules در صورت داشتن تعداد موارد ، قوانین زبان حساس به جمع را فعال می کند. گزینه های شی می تواند تنظیم کند type خاصیت به هر دو:

  • cardinal: مقدار چیزها (پیش فرض) ، یا
  • ordinal: رتبه بندی چیزها ، مانند 1st، 2nd، یا 3rd به انگلیسی

select() روش یک رشته انگلیسی را بازمی گرداند که نمایانگر دسته تعدد عدد است: zero، one، two، few، many، یا other.

مثال ها:


new Intl.PluralRules("en-US", { type: "cardinal" }).select(0);


new Intl.PluralRules("en-US", { type: "ordinal" }).select(0);


new Intl.PluralRules("en-US", { type: "cardinal" }).select(1);


new Intl.PluralRules("en-US", { type: "ordinal" }).select(1);


new Intl.PluralRules("en-US", { type: "cardinal" }).select(2);


new Intl.PluralRules("en-US", { type: "ordinal" }).select(2);


new Intl.PluralRules("en-US", { type: "cardinal" }).select(3);


new Intl.PluralRules("en-US", { type: "ordinal" }).select(3);

مقایسه رشته

سرانجام ، Intl.Collator() object مقایسه رشته حساس به زبان را امکان پذیر می کند. آن است گزینه های شی می تواند ویژگی های زیر را تنظیم کند:

ویژگی شرح
collation جمع آوری نوع برای برخی از مناطق خاص
numeric تنظیم true برای جمع عددی که “1” <"2" <"10"
caseFirst یا "upper" یا "lower" اول مورد
usage یا رشته "sort" (پیش فرض) یا "search"
sensitivity "base" "accent" "case" "variant" مقایسه
ignorePunctuation تنظیم true نادیده گرفتن علائم نگارشی

compare() روش دو رشته را مقایسه می کند. مثلا:


new Intl.Collator('de').compare('z', 'ä');

سود!

اگر از JavaScript برای نمایش داده استفاده می کنید باید ساده باشد که اطلاعات را با استفاده از قالب محلی کاربر نشان دهید. به عنوان مثال ، کد زیر a را تعریف می کند dateFormat() عملکردی که از Intl قالب تاریخ کوتاه یا برگشت به YYYY-MM-DD هنگامی که پشتیبانی نمی شود:


const dateFormat = (Intl && Intl.DateTimeFormat ?
  date => new Intl.DateTimeFormat({ dateStyle: 'short' }).format(date) :
  date => date.toISOString().slice(0, 10)
);


document.getElementById('today').textContent = dateFormat( new Date() );

این به تنهایی برنامه شما را برای مخاطبان بین المللی آسان نخواهد کرد ، اما یک قدم به توزیع جهانی نزدیک است.