diff --git a/README.md b/README.md index 418b6e2..27a9ace 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,14 @@ Integrates the **Ultimate Member** plugin with the **Polylang** plugin. Makes Ul ## Key features -- Localized permalinks for the Account and User (profile) pages. -- Ability to duplicate Ultimate Member forms for all languages in one click. +- Language switcher shortcode. Display the Polylang language switcher where you need it. +- Localize permalinks for the Account and User (profile) pages. - Ability to duplicate Ultimate Member pages for all languages in one click. +- Ability to duplicate Ultimate Member forms for all languages in one click. - Ability to translate email templates. - Ability to translate bio (description) field in profile. +- Integration with the [Account tabs](https://github.com/umdevelopera/um-account-tabs) extension. Makes custom account tabs translatable. +- Integration with the [Profile tabs](https://ultimatemember.com/extensions/profile-tabs/) extension. Makes custom profile tabs translatable. ## Installation @@ -24,18 +27,42 @@ Once the plugin is cloned, enter your site admin dashboard and go to _wp-admin > ### How to install from ZIP archive -You can install this plugin from the [ZIP archive](https://drive.google.com/file/d/17n3Kr05_B_edsGY7An7xu85TZ7H5gbOT/view?usp=sharing) as any other plugin. Follow [this instruction](https://wordpress.org/support/article/managing-plugins/#upload-via-wordpress-admin). +You can install this plugin from the [ZIP archive](https://drive.google.com/file/d/1rj0W6639PMrFQqLfeCZXhoYgRcnCac8d/view?usp=sharing) as any other plugin. Follow [this instruction](https://wordpress.org/support/article/managing-plugins/#upload-via-wordpress-admin). ## How to use +### How to display language switcher + +Add the **[um_pll_switcher]** shortcode to the place you need. + +Shortcode attributes: +- int `dropdown` Displays languages into a dropdown if set to 1. Defaults to 0. +- int `show_flags` Displays flags if set to 1. Defaults to 1. +- int `show_names` Shows language names if set to 1. Defaults to 1. +- string `display_names_as` Whether to display the language name or its slug. Accepts 'slug' and 'name'. Defaults to 'name'. +- string `item_display` Whether to display languages as a list or inline. Accepts 'list-item' and 'inline'. Defaults to 'inline'. +- string `item_spacing` Whether to preserve or discard whitespace between list items. Accepts 'preserve' and 'discard'. Defaults to 'preserve'. +- int `hide_current` Hides the current language if set to 1. Defaults to 0. +- int `hide_if_no_translation` Hides the link if there is no translation if set to 1. Defaults to 0. + +See also [Options](https://polylang.pro/doc/the-language-switcher/#options) + +**Screenshots** + +Image - Language switcher shortcode in the header template. + + +Image - Language switcher in the page header. + + ### How to translate pages Go to *wp-admin > Pages* to translate Ultimate Member pages. Click the **Create Pages** button in the notice to duplicate Ultimate Member pages for all languages. Or click the "+" icon unter the flag to duplicate each page manually. Image - Translate pages. - + -Go to *wp-admin > Settings > Permalinks* and click the **Save Changes** button if you need to update rewrite rules for the Account and User page permalinks. +Go to *wp-admin > Settings > Permalinks* if you need to update rewrite rules for the Account and User page permalinks. Don't change settings on this page, just visit it. WordPress will update rewrite rules. Note: The "Post name" permalink structure is recommended. Image - Permalink settings. @@ -46,12 +73,12 @@ Image - Permalink settings. Go to *wp-admin > Ultimate Member > Forms* to translate Ultimate Member forms. Click the **Create Forms** button in the notice to duplicate Ultimate Member forms for all languages. Or click the "+" icon unter the flag to duplicate each form manually. Image - Translate forms. - + Once forms for languages are created you can open these forms and translate fields. You have to translate a **Label** for custom fields. You also can translate **Placeholder** and **Help Text** if needed. -**Choices** are not translatable, this is necessary for the directory search to work correctly. Don't try to translate choices in the field settings! You can use custom functions to translate choices. -See examples: +__Note:__ Choices in the Checkbox, Radio, Dropdown and Multi-Select fields are not translatable. This is necessary for the directory filters to work correctly. Don't try to translate choices in the field settings! +You can use custom functions to translate choices. See examples here: - [How to translate choices of the Checkbox field](https://gist.github.com/umdevelopera/f7b0e07d5db870c9ce9fc1e513224e45) - [How to translate choices of the Dropdown field](https://gist.github.com/umdevelopera/bcc8c882ead5914845b489ece73b612d) @@ -62,7 +89,25 @@ See examples: Go to *wp-admin > Ultimate Member > Settings > Email* to translate email templates. Click the "+" icon unter the flag to translate a template for the language. The plugin saves translated email templates to locale subfolders in the theme, see [Email Templates](https://docs.ultimatemember.com/article/1335-email-templates). Image - Translate emails. - + + +### How to translate custom account tabs + +This feature is available if you use the [Account tabs](https://github.com/umdevelopera/um-account-tabs) extension. + +Go to *wp-admin > Ultimate Member > Account Tabs*. Click the **Create Tabs** button in the notice to duplicate tabs for all languages. Once the tabs are duplicated for each language, you can manually edit the tab title. + +Image - Translate account tabs. + + +### How to translate custom profile tabs + +This feature is available if you use the [Profile tabs](https://ultimatemember.com/extensions/profile-tabs/) extension. + +Go to *wp-admin > Ultimate Member > Profile Tabs*. Click the **Create Tabs** button in the notice to duplicate tabs for all languages. Once the tabs are duplicated for each language, you can manually edit the tab title. + +Image - Translate profile tabs. + ## Support @@ -75,6 +120,6 @@ Ultimate Member home page: https://ultimatemember.com/ Ultimate Member documentation: https://docs.ultimatemember.com/ -Ultimate Member on wordpress.org: https://wordpress.org/plugins/ultimate-member/ +Ultimate Member download: https://wordpress.org/plugins/ultimate-member/ -Article: [How to translate plugin](https://docs.ultimatemember.com/article/1449-how-to-translate-plugin#switch). +Articles: [How to translate plugin](https://docs.ultimatemember.com/article/1449-how-to-translate-plugin#switch), [The language switcher](https://polylang.pro/doc/the-language-switcher/) diff --git a/includes/admin/class-admin.php b/includes/admin/class-admin.php index 9803a46..78903a0 100644 --- a/includes/admin/class-admin.php +++ b/includes/admin/class-admin.php @@ -21,6 +21,18 @@ */ class Admin { + const NOTICES = array( + 'um_pll_create_forms', + 'um_pll_create_pages', + 'um_pll_create_account_tabs', + 'um_pll_create_profile_tabs', + ); + + const POST_TYPES = array( + 'um_form' => 'um_form', + 'um_account_tabs' => 'um_account_tabs', + 'um_profile_tabs' => 'um_profile_tabs', + ); /** * Admin constructor. @@ -110,8 +122,11 @@ public function notice_create_forms() { } $need_translations = array(); - foreach ( $posts as $post => $post_id ) { - if ( $def_lang !== pll_get_post_language( $post_id ) ) { + foreach ( $posts as $post_id ) { + $cur_lang = pll_get_post_language( $post_id ); + if ( false === $cur_lang ) { + pll_set_post_language( $post_id, PLL()->pref_lang ); + } elseif ( $def_lang !== $cur_lang ) { continue; } $post_translations = pll_get_post_translations( $post_id ); @@ -121,43 +136,41 @@ public function notice_create_forms() { } if ( $need_translations ) { - $url_params = array( - 'um_adm_action' => 'um_pll_create_forms', - '_wpnonce' => wp_create_nonce( 'um_pll_create_forms' ), - ); - - $url = add_query_arg( $url_params ); - - ob_start(); - ?> + $url_params = array( + 'um_adm_action' => 'um_pll_create_forms', + '_wpnonce' => wp_create_nonce( 'um_pll_create_forms' ), + ); -
- -
- + $url = add_query_arg( $url_params ); + ob_start(); + ?> +'notice-warning', - 'message' => $message, - 'dismissible' => true, + // translators: %1$s - plugin name, %2$s - a list of forms. + echo esc_html( + sprintf( + __( '%1$s needs to create required forms for every language to function correctly. Forms that need translation: %2$s', 'um-polylang' ), + UM_PLUGIN_NAME, + implode( ', ', $need_translations ) + ) ); + ?> +
+ + admin()->notices()->add_notice( 'um_pll_create_forms', $notice_data, 20 ); + $notice_data = array( + 'class' => 'notice-warning', + 'message' => $message, + 'dismissible' => true, + ); + + UM()->admin()->notices()->add_notice( 'um_pll_create_forms', $notice_data, 20 ); } } @@ -205,7 +218,6 @@ public function notice_create_pages() { ob_start(); ?> -" class="button button-primary">
- flush_rewrite_rules(); + $this->reset_admin_notices(); } } diff --git a/includes/core/class-shortcodes.php b/includes/core/class-shortcodes.php new file mode 100644 index 0000000..fffdd06 --- /dev/null +++ b/includes/core/class-shortcodes.php @@ -0,0 +1,86 @@ + 0, // Display as list and not as dropdown. + 'show_flags' => 1, // Don't show flags. + 'show_names' => 1, // Show language names. + 'display_names_as' => 'name', // Display the language name. + 'item_display' => 'inline', // CSS "display" property for list items. + 'item_spacing' => 'preserve', // Preserve whitespace between list items. + 'force_home' => 0, // Tries to find a translation. + 'hide_current' => 0, // Don't hide the current language. + 'hide_if_no_translation' => 0, // Don't hide the link if there is no translation. + 'admin_render' => 0, // Make the switcher in a frontend context. + 'echo' => 0, // Echoes the list. + 'raw' => 0, // Build the language switcher. + ); + + /** + * Class constructor. + */ + public function __construct() { + add_shortcode( 'um_pll_switcher', array( $this, 'um_pll_switcher' ) ); + } + + /** + * Displays a language switcher. + * + * Shortcode: [um_pll_switcher] + * + * @param array $atts { + * Optional array of arguments. + * + * @type int $dropdown The list is displayed as dropdown if set, defaults to 0. + * @type int $show_flags Displays flags if set to 1, defaults to 1. + * @type int $show_names Shows language names if set to 1, defaults to 1. + * @type string $display_names_as Whether to display the language name or its slug, valid options are 'slug' and 'name', defaults to 'name'. + * @type string $item_display Optional CSS "display" property for list items. Valid options are 'list-item' and 'inline', defaults to 'inline'. + * @type string $item_spacing Whether to preserve or discard whitespace between list items, valid options are 'preserve' and 'discard', defaults to 'preserve'. + * @type int $hide_current Hides the current language if set to 1, defaults to 0. + * @type int $hide_if_no_translation Hides the link if there is no translation if set to 1, defaults to 0. + * } + * @return string|array either the html markup of the switcher or the raw elements to build a custom language switcher + */ + function um_pll_switcher( $atts ) { + $args = shortcode_atts( self::DEFAULTS, $atts ); + + $output = $this->the_languages( PLL()->links, $args ); + if ( empty( $args['dropdown'] ) ) { + if ( ! empty( $args['item_display'] ) ) { + $search = '+ +
+ + 'notice-warning', + 'message' => $message, + 'dismissible' => true, + ); + + UM()->admin()->notices()->add_notice( 'um_pll_create_account_tabs', $notice_data, 20 ); + } +} +add_action( 'in_admin_header', 'um_polylang_account_tabs_notice' ); + + +/** + * Display a notice after um_adm_action. + * + * @param array $messages Admin notice messages. + * @param string $update Update action key. + * @return array + */ +function um_polylang_account_tabs_notice_update( $messages, $update ) { + if ( 'um_pll_create_account_tabs' === $update ) { + $messages[0]['content'] = __( 'Tabs have been duplicated successfully.', 'um-polylang' ); + } + return $messages; +} +add_filter( 'um_adm_action_custom_notice_update', 'um_polylang_account_tabs_notice_update', 10, 2 ); +add_filter( 'um_adm_action_custom_update_notice', 'um_polylang_account_tabs_notice_update', 10, 2 ); + + +/** + * Localize custom account tabs. + * + * @param array $tabs All custom account tabs like posts array. + * @return array Custom account tabs for the current language. Uses default language tab if no tab for the current. + */ +function um_polylang_account_tabs_get_tabs( $tabs ) { + if ( is_array( $tabs ) ) { + $current = UM()->Polylang()->get_current(); + $default = UM()->Polylang()->get_default(); + foreach( $tabs as $i => $tab ) { + $post_id = is_object( $tab ) ? $tab->ID : absint( $tab ); + $post_lang = pll_get_post_language( $post_id ); + if ( $post_lang === $current ) { + continue; + } + if ( $post_lang === $default && ! pll_get_post( $post_id, $current ) ) { + continue; + } + unset( $tabs[ $i ] ); + } + } + return $tabs; +} +add_filter( 'um_account_tabs_get_tabs', 'um_polylang_account_tabs_get_tabs', 10, 1 ); diff --git a/includes/extensions/profile-tabs.php b/includes/extensions/profile-tabs.php new file mode 100644 index 0000000..1f3edf3 --- /dev/null +++ b/includes/extensions/profile-tabs.php @@ -0,0 +1,287 @@ + 'ids', + 'nopaging' => true, + 'post_status' => 'publish', + 'post_type' => 'um_profile_tabs', + ); + $posts = get_posts( $args ); + + UM()->Polylang()->posts()->create_posts( $posts, 'um_profile_tabs' ); + + $url = add_query_arg( 'update', 'um_pll_create_profile_tabs', admin_url( 'edit.php?post_type=um_profile_tabs' ) ); + exit( wp_safe_redirect( $url ) ); +} +add_action( 'um_admin_do_action__um_pll_create_profile_tabs', 'um_polylang_profile_tabs_create' ); + + +/** + * Update the "Custom Profile Form" setting in the translated tab. + * + * @see um_ext\um_polylang\core\Posts::create_posts() + * + * @param int $tr_id Translated post ID. + * @param int $post_id Original post ID. + * @param string $lang Translated language slug. + * @param string $post_type Post type. + */ +function um_polylang_profile_tabs_create_posts( $tr_id, $post_id, $lang, $post_type ) { + if ( 'um_profile_tabs' === $post_type ) { + $um_form = get_post_meta( $post_id, 'um_form', true ); + if ( ! empty( $um_form ) ) { + $tr_um_form = pll_get_post( $um_form, $lang ); + if ( ! empty( $tr_um_form ) ) { + update_post_meta( $tr_id, 'um_form', $tr_um_form ); + } + } + } +} +add_action( 'um_polylang_create_posts', 'um_polylang_profile_tabs_create_posts', 10, 4 ); + + +/** + * Display a notice with the "Create Tabs" button. + * + * @return void + */ +function um_polylang_profile_tabs_notice() { + $screen = get_current_screen(); + if ( ! is_object( $screen ) || 'edit-um_profile_tabs' !== $screen->id ) { + return; + } + + $languages = pll_languages_list(); + if ( empty( $languages ) ) { + return; + } + $def_lang = pll_default_language(); + + $args = array( + 'fields' => 'ids', + 'nopaging' => true, + 'post_status' => 'publish', + 'post_type' => 'um_profile_tabs', + ); + $posts = get_posts( $args ); + if ( empty( $posts ) ) { + return; + } + + $need_translations = array(); + foreach ( $posts as $post_id ) { + $cur_lang = pll_get_post_language( $post_id ); + if ( false === $cur_lang ) { + pll_set_post_language( $post_id, PLL()->pref_lang ); + } elseif ( $def_lang !== $cur_lang ) { + continue; + } + $post_translations = pll_get_post_translations( $post_id ); + if ( array_diff( $languages, array_keys( $post_translations ) ) ) { + $need_translations[ $post_id ] = get_the_title( $post_id ); + } + } + + if ( $need_translations ) { + $url_params = array( + 'um_adm_action' => 'um_pll_create_profile_tabs', + '_wpnonce' => wp_create_nonce( 'um_pll_create_profile_tabs' ), + ); + + $url = add_query_arg( $url_params ); + + ob_start(); + ?> ++ +
+ + 'notice-warning', + 'message' => $message, + 'dismissible' => true, + ); + + UM()->admin()->notices()->add_notice( 'um_pll_create_profile_tabs', $notice_data, 20 ); + } +} +add_action( 'in_admin_header', 'um_polylang_profile_tabs_notice' ); + + +/** + * Display a notice after um_adm_action. + * + * @param array $messages Admin notice messages. + * @param string $update Update action key. + * @return array + */ +function um_polylang_profile_tabs_notice_update( $messages, $update ) { + if ( 'um_pll_create_profile_tabs' === $update ) { + $messages[0]['content'] = __( 'Tabs have been duplicated successfully.', 'um-polylang' ); + } + return $messages; +} +add_filter( 'um_adm_action_custom_notice_update', 'um_polylang_profile_tabs_notice_update', 10, 2 ); +add_filter( 'um_adm_action_custom_update_notice', 'um_polylang_profile_tabs_notice_update', 10, 2 ); + + +/** + * Add custom profile tabs. + * + * @param array $tabs Profile tabs. + * @return array + */ +function um_polylang_profile_tabs_add_tabs( $tabs ) { + $custom_tabs = um_polylang_profile_tabs_get_tabs(); + if ( $custom_tabs ) { + foreach ( $custom_tabs as $tab ) { + $tabs[ $tab['tabid'] ] = array( + 'ID' => $tab['id'], + 'name' => $tab['title'], + 'icon' => $tab['icon'], + 'is_custom_added' => true, + ); + } + } + return $tabs; +} +add_filter( 'um_profile_tabs', 'um_polylang_profile_tabs_add_tabs', 9999, 1 ); +remove_filter( 'um_profile_tabs', array( UM()->Profile_Tabs()->profile(), 'add_tabs' ), 9999, 1 ); +remove_filter( 'um_profile_tabs', array( UM()->Profile_Tabs()->profile(), 'predefine_tabs' ), 1, 1 ); + + +/** + * Initialize custom profile tabs before adding them to the profile menu. + * + * @staticvar boolean $custom_tabs + * @return array Localized profile tabs array. + */ +function um_polylang_profile_tabs_get_tabs() { + static $custom_tabs = false; + + if ( false === $custom_tabs ) { + $custom_tabs = array(); + + $args = array( + 'numberposts' => -1, + 'post_status' => 'publish', + 'post_type' => 'um_profile_tabs', + ); + $tabs = get_posts( $args ); + + if ( $tabs && is_array( $tabs ) ) { + + // Localize custom profile tabs. + $current = UM()->Polylang()->get_current(); + $default = UM()->Polylang()->get_default(); + foreach( $tabs as $i => $tab ) { + $post_id = is_object( $tab ) ? $tab->ID : absint( $tab ); + $post_lang = pll_get_post_language( $post_id ); + if ( $post_lang === $current ) { + continue; + } + if ( $post_lang === $default && ! pll_get_post( $post_id, $current ) ) { + continue; + } + unset( $tabs[ $i ] ); + } + + // Build tabs. + foreach ( $tabs as $tab ) { + $slug = $tab->um_tab_slug ? $tab->um_tab_slug : $tab->post_name; + if ( isset( $custom_tabs[ $slug ] ) ) { + continue; + } + + $link_type = (int) $tab->um_link_type; + $tab_link = ! $link_type ? '' : $tab->um_tab_link; + + $tab = array( + 'tabid' => $slug, + 'id' => $tab->ID, + 'title' => $tab->post_title, + 'content' => $tab->post_content, + 'form' => $tab->um_form, + 'icon' => $tab->um_icon ? $tab->um_icon : 'fas fa-check', + 'link_type' => $link_type, + 'tab_link' => $tab_link, + ); + + $custom_tabs[ $slug ] = $tab; + + if ( empty( $tab_link ) ) { + // Show content. + add_action( + "um_profile_content_{$slug}", + function( $args ) use ( $tab ) { + $content = wpautop( $tab['content'] ); + $tab_content = um_convert_tags( $content, array(), false ); + + if ( ! empty( $tab['form'] ) ) { + add_filter( 'um_force_shortcode_render', array( UM()->Profile_Tabs()->profile(), 'force_break_form_shortcode' ) ); + } + if ( class_exists( '\Elementor\Plugin' ) ) { + \Elementor\Plugin::instance()->frontend->remove_content_filter(); + } + + echo apply_filters( 'the_content', $tab_content ); + + if ( class_exists( '\Elementor\Plugin' ) ) { + \Elementor\Plugin::instance()->frontend->add_content_filter(); + } + if ( ! empty( $tab['form'] ) ) { + remove_filter( 'um_force_shortcode_render', array( UM()->Profile_Tabs()->profile(), 'force_break_form_shortcode' ) ); + echo ''; + echo UM()->Profile_Tabs()->profile()->um_custom_tab_form( $tab['tabid'], $tab['form'] ); + } + } + ); + } else { + // Show remote link. + add_filter( + "um_profile_menu_link_{$slug}", + function( $nav_link ) use ( $tab_link ) { + return $tab_link; + } + ); + add_filter( + "um_profile_menu_link_{$slug}_attrs", + function( $profile_nav_attrs ) { + return $profile_nav_attrs . ' target="_blank"'; + } + ); + } + } + } + } + + return $custom_tabs; +} diff --git a/languages/um-polylang-en_US.l10n.php b/languages/um-polylang-en_US.l10n.php new file mode 100644 index 0000000..2f5ba2b --- /dev/null +++ b/languages/um-polylang-en_US.l10n.php @@ -0,0 +1,2 @@ +'Ultimate Member - Polylang','report-msgid-bugs-to'=>'','pot-creation-date'=>'2023-12-03 23:01+0000','po-revision-date'=>'2024-11-10 20:47+0000','last-translator'=>'DeveloperA UltimateMember','language-team'=>'English (United States)','language'=>'en_US','plural-forms'=>'nplurals=2; plural=n != 1;','mime-version'=>'1.0','content-type'=>'text/plain; charset=UTF-8','content-transfer-encoding'=>'8bit','x-generator'=>'Loco https://localise.biz/','x-loco-version'=>'2.6.6; wp-6.4.1','x-domain'=>'um-polylang','messages'=>[]]; diff --git a/languages/um-polylang-en_US.mo b/languages/um-polylang-en_US.mo index 78bcd5c..b636fe5 100644 Binary files a/languages/um-polylang-en_US.mo and b/languages/um-polylang-en_US.mo differ diff --git a/languages/um-polylang-en_US.po b/languages/um-polylang-en_US.po index e0c58bd..608d805 100644 --- a/languages/um-polylang-en_US.po +++ b/languages/um-polylang-en_US.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: Ultimate Member - Polylang\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-12-03 23:01+0000\n" -"PO-Revision-Date: 2023-12-24 19:26+0000\n" +"PO-Revision-Date: 2024-11-10 20:47+0000\n" "Last-Translator: DeveloperA UltimateMember\n" "Language-Team: English (United States)\n" "Language: en_US\n" @@ -16,7 +16,7 @@ msgstr "" "X-Domain: um-polylang" #. %1$s - plugin name, %2$s - a list of forms. -#: includes/admin/class-admin.php:138 +#: includes/admin/class-admin.php:153 #, php-format msgid "" "%1$s needs to create required forms for every language to function correctly." @@ -24,22 +24,36 @@ msgid "" msgstr "" #. %1$s - plugin name, %2$s - a list of pages. -#: includes/admin/class-admin.php:213 +#: includes/admin/class-admin.php:226 #, php-format msgid "" "%1$s needs to create required pages for every language to function correctly." " Pages that need translation: %2$s" msgstr "" -#: includes/admin/class-admin.php:146 +#: includes/admin/class-admin.php:161 msgid "Create Forms" msgstr "" -#: includes/admin/class-admin.php:221 +#: includes/admin/class-admin.php:234 msgid "Create Pages" msgstr "" -#: includes/admin/class-admin.php:252 +#: includes/extensions/account-tabs.php:121 +#: includes/extensions/profile-tabs.php:121 +msgid "Create Tabs" +msgstr "" + +#. %1$s - a list of tabs. +#: includes/extensions/account-tabs.php:114 +#: includes/extensions/profile-tabs.php:114 +#, php-format +msgid "" +"Extension needs to create tabs for every language to function correctly. " +"Tabs that need translation: %1$s" +msgstr "" + +#: includes/admin/class-admin.php:264 msgid "Forms have been duplicated successfully." msgstr "" @@ -55,14 +69,21 @@ msgstr "" msgid "Integrates Ultimate Member with Polylang." msgstr "" -#: includes/admin/class-admin.php:147 includes/admin/class-admin.php:222 +#: includes/admin/class-admin.php:162 includes/admin/class-admin.php:235 +#: includes/extensions/account-tabs.php:122 +#: includes/extensions/profile-tabs.php:122 msgid "No thanks" msgstr "" -#: includes/admin/class-admin.php:256 +#: includes/admin/class-admin.php:268 msgid "Pages have been duplicated successfully." msgstr "" +#: includes/extensions/account-tabs.php:148 +#: includes/extensions/profile-tabs.php:148 +msgid "Tabs have been duplicated successfully." +msgstr "" + #. %s - plugin name. #: um-polylang.php:69 #, php-format diff --git a/languages/um-polylang.pot b/languages/um-polylang.pot index a9956ae..3d40963 100644 --- a/languages/um-polylang.pot +++ b/languages/um-polylang.pot @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Ultimate Member - Polylang\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-12-24 19:26+0000\n" +"POT-Creation-Date: 2024-11-10 20:47+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME