Plugin Directory

Changeset 3484878


Ignore:
Timestamp:
03/17/2026 03:09:36 PM (3 weeks ago)
Author:
autoglot
Message:

Version 2.11. Adding translation exclusion filters

Location:
autoglot
Files:
66 added
9 edited

Legend:

Unmodified
Added
Removed
  • autoglot/trunk/admin/autoglot_admin.php

    r3475723 r3484878  
    673673        add_settings_section( 'section_adv_out', __('Output Settings', 'autoglot'), array($this, 'section_callback'), 'autoglot_translation_advanced');
    674674        add_settings_section( 'section_adv_search', __('Search Settings', 'autoglot'), array($this, 'section_callback'), 'autoglot_translation_advanced');
     675        add_settings_section( 'section_adv_exclusion', __('Exclusion Filters', 'autoglot'), array($this, 'section_callback'), 'autoglot_translation_advanced');
    675676        add_settings_section( 'section_linksmod', __('Language Code Insertion', 'autoglot'), array($this, 'section_callback'), 'autoglot_translation_linksmod');
    676677        add_settings_section( 'section_utilities', __('Useful Plugin Utilities', 'autoglot'), array($this, 'section_callback'), 'autoglot_translation_utilities' );
     
    10731074            case 'section_adv_search':
    10741075                echo '<p>' . esc_html__('These are advanced search settings. Please use with caution!', 'autoglot') . '</p>';
     1076                break;
     1077
     1078            case 'section_adv_exclusion':
     1079                echo '<p>' . esc_html__('Use these exclusion filters to prevent certain pages from being translated. Excluded pages will display translated content only if a translation already exists. New translations will not be generated. All links will still lead to the translated version of the site.', 'autoglot') . '</p>';
    10751080                break;
    10761081
     
    15871592                    'sanitize_callback' => array($this, 'sanitize_radio'),
    15881593                ),
     1594                array(
     1595                    'uid' => 'autoglot_translation_exclusion_urls',
     1596                    'label' => __('Exclude these URLs from translation', 'autoglot'),
     1597                    'section' => 'section_adv_exclusion',
     1598                    'page' => 'autoglot_translation_advanced',
     1599                    'placeholder' => __('Exclude these pages from translation', 'autoglot'),
     1600                    'helper' => '',
     1601                    'supplemental' => __('You can prevent specific pages from being translated by adding URL filters. Any page that matches a filter in this box will not be translated.', 'autoglot'). "<br /><br />" .__('Wildcards are allowed. Use relative paths without domain names. Examples:', 'autoglot')."<br /><ul><li>".
     1602/* translators: 1: <code>/blog/*</code>, 2: <code>/blog/</code>, 3: <code>/about-us/</code>, 4: <code>*\/contact/*</code>, 5: <code>/contact/</code>  */
     1603                                    sprintf(__('%1$s - Exclude all URLs starting with %2$s', 'autoglot') . "</li><li>" .
     1604                                            __('%3$s - Exclude this exact URL %3$s', 'autoglot'). "</li><li>" .
     1605                                            __('%4$s - Exclude all URLs containing %5$s', 'autoglot'), '<code>/blog/*</code>', '<code>/blog/...</code>', '<code>/about-us/</code>', '<code>*/contact/*</code>', '<code>.../contact/...</code>') . "</li></ul>"
     1606,
     1607                    'type' => 'textarea',
     1608                    'default' => "",
     1609                    'sanitize_callback' => array($this, 'sanitize_exclusion_urls'),
     1610                ),
     1611                array(
     1612                    'uid' => 'autoglot_translation_exclusion_archives',
     1613                    'label' => __('Choose archives to be excluded', 'autoglot'),
     1614                    'section' => 'section_adv_exclusion',
     1615                    'page' => 'autoglot_translation_advanced',
     1616                    'supplemental' => __('You can prevent specific page types from being translated. This will exclude pages such as search results and attachment pages, as well as archive pages like category archives, date archives, etc.', 'autoglot')
     1617,
     1618                    'type' => 'checkbox',
     1619                    'checkboxcolor' => 'red',
     1620                    'options' => $this->autoglot->options->get_archives(),
     1621                    'default' => array(),
     1622                    'sanitize_callback' => array($this, 'sanitize_exclusion_archives'),
     1623                ),
     1624                array(
     1625                    'uid' => 'autoglot_translation_exclusion_noindex',
     1626                    'label' => __('No-index excluded pages', 'autoglot'),
     1627                    'section' => 'section_adv_exclusion',
     1628                    'page' => 'autoglot_translation_advanced',
     1629                    'type' => 'radio',
     1630/* translators: element #ID */
     1631                    'supplemental' => sprintf(__('Modify %s tag and set it to noindex to prevent search engines from indexing the content of excluded pages.', 'autoglot'), "<code>&lt;meta name='robots' content='noindex'... /&gt;</code>"),
     1632                    'options' => array(
     1633                        1 => __('Set meta robots tag to noindex', 'autoglot'),
     1634                        0 => __('Do not modify meta robots tag', 'autoglot'),
     1635                    ),
     1636                    'default' => array(AUTOGLOT_DEFAULT_EXCLUSION_NOINDEX),
     1637                    'sanitize_callback' => array($this, 'sanitize_radio'),
     1638                ),
    15891639                array(
    15901640                    'uid' => 'autoglot_translation_add_lngcode',
     
    17991849            $value = $arguments['default'];
    18001850        }
     1851        $checkboxred = "";
    18011852        // Lets do some setup based ont he type of element we are trying to display.
    18021853        switch( $arguments['type'] ){
     
    18321883                }
    18331884                break;
     1885            case 'checkbox':
    18341886            case 'radio':
    1835             case 'checkbox':
    18361887                if( ! empty ( $arguments['options'] ) && is_array( $arguments['options'] ) ){
     1888                    if(isset($arguments['checkboxcolor'])) $checkboxred = " checkbox".$arguments['checkboxcolor'];
    18371889                    $options_markup = '';
    18381890                    $iterator = 0;
     
    18471899                        }
    18481900                        // Lets build out the checkbox
    1849                         $options_markup .= sprintf( '<label for="%1$s_%6$s" class="checkboxlabel"><input id="%1$s_%6$s" name="%1$s[]" type="%2$s" value="%3$s" %4$s class="checkboxinput" /> <span class="checkboxtext">%5$s</span></label><br/>', $arguments['uid'], $arguments['type'], $key, $is_checked, $label, $iterator )."\r\n";
     1901                        $options_markup .= sprintf( '<label for="%1$s_%6$s" class="checkboxlabel"><input id="%1$s_%6$s" name="%1$s[]" type="%2$s" value="%3$s" %4$s class="checkboxinput%7$s" /> <span class="checkboxtext">%5$s</span></label><br/>', $arguments['uid'], $arguments['type'], $key, $is_checked, $label, $iterator, $checkboxred)."\r\n";
    18501902                    }
    18511903                    printf( '<fieldset id="%s">%s</fieldset>', (/*count($arguments['options'])>10*/$arguments['type']=="checkbox"?"autoglot_tgs":""), wp_kses($options_markup, autoglot_consts::ADMIN_ALLOWED_TAGS) );
    1852                     if(count($arguments['options'])>10) {
     1904                    /*if(count($arguments['options'])>10) {
    18531905                        echo '<br /><span><a href="#" id="autoglot_checkon">' . esc_html__('Check all', 'autoglot') . '</a></span> | <span><a href="#" id="autoglot_checkoff">' . esc_html__('Uncheck all', 'autoglot') . '</a></span>';
    1854                     }
     1906                    }*/
    18551907                }
    18561908                break;
     
    19592011        $newinput = array();
    19602012        if(is_array($input) && count($input))foreach($input as $ln) {
    1961             if(in_array($ln, array_keys(autoglot_utils::get_all_language_names()))){
     2013            if(in_array($ln, array_keys(autoglot_utils::get_all_language_names()), true)){
    19622014                $newinput[] = $ln;
    19632015            }
     
    19652017        return $newinput;
    19662018    }
    1967 
     2019   
     2020    public function sanitize_exclusion_archives ($input){
     2021        $newinput = array();
     2022        if(is_array($input) && count($input))foreach($input as $ln) {
     2023            if(in_array($ln, array_keys($this->autoglot->options->get_archives()), true)){
     2024                $newinput[] = $ln;
     2025            }
     2026        }
     2027        return $newinput;
     2028    }
     2029
     2030    public function sanitize_exclusion_urls( $input ) {
     2031        $sanitized_paths = array();
     2032        $paths = explode("\r\n", trim( $input ));
     2033       
     2034        foreach($paths as $path){
     2035            $path = preg_replace( '/[^\p{L}\p{N}\/\-_\.\*]/u', '', $path );
     2036            $path = preg_replace( '/\/\/+/', '/', $path );
     2037            if(strlen($path))$sanitized_paths[] = $path;
     2038        }
     2039   
     2040        return implode("\r\n", $sanitized_paths);
     2041    }
    19682042
    19692043    /**
     
    21072181        delete_transient( 'text_replacement_settings_errors' );
    21082182        remove_action( 'admin_notices', 'text_replacement_admin_notices' );
    2109 }
     2183    }
    21102184    function text_replacement_custom_box_html($post){
    21112185        $alllangs = autoglot_utils::get_all_language_names(1);
     
    21182192        foreach($alllangs as $lng => $nm){
    21192193            if(in_array($lng,$this->autoglot->options->active_languages, true) && $lng!=$this->autoglot->options->default_language) echo "<tr><td><strong style=\"color:#007cba\">".esc_html($nm)."</strong></td><td><strong style=\"color:#007cba\">".esc_html($lng)."</strong></td><td>"; else echo "<tr><td>".esc_html($nm)."</td><td>".esc_html($lng)."</td><td>";
    2120             printf( '<textarea '.($lng==$this->autoglot->options->default_language?" disabled":"").' name="autoglot_text_replacement_content['.esc_attr($lng).']" id="autoglot_text_replacement_content_'.esc_attr($lng).'" rows="2" cols="50">%1$s</textarea>', esc_textarea($meta_value[$lng]) );
     2194            if($lng==$this->autoglot->options->default_language) echo '<div style="height:40px;background:#CCC;width:auto;"><input type="hidden" name="autoglot_text_replacement_content['.esc_attr($lng).']" id="autoglot_text_replacement_content_'.esc_attr($lng).'" value="'.esc_attr($meta_value[$lng]).'" /></div>';
     2195            else printf( '<textarea name="autoglot_text_replacement_content['.esc_attr($lng).']" id="autoglot_text_replacement_content_'.esc_attr($lng).'" rows="2" cols="50">%1$s</textarea>', esc_textarea($meta_value[$lng]) );
    21212196            echo "</td></tr>";
    21222197        }
  • autoglot/trunk/admin/css/autoglot_translation_admin.css

    r3455513 r3484878  
    6060    padding-right: 2em;
    6161}
     62#autoglot_tgs .checkboxred:checked ~ .checkboxtext {
     63    background: #c72138 !important;
     64}
    6265
    6366#autoglot_tgs .checkboxinput:checked ~ .checkboxtext:before {
     
    7174    color: #007cba;
    7275    font-weight:bold;
     76}
     77#autoglot_tgs .checkboxred:checked ~ .checkboxtext:after {
     78    content: '\2717';
     79    color: #c72138;
    7380}
    7481
     
    8289    cursor: default;
    8390}
    84 
     91#autoglot_tgs .checkboxred:disabled ~ .checkboxtext {
     92    border: 2px solid #c72138;
     93    color: #c72138;
     94}
    8595#autoglot_tgs .checkboxinput:disabled ~ .checkboxtext:after {
    8696    content: none;
  • autoglot/trunk/autoglot.php

    r3475813 r3484878  
    44Plugin URI: https://autoglot.com/download/
    55Description: Fully automatic SEO-friendly plugin for multilingual WordPress translation. Translate your website and boost your traffic in minutes! No coding, no subscription, no recurring payments, no hurdles!
    6 Version: 2.10.10
     6Version: 2.11.0
    77Text Domain: autoglot
    88Author: Autoglot WordPress Team
     
    102102        /** for a language menu block */
    103103        public $block_menu;
     104
     105        /** translation of the current page is excluded */
     106        public $translation_excluded = false;
    104107
    105108        function __construct() {
     
    572575        /**
    573576         * Main WP funciton.
     577         * Check if archive page is excluded from translation
    574578         */
    575579
    576580        function wp_main()
    577581        {
     582            if(count($this->options->exclusion_archives)){
     583                if( (is_category() && in_array("category", $this->options->exclusion_archives, true)) ||
     584                    (is_tag() && in_array("post_tag", $this->options->exclusion_archives, true)) ||
     585                    (is_search() && in_array("default_search", $this->options->exclusion_archives, true)) ||
     586                    (is_404() && in_array("default_404", $this->options->exclusion_archives, true)) ||
     587                    (is_attachment() && in_array("default_attachment", $this->options->exclusion_archives, true)) ||
     588                    (is_author() && in_array("default_author", $this->options->exclusion_archives, true)) ||
     589                    (is_date() && in_array("default_date", $this->options->exclusion_archives, true)) ) $this->translation_excluded = true;
     590                elseif(is_tax()) {
     591                    foreach($this->options->exclusion_archives as $ea){
     592                        if(is_tax($ea)) $this->translation_excluded = true;
     593                    }
     594                }
     595                   
     596                if($this->translation_excluded){
     597                    $this->options->translation_enable = 0;
     598                    add_action( 'admin_bar_menu', array($this, 'notranslation_admin_bar_menu'), 999 );
     599                }
     600            }
    578601
    579602        }
     
    581604        /**
    582605         * Start buffering after init
    583          * Register widgets
    584          * Add filters to 3rd party SEO plugins
    585606         */
    586607
     
    618639
    619640            if(strlen($home_url) && strpos($href, $home_url)!==false) $href = substr($href, strlen($home_url));
     641
    620642            $url = stripslashes(urldecode($href));
    621643            $params = ($pos = strpos($url, '?')) ? substr($url, $pos) : '';
     
    717739            if (strlen($langURL)) {
    718740                remove_filter( 'request', array($this, 'autoglot_request_filter'));
     741
     742                if(autoglot_utils::url_excluded($add_home.$this->get_original_url($saveuri, '', $langURL, 0), $this->options->exclusion_urls)) {//check if translated URL is excluded
     743                    $this->translation_excluded = true;
     744                    $this->options->translation_enable = 0;
     745                    add_action( 'admin_bar_menu', array($this, 'notranslation_admin_bar_menu'), 999 );
     746                }
     747                   
    719748                $_SERVER['REQUEST_URI'] = $add_home.$this->get_original_url($saveuri, '', $langURL);
     749
     750                if(autoglot_utils::url_excluded($_SERVER['REQUEST_URI'], $this->options->exclusion_urls)) {//check if original URL is excluded
     751                    $this->translation_excluded = true;
     752                    $this->options->translation_enable = 0;
     753                    add_action( 'admin_bar_menu', array($this, 'notranslation_admin_bar_menu'), 999 );
     754                }
     755
    720756                global $wp;
    721757                $savemr = $wp->matched_rule;//save, remove, then $wp->matched_rule - otherwise warnings on translated index pages
     
    728764            return $query_vars;
    729765        }
    730 
     766       
     767        function notranslation_admin_bar_menu( $wp_admin_bar ) {
     768
     769            $wp_admin_bar->add_node( array(
     770                'id'    => 'autoglot-translation-disabled',
     771                'title' => __('Translation disabled', 'autoglot') . ' <span class="ab-icon dashicons dashicons-translation" style="top:3px"></span>',
     772                'href'  => admin_url('admin.php?page=autoglot_translation_advanced'),
     773            ) );
     774        }
     775       
    731776        /**
    732777         * Process page after end of buffer
     
    734779
    735780        function process_page($buffer) {
     781
    736782            //file_put_contents(__DIR__."/debug.txt", $_SERVER['REQUEST_URI']."\r\n".$buffer."\r\n\r\n", FILE_APPEND);
    737783            $this->response_content_type = autoglot_utils::get_response_content_type();
  • autoglot/trunk/readme.txt

    r3475813 r3484878  
    55Tested up to: 6.9
    66Requires PHP: 7.0
    7 Stable tag: 2.10.10
     7Stable tag: 2.11.0
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    408408== Upgrade Notice ==
    409409
     410= 2.11.0 =
     411Added translation exclusion filters
     412
    410413= 2.10.10 =
    411414Improved HTML formatting
     
    465468== Changelog ==
    466469
     470= 2.11.0 (17/03/2026) =
     471** Autoglot Adds Translation Exclusion Filters!**
     472
     473* Added Exclusion Filters section to the Advanced Plugin Settings page
     474* Exclusion filters allow administrators to prevent specific pages from being translated
     475* Excluded pages display translated content only if a translation already exists; Autoglot will not generate new translations
     476* All links will still lead to the translated version of the site
     477* URL filters can exclude specific pages from translation using wildcard patterns
     478* Page type filters can exclude search results, attachment pages, and archive pages such as category or date archives
     479* Additionally, 'meta robots' tag can be set to 'noindex' to prevent search engines from indexing the content of excluded pages
     480* Minor optimization in the search function
     481* Minor bug fixes in the Text Replacement module
     482
    467483= 2.10.10 (05/03/2026) =
    468484* Added an option to format HTML and force adding closing slashes to self-closing tags such as "br" or "meta"
     485* Minor fixes
    469486
    470487= 2.10.9 (05/03/2026) =
  • autoglot/trunk/utils/autoglot_constants.php

    r3475813 r3484878  
    192192     * Default keys for URLs in inline JS+JSON objects
    193193     */
    194     const JSON_KEYS_URL = array('url', 'urlTemplate');
     194    const JSON_KEYS_URL = array('url', 'urlTemplate', '@id');
    195195       
    196196    const ADMIN_ALLOWED_TAGS = array(
     
    317317
    318318//Define for autoglot plugin version
    319 define('AUTOGLOT_PLUGIN_VER', '2.10.10');
     319define('AUTOGLOT_PLUGIN_VER', '2.11.0');
    320320
    321321//Define for autoglot plugin name
     
    434434//use advanced search
    435435define('AUTOGLOT_DEFAULT_ADVANCED_SEARCH', 1);//2.7.0
     436
     437//no-index excluded pages
     438define('AUTOGLOT_DEFAULT_EXCLUSION_NOINDEX', 0);//2.11.0
    436439
    437440/*********************** folders settings *********************/
  • autoglot/trunk/utils/autoglot_db.php

    r3469237 r3484878  
    486486            return $return;
    487487        } else {
    488             return false;
     488            return array();
    489489        }
    490490    }   
  • autoglot/trunk/utils/autoglot_dom.php

    r3475723 r3484878  
    546546            }
    547547            $node->setAttribute("content", $og_locale);
     548        }
     549       
     550        if($this->autoglot->translation_excluded && $this->autoglot->options->exclusion_noindex) {
     551            $robotstags = $xpath->query("//meta[@name=\"robots\"]");
     552            if ($robotstags->length){
     553                foreach ($robotstags as $node) {
     554                    $content = $node->getAttribute("content");
     555                    $parts = array_map('trim', explode(',', $content));
     556                    $lowerParts = array_map('strtolower', $parts);
     557   
     558                    if (in_array('index', $lowerParts)) {
     559                        foreach ($parts as $key => $value) {
     560                            if (strtolower($value) === 'index') $parts[$key] = 'noindex';
     561                        }
     562                    } elseif (!in_array('noindex', $lowerParts)) {
     563                        $parts[] = 'noindex';
     564                    }
     565   
     566                    $node->setAttribute("content", implode(', ', $parts));
     567                }
     568            } else {
     569                $head = $xpath->query("//head")->item(0);
     570                if ($head) {
     571                    $newRobots = $head->ownerDocument->createElement('meta');
     572                    $newRobots->setAttribute('name', 'robots');
     573                    $newRobots->setAttribute('content', 'noindex');
     574                    $head->appendChild($newRobots);
     575                }               
     576            }
    548577        }
    549578       
  • autoglot/trunk/utils/autoglot_options.php

    r3475723 r3484878  
    4949    public $editors_edit;
    5050    public $advanced_search;
     51    public $exclusion_urls;
     52    public $exclusion_archives;
     53    public $exclusion_noindex;
    5154
    5255    private $translate_delays;
     
    5558    private $language_name_options;
    5659    private $language_switcher_menu;
     60
     61    private $default_archives;
    5762
    5863    private function validate_checkbox($option, $default1 = 1, $max_value = 1){
     
    179184        $this->manual_strings = stripslashes($option);
    180185       
     186        $option = get_option('autoglot_translation_exclusion_urls');
     187        $vldt_eu = explode("\r\n", trim( stripslashes($option)));
     188        $this->exclusion_urls =  array();
     189        foreach($vldt_eu as $path){
     190            $path = preg_replace( '/[^\p{L}\p{N}\/\-_\.\*]/u', '', $path );
     191            $path = preg_replace( '/\/\/+/', '/', $path );
     192            if(strlen($path))$this->exclusion_urls[] = $path;
     193        }
     194
     195        $option = get_option('autoglot_translation_exclusion_archives', array());
     196        $this->exclusion_archives = array();
     197        foreach($option as $ln) {
     198            if(is_string($ln) && preg_match('/^[a-z0-9_]+$/i', $ln)){//can't check real values because they have not been generated yet
     199                $this->exclusion_archives[] = $ln;
     200            }
     201        }
     202
     203        $option = get_option('autoglot_translation_exclusion_noindex', array(AUTOGLOT_DEFAULT_EXCLUSION_NOINDEX));
     204        $this->exclusion_noindex = $this->validate_checkbox($option[0], AUTOGLOT_DEFAULT_EXCLUSION_NOINDEX);
     205
    181206        $option = get_option('autoglot_translation_add_lngcode');
    182207        if(is_array($option)) {
     
    255280            'nativeiso'     => __( 'Native name (2-letter ISO code)', 'autoglot' ),
    256281        );
     282       
     283        $this->default_archives = array(
     284            'default_author' => __('Author Archives', 'autoglot' ),
     285            'default_date' => __('Date Archives', 'autoglot' ),
     286            'default_search' => __('Search Results', 'autoglot' ),
     287            'default_attachment' => __('Attachment Pages', 'autoglot' ),
     288            'default_404' => __('404 Not Found Page', 'autoglot' ),
     289        );
     290
    257291    }
    258292
     
    276310        return $this->language_name_options;
    277311    }
     312
     313    public function get_archives(): array {
     314        $archives = array();
     315        $taxes = get_taxonomies(array( 'public' => true ), "object");
     316        foreach($taxes as $tx){
     317            if(is_object($tx) && isset($tx->name) && isset($tx->label))
     318            $archives[$tx->name] = $tx->label;
     319        }
     320        $archives = array_merge($this->default_archives, $archives);
     321
     322        return $archives;
     323    }
    278324}
    279325
  • autoglot/trunk/utils/autoglot_utils.php

    r3475813 r3484878  
    313313        $tagsList = implode('|', $selfClosingTags);
    314314   
    315         /**
    316          * Regex Breakdown:
     315        /*
    317316         * <($tagsList)  -> Match the opening bracket and the tag name
    318317         * ([^>]*?)      -> Capture any attributes (non-greedy)
     
    326325   
    327326        return $html;
     327    }
     328
     329    /**
     330     * Check if URL is in array of excluded filters with wildcards
     331     */
     332
     333    public static function url_excluded($url, array $filters) {
     334        foreach ($filters as $filter) {
     335
     336            $quotedFilter = preg_quote($filter, '#');
     337           
     338            $pattern = str_replace('\*', '.*', $quotedFilter);
     339
     340            if (preg_match('#^' . $pattern . '$#iu', $url)) {
     341                return true;//URL matches this filter and should be excluded
     342            }
     343        }
     344        return false;
    328345    }
    329346
     
    571588        return $array;
    572589    }
     590
    573591    /**
    574592     * Return capabilities for translation editors
     
    579597    }
    580598   
     599
    581600    /**
    582601     * Removes outer <p> tags, used in a few files
Note: See TracChangeset for help on using the changeset viewer.