Viewing 10 posts - 1 through 10 (of 10 total)
  • Author
    Posts
  • #1493525

    Hello, I am using LayerSlider 8.1.2. I would like to switch this great plugin to German in the backend, but I am unable to do so. Here’s what I’ve already done:

    To deactivate the integrated LayerSlider in the Enfold theme:

    1. I added the entry add_theme_support(‘deactivate_layerslider’); to the functions.php file of my child theme.
    2. I copied the unzipped LayerSlider folder via FTP to /wp-content/plugins/.
    3. I activated LayerSlider on the Plugins page in WordPress.
    4. Everything worked correctly.

    To switch LayerSlider to German:

    1. I translated the LayerSlider-en_US.pot file with Poedit.
    2. I copied the LayerSlider-de_DE.po and LayerSlider-de_DE.mo files via FTP to /wp-content/plugins/LayerSlider/assets/locales.
    3. The site language in WordPress under Settings → General is set to “German”.
    4. My WordPress profile language is set to “Site Default”.

    The German language does not appear as an option in the LayerSlider backend dropdown menu. Only the pre-installed languages are available.

    Kreatura writes:
    “It’s also expected behavior that the LayerSlider language dropdown only lists the built-in languages shown in your screenshot. Custom translations added manually won’t appear there, but they’re loaded automatically based on WordPress’ active locale.”

    In the LayerSlider backend under General Settings, the language is set to “Site default”, but German still isn’t loading. What do I need to change?

    Best regards

    #1493548

    on tmpl-plugin-settings.php add your edited language manually – and upload it to the assets/templates folder via ftp

    <select name="ls_custom_locale" data-confirm="<?= __('The selected language has been changed. Reload the page to apply the new language?', 'LayerSlider') ?>">
    	<option value="auto" <?php echo ( $custom_locale === 'auto' ) ? 'selected' : ''?>><?php _e('Site default', 'LayerSlider') ?></option>
    	<option value="en_US" <?php echo ( $custom_locale === 'en_US' ) ? 'selected' : ''?>>English (United States)</option>
    	<option value="fr_FR" <?php echo ( $custom_locale === 'fr_FR' ) ? 'selected' : ''?>>Français</option>
    	<option value="de_DE" <?php echo ( $custom_locale === 'de_DE' ) ? 'selected' : ''?>>Deutsch</option>
    	<option value="hu_HU" <?php echo ( $custom_locale === 'hu_HU' ) ? 'selected' : ''?>>Magyar</option>
    	<option value="uk" <?php echo ( $custom_locale === 'uk' ) ? 'selected' : ''?>>Українська</option>
    </select>

    then you find your language in the drop down.:

    a reload of the page will then switch to your lang files

    i inserted in that drop-down list my german lang option:

    i only tested it with some of the translations – f.e.:

    #1493549

    Hi,

    Thank you for the inquiry.

    Have you tried completely removing the Layer Slider plugin from the theme via Enfold > Layout Builder > Integrated (Bundled) LayerSlider Plugin settings instead of using the deactivate_layerslider hook? If you can provide the login details in the private field, we’ll try to check this further.

    Best regards,
    Ismael

    #1493554

    i have this stand alone Version too – because i do have some Licenses for Layerslider.
    so this seems to be very similar to Herb. I decided to completely remove theme plugin files ( and keep slides ) option.

    but – i do not have a proper child-theme solution for that now – maybe i find a way to do that.…

    #1493559

    Hi, Guenni007,
    Thank you so much for your great help — the language switch now works exactly as I wanted. You’re my hero!
    Questions:
    1. I assume I have to reinsert the code line after every LayerSlider update.
    2. Would it make sense to completely remove the LayerSlider included in Enfold?
    3. If so, would I then have to remove the LayerSlider again after every Enfold update? It would be nice if there were an option, for example a toggle switch (LayerSlider on/off), to permanently deactivate and delete the included LayerSlider.

    Hi, Ismael,
    Thank you for your quick reply. I’m unsure whether I should completely remove the bundled LayerSlider plugin. That might only cause problems and unnecessary effort.
    Best Regards
    Herb

    #1493566

    If you have a license for a standalone plugin, you can remove the included Layerslider. Since I already had some projects beforehand, I used the removal option mentioned above.
    Since the projects are not stored in the plugin folder, they can be retained.

    ______

    I’m looking for a child theme solution that is update-proof, but that doesn’t seem to be as easy as I initially thought.
    I thought I could read the language files in the locales folder and then automatically add the newly found languages to the select menu. And do so in such a way that an auto-patch is performed even after a plugin update.

    BTW: maybe you offer your translation to KreaturaMedia – maybe they will include that files.

    #1493574

    here we go – Edit: i think this is the better way to do it :
    https://kriesi.at/support/topic/layerslider-translation-into-german-does-not-work/#post-1493597
    ________________________
    (just for standalone plugin – not for the included layerslider)

    /**
     * LayerSlider: Auto-Patch for Select Option of lang files
     */
    
    // 1. Daily auto-patch
    function child_theme_layerslider_auto_patch() {
        if (!defined('LS_ROOT_PATH')) {
            return;
        }
        
        // Check only once a day
        $last_check = get_option('layerslider_patch_last_check', 0);
        if (time() - $last_check < DAY_IN_SECONDS) {
            return;
        }
        
        child_theme_patch_layerslider_template();
        update_option('layerslider_patch_last_check', time());
    }
    add_action('admin_init', 'child_theme_layerslider_auto_patch', 999);
    
    // 2. Patch-Function
    function child_theme_patch_layerslider_template() {
        $template_file = LS_ROOT_PATH . '/templates/tmpl-plugin-settings.php';
        $locales_dir = LS_ROOT_PATH . '/locales';
        
        if (!file_exists($template_file) || !is_dir($locales_dir)) {
            return false;
        }
        
        // Find available languages
        $available_languages = child_theme_get_available_languages($locales_dir);
        
        if (empty($available_languages)) {
            return false;
        }
        
        $content = file_get_contents($template_file);
        
        // language names
        $language_names = [
            'de_DE' => 'Deutsch',
            'de_DE_formal' => 'Deutsch (Sie)',
            'de_CH' => 'Deutsch (Schweiz)',
            'de_CH_informal' => 'Deutsch (Schweiz, Du)',
            'de_AT' => 'Deutsch (Österreich)',
            // add lang names needed for your uploaded lang files
        ];
        
        // protected default languages 
        $protected_languages = ['auto', 'en_US', 'fr_FR', 'hu_HU', 'uk'];
        
        $modified = false;
        
        // PART 1: Adding missing languages
        $new_options = '';
        foreach ($available_languages as $locale) {
            if (strpos($content, 'value="' . $locale . '"') !== false) {
                continue;
            }
            
            $language_name = isset($language_names[$locale]) ? $language_names[$locale] : $locale;
            $new_options .= "\n\t\t\t\t\t\t<option value=\"" . $locale . "\" <?php echo ( \$custom_locale === '" . $locale . "' ) ? 'selected' : ''?>>" . $language_name . "</option>";
            $modified = true;
        }
        
        if (!empty($new_options)) {
            $search = '<option value="auto" <?php echo ( $custom_locale === \'auto\' ) ? \'selected\' : \'\'?>><?php _e(\'Site default\', \'LayerSlider\') ?></option>';
            $replace = $search . $new_options;
            $content = str_replace($search, $replace, $content);
        }
        
        // PART 2: Removing languages that no longer exist
        foreach ($language_names as $locale => $name) {
            if (in_array($locale, $protected_languages)) {
                continue;
            }
            
            if (strpos($content, 'value="' . $locale . '"') !== false && !in_array($locale, $available_languages)) {
                $pattern = '/\s*<option value="' . preg_quote($locale, '/') . '"[^>]*>.*?<\/option>/';
                $new_content = preg_replace($pattern, '', $content);
                
                if ($new_content !== $content) {
                    $content = $new_content;
                    $modified = true;
                }
            }
        }
        
        if (!$modified) {
            return true;
        }
        
        // Back up and save
        file_put_contents($template_file . '.backup-' . date('Y-m-d-His'), file_get_contents($template_file));
        file_put_contents($template_file, $content);
        
        return true;
    }
    
    // 3. helper function
    function child_theme_get_available_languages($locales_dir) {
        $languages = [];
        $files = glob($locales_dir . '/LayerSlider-*.mo');
    
        if (!$files) {
            return $languages;
        }
    
        foreach ($files as $file) {
            $filename = basename($file, '.mo');
            $locale = str_replace('LayerSlider-', '', $filename);
            if (!empty($locale)) {
                $languages[] = $locale;
            }
        }   
        return $languages;
    }
    
    // 4. Automatically patch after plugin update
    function child_theme_layerslider_after_update($upgrader_object, $options) {
        if ($options['action'] !== 'update' || $options['type'] !== 'plugin') {
            return;
        }
        
        if (!isset($options['plugins'])) {
            return;
        }
        
        foreach ($options['plugins'] as $plugin) {
            if (strpos($plugin, 'layerslider') !== false || strpos($plugin, 'LayerSlider') !== false) {
                delete_option('layerslider_patch_last_check');
                child_theme_patch_layerslider_template();
                break;
            }
        }
    }
    add_action('upgrader_process_complete', 'child_theme_layerslider_after_update', 10, 2);
    
    /**
     * END of LayerSlider: Auto-Patch for Select Option of lang files
     */

    Summary of the final solution:
    ✅ Upload language files to /LayerSlider/assets/locales/
    ✅ Automatic patch after 24 hours
    ✅ Automatic patch after plugin updates
    ✅ when needed: delete_option(‘layerslider_patch_last_check’); – for immediate patch

    these snippets will inspect each day – if there are additional lang files for LayerSlider

    PS: You can force the patcher by temporarily inserting the following to your child-theme functions.php: delete_option('layerslider_patch_last_check');
    after that goto Layerslider Dashboard and : Plugin Updates – Re-Check

    #1493575

    can you send me your german lang file please?
    – thanks in advance –
    – if you do not like to post it here on public – send me an e-mail (links are under my avatar or nick)

    #1493597

    this is i think the best option to handle the lang files:
    it is a only manual patch vor those lang files of LayerSlider.
    Or automatic after Plugin Update
    Just uploading the lang-files to /wp-content/plugins/LayerSlider/assets/locales folder

    You will have than a button on the LayerSlider Admin bar:

    
    /* ========================================================================
     * LayerSlider: Patch for Select Option of lang files
     * Auto-copies language files from uploads to plugin directory
     * Auto-removes language files that were deleted from uploads
     * Auto-patches after plugin updates
     ======================================================================== */
    
    // 1. Patch-Function
    function child_theme_patch_layerslider_template() {
    
        if (!defined('LS_ROOT_PATH')) {
            return false;
        }
    
        $template_file = LS_ROOT_PATH . '/templates/tmpl-plugin-settings.php';
        
        // Check both locations
        $plugin_locales_dir = LS_ROOT_PATH . '/locales';
        $upload_dir = wp_upload_dir();
        $custom_locales_dir = $upload_dir['basedir'] . '/layerslider/lang';
        
        if (!file_exists($template_file)) {
            return false;
        }
        
        // Create custom locales directory if it doesn't exist
        if (!is_dir($custom_locales_dir)) {
            wp_mkdir_p($custom_locales_dir);
        }
        
        // SYNC language files (copy new/updated, delete removed)
        child_theme_sync_language_files($custom_locales_dir, $plugin_locales_dir);
        
        // Find available languages (now from plugin directory after sync)
        $available_languages = child_theme_get_available_languages($plugin_locales_dir);
        
        if (empty($available_languages)) {
            return false;
        }
        
        $content = file_get_contents($template_file);
        
        // language names
        $language_names = [
            'de_DE' => 'Deutsch',
            'de_DE_formal' => 'Deutsch (Sie)',
            'de_CH' => 'Deutsch (Schweiz)',
            'de_CH_informal' => 'Deutsch (Schweiz, Du)',
            'de_AT' => 'Deutsch (Österreich)',
            // add lang names needed for your uploaded lang files
        ];
        
        // protected default languages 
        $protected_languages = ['auto', 'en_US', 'fr_FR', 'hu_HU', 'uk'];
        
        $modified = false;
        
        // PART 1: Adding missing languages
        $new_options = '';
        foreach ($available_languages as $locale) {
            if (strpos($content, 'value="' . $locale . '"') !== false) {
                continue;
            }
            
            $language_name = isset($language_names[$locale]) ? $language_names[$locale] : $locale;
            $new_options .= "\n\t\t\t\t\t\t<option value=\"" . $locale . "\" <?php echo ( \$custom_locale === '" . $locale . "' ) ? 'selected' : ''?>>" . $language_name . "</option>";
            $modified = true;
        }
        
        if (!empty($new_options)) {
            $search = '<option value="auto" <?php echo ( $custom_locale === \'auto\' ) ? \'selected\' : \'\'?>><?php _e(\'Site default\', \'LayerSlider\') ?></option>';
            $replace = $search . $new_options;
            $content = str_replace($search, $replace, $content);
        }
        
        // PART 2: Removing languages that no longer exist
        foreach ($language_names as $locale => $name) {
            if (in_array($locale, $protected_languages)) {
                continue;
            }
            
            if (strpos($content, 'value="' . $locale . '"') !== false && !in_array($locale, $available_languages)) {
                $pattern = '/\s*<option value="' . preg_quote($locale, '/') . '"[^>]*>.*?<\/option>/';
                $new_content = preg_replace($pattern, '', $content);
                
                if ($new_content !== $content) {
                    $content = $new_content;
                    $modified = true;
                }
            }
        }
        
        if (!$modified) {
            return true;
        }
        
        // Save
        file_put_contents($template_file, $content);
        
        return true;
    }
    
    // 2. IMPROVED: Sync language files (copy new + delete removed)
    function child_theme_sync_language_files($source_dir, $target_dir) {
        
        if (!is_dir($source_dir) || !is_dir($target_dir)) {
            return false;
        }
        
        $copied = 0;
        $deleted = 0;
        
        // PART 1: Copy new/updated files from source to target
        $source_files = glob($source_dir . '/LayerSlider-*.{mo,po}', GLOB_BRACE);
        
        // Get list of locales in source directory
        $source_locales = [];
        if ($source_files) {
            foreach ($source_files as $source_file) {
                $filename = basename($source_file);
                $target_file = $target_dir . '/' . $filename;
                
                // Extract locale from filename
                preg_match('/LayerSlider-([^\.]+)\./', $filename, $matches);
                if (isset($matches[1])) {
                    $source_locales[] = $matches[1];
                }
                
                // Copy if doesn't exist or is newer
                if (!file_exists($target_file) || filemtime($source_file) > filemtime($target_file)) {
                    if (copy($source_file, $target_file)) {
                        $copied++;
                    }
                }
            }
        }
        
        // Remove duplicates
        $source_locales = array_unique($source_locales);
        
        // PART 2: Delete files from target that don't exist in source
        $target_files = glob($target_dir . '/LayerSlider-*.{mo,po}', GLOB_BRACE);
        
        // Protected locales (never delete these - they're from the plugin itself)
        $protected_locales = ['en_US', 'fr_FR', 'hu_HU', 'uk'];
        
        if ($target_files) {
            foreach ($target_files as $target_file) {
                $filename = basename($target_file);
                
                // Extract locale from filename
                preg_match('/LayerSlider-([^\.]+)\./', $filename, $matches);
                if (!isset($matches[1])) {
                    continue;
                }
                
                $locale = $matches[1];
                
                // Skip protected locales
                if (in_array($locale, $protected_locales)) {
                    continue;
                }
                
                // If this locale is NOT in source directory, delete it from target
                if (!in_array($locale, $source_locales)) {
                    if (unlink($target_file)) {
                        $deleted++;
                    }
                }
            }
        }
        
        return ['copied' => $copied, 'deleted' => $deleted];
    }
    
    // 3. Helper function
    function child_theme_get_available_languages($locales_dir) {
        $languages = [];
        
        if (!is_dir($locales_dir)) {
            return $languages;
        }
        
        $files = glob($locales_dir . '/LayerSlider-*.mo');
        
        if (!$files) {
            return $languages;
        }
        
        foreach ($files as $file) {
            $filename = basename($file, '.mo');
            $locale = str_replace('LayerSlider-', '', $filename);
            if (!empty($locale)) {
                $languages[] = $locale;
            }
        }
        
        return $languages;
    }
    
    // 4. Insert button in dashboard
    function child_theme_layerslider_add_sync_button() {
    	$screen = get_current_screen();
    	if (!$screen || strpos($screen->id, 'layerslider') === false) {
    	    return;
    	}
    	?>
    	<script type="text/javascript">
    	    jQuery(document).ready(function($) {
    	        setTimeout(function() {
    	            if ($('.ls-sync-languages-button').length > 0) {
    	                return;
    	            }
    	            
    	            var $settingsButton = $('.ls-open-plugin-settings-button');
    	            
    	            if ($settingsButton.length === 0) {
    	                return;
    	            }
    	            
    	            var syncUrl = <?php echo wp_json_encode(add_query_arg('ls_sync', '1', admin_url('admin.php?page=layerslider'))); ?>;
    	            
    	            var $syncButton = $('<a>', {
    	                href: syncUrl,
    	                class: 'ls-button ls-sync-languages-button',
    	                html: '<?php echo addslashes(lsGetSVGIcon("globe")); ?>'
    	            });
    	               
    	            $settingsButton.before($syncButton);
    	            
    	        }, 500);
    	    });
    	</script>
    	    
    	<style>
    	.ls-sync-languages-button:hover {
    	    color: #fff;
    	    background: #54575f;
    	    border-color: #0000;
    	    transition: opacity 0.2s;
    	}
    	</style>
    	<?php
    }
    add_action('admin_footer', 'child_theme_layerslider_add_sync_button');
    
    // 5. MANUAL TRIGGER
    function child_theme_layerslider_manual_sync() {
        if (!isset($_GET['ls_sync']) || $_GET['ls_sync'] != '1') {
            return;
        }
        
        if (!current_user_can('manage_options')) {
            wp_die('No permission');
        }
        
        $success = child_theme_patch_layerslider_template();
        
        $redirect_url = admin_url('admin.php?page=layerslider');
        
        if ($success !== false) {
            $redirect_url = wp_json_encode(add_query_arg('ls_synced', '1', $redirect_url));
        } else {
            $redirect_url = wp_json_encode(add_query_arg('ls_sync_failed', '1', $redirect_url));
        }
        
        wp_redirect($redirect_url);
        exit;
    }
    add_action('admin_init', 'child_theme_layerslider_manual_sync', 1);
    
    // 6. AUTO-PATCH after plugin update
    function child_theme_layerslider_after_update($upgrader_object, $options) {
        if ($options['action'] !== 'update' || $options['type'] !== 'plugin') {
            return;
        }
        
        if (!isset($options['plugins'])) {
            return;
        }
        
        foreach ($options['plugins'] as $plugin) {
            if (strpos($plugin, 'layerslider') !== false || strpos($plugin, 'LayerSlider') !== false) {
                // Run patch automatically after LayerSlider update
                child_theme_patch_layerslider_template();
                break;
            }
        }
    }
    add_action('upgrader_process_complete', 'child_theme_layerslider_after_update', 10, 2);
    
    #1493610

    by the way : this is only for standalone Plugin of LayerSlider.
    maybe i find some time to adjust that snippets to the included Layerslider in the new year.

Viewing 10 posts - 1 through 10 (of 10 total)
  • You must be logged in to reply to this topic.