Як перекласти поля форми WPForms
Привіт:) У цьому пості покажу, як перекласти значення полів форми плагіна WPForms на декілька мов.
Було поставлено завдання зробити мультимовний сайт. За замовчуванням було обрано українську мову, а також російську та англійську.
У ході пошуку рішень вибрав зв'язку безкоштовних розширень Polylang та WPForms. Але через штатні інструменти плагіну перекладу реалізації декількох мовних версій форми не знайшов. У результаті зробив виключно через вбудовані хуки модулі форм.
Мова за замовчуванням для проекту була обрана українською, а тому початкові значення полів прописувалися тією ж мовою. Загалом мої форми мають вигляд:
І друга:
Вони мають наступні ID:
У безкоштовній версії плагіну WPForms доступні такі типи полів:
Покажу, як додати декілька мовних версій окремих полів форми.
Name (Имя)
Це поле у моїй формі виглядає так:
Код для перекладу іншими мовами (потрібно додати до файлу functions.php):
/**
* https://wpforms.com/developers/how-to-change-sublabels-for-the-name-field/
*/
function wpf_dev_name_field_properties( $properties, $field, $form_data ) {
if ( ( absint( $form_data['id'] ) === 755 ) || ( absint( $form_data['id'] ) === 306 ) ) {
if ( get_locale() == 'ru_RU' ) {
$properties['label']['value'] = 'Напишите свое имя';
$properties['inputs']['primary']['attr']['placeholder'] = 'Например: Станислав';
} elseif ( get_locale() == 'en_US' ) {
$properties['label']['value'] = 'Enter your name';
$properties['inputs']['primary']['attr']['placeholder'] = 'For example: Stanislav';
}
}
return $properties;
}
add_filter( 'wpforms_field_properties_name' , 'wpf_dev_name_field_properties', 10, 3 );
У коді роблю перевірку, щоб переклад виконувався лише для ID цих 2-х форм. Українську версію не вказую, оскільки ці значення вказані під час створення полів за замовчуванням. Поточну мову перевіряю за допомогою функції get_locale()
.
Текст повідомлення після успішного надсилання форми
/**
* https://wpforms.com/developers/wpforms_frontend_confirmation_message/
*/
function wpf_dev_frontend_confirmation_message( $message, $form_data, $fields, $entry_id ) {
// Get the name field ID '0' to set the name for the message
$contact_name = $fields['0']['value'];
// Add the name to the message
// $message = "Thanks $contact_name we will be in touch!";
if ( ( absint( $form_data['id'] ) === 755 ) || ( absint( $form_data['id'] ) === 306 ) ) {
if (get_locale() == 'ru_RU') {
$message = "Спасибо, что оставили заявку! В ближайшее время мы с вами свяжемся.";
} elseif (get_locale() == 'en_US') {
$message = "Thank you for submitting your request! We will contact you shortly.";
}
}
return $message;
}
add_filter( 'wpforms_frontend_confirmation_message', 'wpf_dev_frontend_confirmation_message', 10, 4 );
function wpf_dev_email_field_properties( $properties, $field, $form_data ) {
if ( absint( $form_data['id'] ) !== 306 ) {
return $properties;
}
if ( get_locale() == 'ru_RU' ) {
$properties['label']['value'] = 'Укажите свой e-mail';
$properties['inputs']['primary']['attr']['placeholder'] = 'Например: stanislav@gmail.com';
} elseif ( get_locale() == 'en_US' ) {
$properties['label']['value'] = 'Enter your e-mail';
$properties['inputs']['primary']['attr']['placeholder'] = 'For example: stanislav@gmail.com';
}
return $properties;
// echo '<pre>';
// var_dump($properties['label']['value']);
// echo '</pre>';
}
add_filter( 'wpforms_field_properties_email' , 'wpf_dev_email_field_properties', 10, 3 );
Поле Email
зустрічається лише в одній формі.
Single Line Text (Строка текста)
Це поле використовував для введення номеру телефону та теми повідомлення у різних формах, тому перекладаю в одній функції.
Код буде наступним:
function wpf_dev_text_field_properties( $properties, $field, $form_data ) {
if ( absint( $form_data['id'] ) == 755 ) {
if ( get_locale() == 'ru_RU' ) {
$properties['label']['value'] = 'Укажите свой номер телефона';
} elseif ( get_locale() == 'en_US' ) {
$properties['label']['value'] = 'Enter your phone number';
}
}
if ( absint( $form_data['id'] ) == 306 ) {
if ( get_locale() == 'ru_RU' ) {
$properties['label']['value'] = 'Напишите тему сообщения';
$properties['inputs']['primary']['attr']['placeholder'] = 'Например: Предложение о сотрудничестве';
} elseif ( get_locale() == 'en_US' ) {
$properties['label']['value'] = 'Write the subject of the message';
$properties['inputs']['primary']['attr']['placeholder'] = 'For example: Proposal for cooperation ';
}
}
return $properties;
}
add_filter( 'wpforms_field_properties_text', 'wpf_dev_text_field_properties', 10, 3 );
Paragraph Text (Текст або Textarea)
function wpf_dev_textarea_field_properties( $properties, $field, $form_data ) {
if ( absint( $form_data['id'] ) !== 306 ) {
return $properties;
}
if ( get_locale() == 'ru_RU' ) {
$properties['label']['value'] = 'Напишите сообщение ';
$properties['inputs']['primary']['attr']['placeholder'] = 'Ваше сообщение ';
} elseif ( get_locale() == 'en_US' ) {
$properties['label']['value'] = 'Write a message ';
$properties['inputs']['primary']['attr']['placeholder'] = 'Your message ';
}
return $properties;
// echo '<pre>';
// var_dump($properties['label']['value']);
// echo '</pre>';
}
add_filter( 'wpforms_field_properties_textarea' , 'wpf_dev_textarea_field_properties', 10, 3 );
Dropdown (Список)
У цьому полі у мене список районів та передмість.
Для перекладу списку потрібно було дивитися значення ключа кожного елемента в масиві $properties
. В результаті:
function wpf_dev_select_field_properties( $properties, $field, $form_data ) {
if ( absint( $form_data['id'] ) !== 755 ) {
return $properties;
}
if ( get_locale() == 'ru_RU' ) {
$properties['label']['value'] = 'Выберите район города или пригорода';
$properties['inputs'][47]['label']['text'] = 'Академгородок (район города)';
$properties['inputs'][48]['label']['text'] = 'Березняки (район города)';
$properties['inputs'][49]['label']['text'] = 'Борщаговка (район города)';
$properties['inputs'][50]['label']['text'] = 'ВДНХ (район города)';
$properties['inputs'][51]['label']['text'] = 'Виноградар (район города)';
$properties['inputs'][52]['label']['text'] = 'Отрадное (район города)';
$properties['inputs'][53]['label']['text'] = 'Голосеевский (район города)';
$properties['inputs'][54]['label']['text'] = 'Дарница (район города)';
$properties['inputs'][55]['label']['text'] = 'Дарницкий (район города)';
$properties['inputs'][56]['label']['text'] = 'Деснянский (район города)';
$properties['inputs'][57]['label']['text'] = 'Днепровский (район города)';
$properties['inputs'][58]['label']['text'] = 'Куреневка (район города)';
$properties['inputs'][59]['label']['text'] = 'Левый Берег (район города)';
$properties['inputs'][60]['label']['text'] = 'Лесной Массив (район города)';
$properties['inputs'][61]['label']['text'] = 'Липки (район города)';
$properties['inputs'][62]['label']['text'] = 'Лукьяновка (район города)';
$properties['inputs'][63]['label']['text'] = 'Нивки (район города)';
$properties['inputs'][64]['label']['text'] = 'Оболонский (район города)';
$properties['inputs'][65]['label']['text'] = 'Оболонь (район города)';
$properties['inputs'][66]['label']['text'] = 'Осокорки (район города)';
$properties['inputs'][67]['label']['text'] = 'Первомайский (район города)';
$properties['inputs'][68]['label']['text'] = 'Петровка (район города)';
$properties['inputs'][69]['label']['text'] = 'Печерск (район города)';
$properties['inputs'][70]['label']['text'] = 'Печерский (район города)';
$properties['inputs'][71]['label']['text'] = 'Пирогово (район города)';
$properties['inputs'][72]['label']['text'] = 'Победа (район города)';
$properties['inputs'][73]['label']['text'] = 'Подол (район города)';
$properties['inputs'][74]['label']['text'] = 'Подольский (район города)';
$properties['inputs'][75]['label']['text'] = 'Позняки (район города)';
$properties['inputs'][76]['label']['text'] = 'Радужный Массив (район города)';
$properties['inputs'][77]['label']['text'] = 'Русановка (район города)';
$properties['inputs'][78]['label']['text'] = 'Святошино (район города)';
$properties['inputs'][79]['label']['text'] = 'Святошинский (район города)';
$properties['inputs'][80]['label']['text'] = 'Севастопольская Площадь (район города)';
$properties['inputs'][81]['label']['text'] = 'Соломенский (район города)';
$properties['inputs'][82]['label']['text'] = 'Соцгород (район города)';
$properties['inputs'][83]['label']['text'] = 'Теремки (район города)';
$properties['inputs'][84]['label']['text'] = 'Троещина (район города)';
$properties['inputs'][85]['label']['text'] = 'Харьковский Массив (район города)';
$properties['inputs'][86]['label']['text'] = 'Харьковский (район города)';
$properties['inputs'][87]['label']['text'] = 'Центр (район города)';
$properties['inputs'][88]['label']['text'] = 'Шевченковский (район города)';
$properties['inputs'][89]['label']['text'] = 'Шулявка (район города)';
$properties['inputs'][90]['label']['text'] = 'Белая Церковь (пригород)';
$properties['inputs'][91]['label']['text'] = 'Белогородка (пригород)';
$properties['inputs'][92]['label']['text'] = 'Борисполь (пригород)';
$properties['inputs'][93]['label']['text'] = 'Бородянка (пригород)';
$properties['inputs'][94]['label']['text'] = 'Боярка (пригород)';
$properties['inputs'][95]['label']['text'] = 'Бровары (пригород)';
$properties['inputs'][96]['label']['text'] = 'Буча (пригород)';
$properties['inputs'][97]['label']['text'] = 'Васильков (пригород)';
$properties['inputs'][98]['label']['text'] = 'Вита-Почтовая (пригород)';
$properties['inputs'][99]['label']['text'] = 'Вишневое (пригород)';
$properties['inputs'][100]['label']['text'] = 'Вышгород (пригород)';
$properties['inputs'][101]['label']['text'] = 'Гатное (пригород)';
$properties['inputs'][102]['label']['text'] = 'Гореничи (пригород)';
$properties['inputs'][103]['label']['text'] = 'Ирпень (пригород)';
$properties['inputs'][104]['label']['text'] = 'Козин (пригород)';
$properties['inputs'][105]['label']['text'] = 'Конча-Заспа (пригород)';
$properties['inputs'][106]['label']['text'] = 'Коцюбинское (пригород)';
$properties['inputs'][107]['label']['text'] = 'Крюковщина (пригород)';
$properties['inputs'][108]['label']['text'] = 'Лесники (пригород)';
$properties['inputs'][109]['label']['text'] = 'Новые Петровцы (пригород)';
$properties['inputs'][110]['label']['text'] = 'Обухов (пригород)';
$properties['inputs'][111]['label']['text'] = 'Петропавловская Борщаговка (пригород)';
$properties['inputs'][112]['label']['text'] = 'Пуща-Водица (пригород)';
$properties['inputs'][113]['label']['text'] = 'Софиевская Борщаговка (пригород)';
$properties['inputs'][114]['label']['text'] = 'Стоянка (пригород)';
$properties['inputs'][115]['label']['text'] = 'Украинка (пригород)';
$properties['inputs'][116]['label']['text'] = 'Фастов (пригород)';
$properties['inputs'][117]['label']['text'] = 'Ходосовка (пригород)';
$properties['inputs'][118]['label']['text'] = 'Хотов (пригород)';
$properties['inputs'][119]['label']['text'] = 'Чабаны (пригород)';
} elseif ( get_locale() == 'en_US' ) {
$properties['label']['value'] = 'Select an area of a city or suburb';
$properties['inputs'][47]['label']['text'] = 'Akademmistechko (district of the city)';
$properties['inputs'][48]['label']['text'] = 'Bereznyaky (district of the city)';
$properties['inputs'][49]['label']['text'] = 'Borshagivka (district of the city)';
$properties['inputs'][50]['label']['text'] = 'VDNH (district of the city)';
$properties['inputs'][51]['label']['text'] = 'Vinogradar (district of the city)';
$properties['inputs'][52]['label']['text'] = 'Vidradne (district of the city)';
$properties['inputs'][53]['label']['text'] = 'Golosiyivskyj (district of the city)';
$properties['inputs'][54]['label']['text'] = 'Darnicya (district of the city)';
$properties['inputs'][55]['label']['text'] = 'Darnickyj (district of the city)';
$properties['inputs'][56]['label']['text'] = 'Desnyanskyj (district of the city)';
$properties['inputs'][57]['label']['text'] = 'Dniprovskyj (district of the city)';
$properties['inputs'][58]['label']['text'] = 'Kurenivka (district of the city)';
$properties['inputs'][59]['label']['text'] = 'Livyj Bereg (district of the city)';
$properties['inputs'][60]['label']['text'] = 'Lisovyj Masiv (district of the city)';
$properties['inputs'][61]['label']['text'] = 'Lipky (district of the city)';
$properties['inputs'][62]['label']['text'] = 'Lukyanivka (district of the city)';
$properties['inputs'][63]['label']['text'] = 'Nivky (district of the city)';
$properties['inputs'][64]['label']['text'] = 'Obolonskyj (district of the city)';
$properties['inputs'][65]['label']['text'] = 'Obolon (district of the city)';
$properties['inputs'][66]['label']['text'] = 'Osokorky (district of the city)';
$properties['inputs'][67]['label']['text'] = 'Pervomajskyj (district of the city)';
$properties['inputs'][68]['label']['text'] = 'Petrivka (district of the city)';
$properties['inputs'][69]['label']['text'] = 'Pechersk (district of the city)';
$properties['inputs'][70]['label']['text'] = 'Pecherskyj (district of the city)';
$properties['inputs'][71]['label']['text'] = 'Pirogovo (district of the city)';
$properties['inputs'][72]['label']['text'] = 'Peremoga district of the city)';
$properties['inputs'][73]['label']['text'] = 'Podol (district of the city)';
$properties['inputs'][74]['label']['text'] = 'Podilskyj (district of the city)';
$properties['inputs'][75]['label']['text'] = 'Poznyaky (district of the city)';
$properties['inputs'][76]['label']['text'] = 'Rajduzhnyj Masiv (district of the city)';
$properties['inputs'][77]['label']['text'] = 'Rusanivka (district of the city)';
$properties['inputs'][78]['label']['text'] = 'Svyatoshino (district of the city)';
$properties['inputs'][79]['label']['text'] = 'Svyatoshinskyj (district of the city)';
$properties['inputs'][80]['label']['text'] = 'Sevastopolska Plosha (district of the city)';
$properties['inputs'][81]['label']['text'] = 'Solomyanskyj (district of the city)';
$properties['inputs'][82]['label']['text'] = 'Socmisto (district of the city)';
$properties['inputs'][83]['label']['text'] = 'Teremky (district of the city)';
$properties['inputs'][84]['label']['text'] = 'Troyeshina (district of the city)';
$properties['inputs'][85]['label']['text'] = 'Harkivskyj Masiv (district of the city)';
$properties['inputs'][86]['label']['text'] = 'Harkivskyj (district of the city)';
$properties['inputs'][87]['label']['text'] = 'Centr (district of the city)';
$properties['inputs'][88]['label']['text'] = 'Shevchenkivskyj (district of the city)';
$properties['inputs'][89]['label']['text'] = 'Shulyavka (district of the city)';
$properties['inputs'][90]['label']['text'] = 'Bila Cerkva (suburb)';
$properties['inputs'][91]['label']['text'] = 'Bilogorodka (suburb)';
$properties['inputs'][92]['label']['text'] = 'Boryspil (suburb)';
$properties['inputs'][93]['label']['text'] = 'Borodyanka (suburb)';
$properties['inputs'][94]['label']['text'] = 'Boyarka (suburb)';
$properties['inputs'][95]['label']['text'] = 'Brovary (suburb)';
$properties['inputs'][96]['label']['text'] = 'Bucha (suburb)';
$properties['inputs'][97]['label']['text'] = 'Vasilkiv (suburb)';
$properties['inputs'][98]['label']['text'] = 'Vita-Poshtova (suburb)';
$properties['inputs'][99]['label']['text'] = 'Vishneve (suburb)';
$properties['inputs'][100]['label']['text'] = 'Vishgorod (suburb)';
$properties['inputs'][101]['label']['text'] = 'Gatne (suburb)';
$properties['inputs'][102]['label']['text'] = 'Gorenichi (suburb)';
$properties['inputs'][103]['label']['text'] = 'Irpin (suburb)';
$properties['inputs'][104]['label']['text'] = 'Kozin (suburb)';
$properties['inputs'][105]['label']['text'] = 'Konche-Zaspa (suburb)';
$properties['inputs'][106]['label']['text'] = 'Kocyubinskyj (suburb)';
$properties['inputs'][107]['label']['text'] = 'Kryukivshina (suburb)';
$properties['inputs'][108]['label']['text'] = 'Lisniky (suburb)';
$properties['inputs'][109]['label']['text'] = 'Nova Petrivka (suburb)';
$properties['inputs'][110]['label']['text'] = 'Obuhiv (suburb)';
$properties['inputs'][111]['label']['text'] = 'Petropavlivska Borshagivka (suburb)';
$properties['inputs'][112]['label']['text'] = 'Pushya-Vodicya (suburb)';
$properties['inputs'][113]['label']['text'] = 'Sofiyivska Borshagivka (suburb)';
$properties['inputs'][114]['label']['text'] = 'Stoyanka (suburb)';
$properties['inputs'][115]['label']['text'] = 'Ukrayinka (suburb)';
$properties['inputs'][116]['label']['text'] = 'Fastiv (suburb)';
$properties['inputs'][117]['label']['text'] = 'Hodosivka (suburb)';
$properties['inputs'][118]['label']['text'] = 'Hotov (suburb)';
$properties['inputs'][119]['label']['text'] = 'Chabany (suburb)';
}
// error_log( print_r( $properties, 1) );
return $properties;
}
add_filter( 'wpforms_field_properties_select', 'wpf_dev_select_field_properties', 10, 3 );
Submit (Кнопка)
function wpf_dev_submit_field_properties( $settings, $form_data ) {
if ( get_locale() == 'ru_RU' ) {
return 'Отправить';
} elseif ( get_locale() == 'en_US' ) {
return 'Send';
}
return $settings;
}
add_filter( 'wpforms_field_submit', 'wpf_dev_submit_field_properties', 10, 2 );
Текст повідомлень валідації форми
function wpforms_dev_frontend_strings( $strings ) {
$currentLanguage = apply_filters( 'wpml_current_language', false );
switch ( $currentLanguage ) {
//For Russian translation
case 'ru':
//Required field
$strings['val_required'] = 'Это поле обязательно к заполнению.';
//Valid URL
$strings['val_url'] = 'Пожалуйста, введите корректный URL-адрес.';
//Valid Email
$strings['val_email'] = 'Пожалуйста, введите корректный Email-адрес.';
//Email suggestion text
$strings['val_email_suggestion'] = 'Вы имеете в виду {suggestion}?';
//Valid number
$strings['val_number'] = 'Пожалуйста введите правильное число.';
//Confirmation message 'fields do not match'
$strings['val_confirm'] = 'Значения полей не совпадают.';
//Checkbox option limit
$strings['val_checklimit'] = 'Вы превысили допустимое количество вариантов выбора: {#}.';
//Valid file type
$strings['val_extension'] = 'Тип файла не разрешен.';
//Max size limit text
$strings['val_maxsize'] = 'Файл превышает максимально допустимый размер.';
//Valid 12h time format
$strings['val_time12h'] = 'Введите время в 12-часовом формате AM/PM (например, 8:45).';
//Valid 24h time format
$strings['val_time24h'] = 'Введите время в 24-часовом формате (например, 22:45).';
//Payment required text
$strings['val_requiredpayment'] = 'Оплата обязательна.';
//Valid credit card number
$strings['val_creditcard'] = 'Пожалуйста, введите действующий номер кредитной карты.';
//Maximum size limit reached text
$strings['val_post_max_size'] = 'Общий размер выбранных файлов {totalSize} МБ превышает допустимый предел {maxSize} МБ.';
//Valid unique value required
$strings['val_validation_unique'] = 'Значение должно быть уникальным.';
//All phone field - Smart, International and US
$strings ['val_phone'] = 'Укажите действующий номер телефона.';
break;
//For Ukrainian translation
case 'uk':
//Required field
$strings['val_required'] = 'Це поле є обов\'язковим до заповнення. ';
//Valid URL
$strings['val_url'] = 'Будь ласка, введіть правильну URL-адресу.';
//Valid Email
$strings['val_email'] = 'Будь ласка, введіть правильну Email-адресу.';
//Email suggestion text
$strings['val_email_suggestion'] = 'Ви маєте на увазі {suggestion}?';
//Valid number
$strings['val_number'] = 'Введіть правильне число.';
//Confirmation message 'fields do not match'
$strings['val_confirm'] = 'Значення полів не збігаються.';
//Checkbox option limit
$strings['val_checklimit'] = 'Ви перевищили допустиму кількість варіантів вибору: {#}.';
//Valid file type
$strings['val_extension'] = 'Тип файлу заборонений.';
//Max size limit text
$strings['val_maxsize'] = 'Файл перевищує максимальний розмір.';
//Valid 12h time format
$strings['val_time12h'] = 'Введіть час у 12-годинному форматі AM/PM (наприклад, 8:45).';
//Valid 24h time format
$strings['val_time24h'] = 'Введіть час у 24-годинному форматі (наприклад, 22:45).';
//Payment required text
$strings['val_requiredpayment'] = 'Оплата є обов\'язковою.';
//Valid credit card number
$strings['val_creditcard'] = 'Будь ласка, введіть номер діючої кредитної картки. ';
//Maximum size limit reached text
$strings['val_post_max_size'] = 'Загальний розмір вибраних файлів {totalSize} МБ перевищує допустиму межу {maxSize} МБ.';
//Valid unique value required
$strings['val_validation_unique'] = 'Значення має бути унікальним.';
//All phone field - Smart, International and US
$strings ['val_phone'] = 'Вкажіть номер телефону.';
break;
}
return $strings;
}
add_filter( 'wpforms_frontend_strings', 'wpforms_dev_frontend_strings' );
Переклади цих рядків зберігаються у файлах перекладу плагіну WPForms та за замовчуванням англійською.
wpforms_field_properties_name
або wpforms_field_properties_select
).Текст повідомлення про помилку надсилання форми
/**
* https://wpforms.com/developers/how-to-change-the-error-text-for-failed-submissions/
*/
function wpf_translated( $translated_text, $text, $domain ) {
// Bail early if it's not WPForms string.
if ( $domain !== 'wpforms-lite' ) {
return $translated_text;
}
// Compare against the original string (in English).
if ( $text === 'The form was unable to submit. Please contact the site administrator.' ) {
$translated_text = __('Hey! Please check under the hood!', 'wpforms');
}
return $translated_text;
}
add_filter( 'gettext', 'wpf_translated', 10, 3 );
Цей текст помилки за замовчуванням теж англійською та прописаний у файлах перекладу плагіну.