将URL参数添加到使用特定主题的所有内部链接

时间:2016-05-23 作者:Lens

我被一些修改卡住了,也许有人可以给我一些帮助。

What am I doing

我使用多主题插件切换WordPress项目的主题。要在主题之间切换,将添加URL参数www.mydomain/?parameter=XYZ. 到目前为止,一切都很顺利。

Where is the issue

问题是,当我单击页面内的内部链接时,我被发送回基本主题,因为网站内的链接和URL没有附加URL参数。

请注意,我知道该插件有一个粘性函数,可以将参数添加到大多数URL,但它不适用于所有URL,尤其是那些加载了AJAX的URL。此外,我仍然需要能够访问通过正常的URL没有参数的基本主题。

What I am trying to do

functions.php 对于特定主题,我尝试添加一个函数,将所需参数添加到WordPress生成的所有URL中。

基于this info:
我至少可以回显正确的URL

//Add partner parameter
echo add_query_arg( \'partner\', \'XYZ\', get_permalink());
不幸的是,我不知道如何将其转换为一个函数,使加载网页中的所有URL都附加参数?有人有主意吗?

What I already checked

I am Looking to append URL Parameter to all URLs

由于这是一个重定向,而不是对URL的重写,因此如果没有参数,我将无法访问正常的URL。

3 个回复
SO网友:majick

您可以设置$_GET 全球内部。通过保存作为用户元和/或cookie传递的参数并稍后检索它。这可能需要放在你的/wp-content/mu-plugins/ 要使文件夹正常工作(以便尽早加载):

<?php 

    $parameter = \'theme\'; // default for theme test drive
    $savemethod = \'both\'; // \'usermeta\' (only), \'cookie\' (only) or \'both\'
    $expires = 7*24*60*60; // cookie length (a week in seconds)

    if (!function_exists(\'is_user_logged_in\')) {require(ABSPATH.WPINC.\'/pluggable.php\');}
    if (is_user_logged_in()) {global $current_user; wp_get_current_user();}

    if (isset($_GET[$parameter])) {
        // sanitize querystring input (like a theme slug)
        $originalvalue = $_GET[$parameter];
        $value = sanitize_title($_GET[$originalvalue]);
        if (!$value) {$value = \'\';}

        // save parameter as usermeta
        if ( ($savemethod != \'cookie\') && (is_user_logged_in()) ) {
            if ($value == \'\') {delete_user_meta($current_user->ID,$parameter);}
            else {update_user_meta($current_user->ID,$parameter,$value);}
        } 
        // save parameter value as cookie
        if ($savemethod != \'usermeta\') {
            if ($value == \'\') {setCookie($parameter,\'\',-300);}
            else {setCookie($parameter,$value,time()+$expires);}
        }
    }
    elseif ( ($savemethod != \'cookie\') && (is_user_logged_in()) ) {
        // maybe set parameter from usermeta
        $uservalue = get_user_meta($current_user->ID,$parameter,true);
        if ($uservalue != \'\') {$_GET[$parameter] = $uservalue;}
    }
    elseif ($savemethod != \'usermeta\') {
        // maybe set parameter from cookie
        if ( (isset($_COOKIE[$parameter])) && ($_COOKIE[$parameter] != \'\') ) {
            $_GET[$parameter] = $_COOKIE[$parameter];
        }
     }

    // parameter override debugging
    if ( (isset($_GET[$parameter.\'debug\'])) && ($_GET[$parameter.\'debug\'] == \'1\') ) {
        $debugfile = get_stylesheet_directory().\'/\'.$parameter.\'-debug.txt\';
        $fh = fopen($debugfile,\'a\'); 
        $debugline = $_SERVER[\'REQUEST_URI\'].\'::original:\'.$originalvalue;
        $debugline .= \'::cookie:\'.$_COOKIE[$parameter\'].\'::usermeta.\'.$uservalue;
        $debugline .= \'::current:\'.$_GET[$parameter].PHP_EOL;
        fwrite ($debugfile,$debugline); fclose($fh);
    }

?>
用法:这可以用于在每个用户级别上持久化主题试驾,目前它仅在用户角色级别和/或通过非持久化查询字符串工作。然而,主题试驾不允许站点区域选择-无论用户在任何地方或任何地方都可以切换整个主题。

SO网友:majick

好吧,这是一个非常长的答案,但幸运的是,我正在用我的主题测试主题试驾插件,我想我还可以通过修复管理问题使其更好地与多个主题兼容。。。

这是我提出的处理这两者的代码。再一次,把它放在你的/wp-content/mu-plugins/ 文件夹(虽然它也可以作为插件使用。)我把它放在我的主题中是为了支持子主题切换,但它需要更早加载才能支持父主题切换。

稍后我将添加一些其他注释,因为现在值得一提的是,您想要not 使用多个主题的“粘滞”选项,因为这会导致冲突,因为如果在不同的窗口中打开同一站点上的两个主题,持久cookie将覆盖匹配的管理调用,这正是我编写此解决方案的原因,以克服该问题。

基本上,它让多个主题像往常一样确定使用哪个样式表/模板,并在加载时将具有不同主题的URL列表存储为默认值,然后使用admin-AJAX请求的引用字符串(支持admin-AJAX.php和admin-post.php)匹配这些URL

至于主题试驾,我发现如果启用了持久主题驱动,它已经在admin中加载了,很好。但是对于querystring试驾,我使用了一种完全不同的方法来匹配cookie和瞬态。

无论如何,这已经足够了,请阅读代码注释以了解更多信息(如果你敢的话)否则,我已经对它进行了相当彻底的测试,所以您可以试一试…:-)

add_action(\'init\',\'muscle_theme_switch_admin_fix\');

if (!function_exists(\'muscle_theme_switch_admin_fix\')) {
 function muscle_theme_switch_admin_fix() {

    $multiplethemes = false; $themetestdrive = false; $debug = false;
    $expires = 24*60*60; // transient time for temporary theme test drive (querystring)

    // maybe reset cookie and URL data by user request
    if ( (isset($_GET[\'resetthemes\'])) && ($_GET[\'resetthemes\'] == \'1\') ) {
        if ($debug) {echo "<!-- THEME SWITCH DATA RESET -->";}
        if ($themetestdrive) {setCookie(\'theme_test_drive\',\'\',-300);}
        delete_option(\'theme_switch_request_urls\'); return;
    }

    // maybe set debug switch
    if ( (isset($_GET[\'debug\'])) && ($_GET[\'debug\'] == \'1\') ) {$debug = true;}
    elseif (defined(\'THEMEDEBUG\')) {$debug = THEMEDEBUG;}

    // check for a valid active plugin
    $activeplugins = maybe_unserialize(get_option(\'active_plugins\'));
    if (!is_array($activeplugins)) {return;}
    if (in_array(\'jonradio-multiple-themes/jonradio-multiple-themes.php\',$activeplugins)) {$multiplethemes = true;}
    if (in_array(\'theme-test-drive/themedrive.php\',$activeplugins)) {$themetestdrive = true;}
    if ( (!$multiplethemes) && (!$themetestdrive) ) {return;} // nothing to do

    // theme test drive by default only filters via get_stylesheet and get_template
    // improve theme test drive to use options filters like multiple themes instead
    if ($themetestdrive) {
        remove_filter(\'template\', \'themedrive_get_template\'); remove_filter(\'stylesheet\', \'themedrive_get_stylesheet\');
        add_filter(\'pre_option_stylesheet\', \'themedrive_get_stylesheet\'); add_filter(\'pre_option_template\', \'themedrive_get_template\');
    }

    // maybe load stored alternative theme for AJAX/admin calls
    if (is_admin()) {

        // get pagenow to check for admin-post.php as well
        global $pagenow;

        if ( ( (defined(\'DOING_AJAX\')) && (DOING_AJAX) ) || ($pagenow == \'admin-post.php\') ) {

            // set the referer path for URL matching
            $referer = parse_url($_SERVER[\'HTTP_REFERER\'],PHP_URL_PATH);

            // set some globals for the AJAX theme options
            global $ajax_stylesheet, $ajax_template;

            // check for temporary Theme Test Drive cookie data
            if ( ($themetestdrive) && (isset($_COOKIE[\'theme_test_drive\'])) && ($_COOKIE[\'theme_test_drive\'] != \'\') ) {
                $i = 0; $cookiedata = explode(\',\',$_COOKIE[\'theme_test_drive\']);
                // attempt to match referer data with stored transient request
                foreach ($cookiedata as $transientkey) {
                    $transientdata = get_transient($transientkey);
                    if ($transientdata) {
                        $data = explode(\':\',$transientdata);
                        if ($data[0] == $referer) {
                            $ajax_stylesheet = $data[1]; $ajax_template = $data[2];
                            $transientdebug = $transientdata; $matchedurlpath = true;
                        }
                    }
                    $i++;
                }
            }
            elseif ($multiplethemes) {
                // check the request URL list to handle all other cases
                $requesturls = get_option(\'theme_switch_request_urls\');
                if (!is_array($requesturls)) {return;}

                if ( (is_array($requesturls)) && (array_key_exists($referer,$requesturls)) ) {
                    $matchedurlpath = true;
                    $ajax_stylesheet = $requesturls[$referer][\'stylesheet\'];
                    $ajax_template = $requesturls[$referer][\'template\'];
                }
            }

            if ($matchedurlpath) {
                // add new theme option filters for admin AJAX (and admin post)
                // so any admin actions defined by the theme are finally loaded!
                add_filter(\'pre_option_stylesheet\',\'admin_ajax_stylesheet\');
                add_filter(\'pre_option_template\',\'admin_ajax_template\');

                function admin_ajax_stylesheet() {global $ajax_stylesheet; return $ajax_stylesheet;}
                function admin_ajax_template() {global $ajax_template; return $ajax_template;}
            }

            // maybe output debug info for AJAX/admin test frame
            if ($debug) {
                echo "<!-- COOKIE DATA: ".$_COOKIE[\'theme_test_drive\']." -->";
                echo "<!-- TRANSIENT DATA: ".$transientdebug." -->";
                echo "<!-- REFERER: ".$referer." -->";
                echo "<!-- STORED URLS: "; print_r($requesturls); echo " -->";
                if ($matchedurlpath) {echo "<!-- URL MATCH FOUND -->";} else {echo "<!-- NO URL MATCH FOUND -->";}
                echo "<!-- AJAX Stylesheet: ".get_option(\'stylesheet\')." -->";
                echo "<!-- AJAX Template: ".get_option(\'template\')." -->";
            }

            return; // we are done so bug out here
        }
    }

    // store public request URLs where an alternate theme is active
    // (multiple themes does not load in admin, but theme test drive does)
    if ( ($themetestdrive) || ( (!is_admin()) && ($multiplethemes) ) ) {

        // get current theme (possibly overriden) setting
        $themestylesheet = get_option(\'stylesheet\'); $themetemplate = get_option(\'template\');

        // remove filters, get default theme setting, re-add filters
        if ($multiplethemes) {
            remove_filter(\'pre_option_stylesheet\', \'jr_mt_stylesheet\'); remove_filter(\'pre_option_template\', \'jr_mt_template\');
            $stylesheet = get_option(\'stylesheet\'); $template = get_option(\'template\');
            add_filter(\'pre_option_stylesheet\', \'jr_mt_stylesheet\'); add_filter(\'pre_option_template\', \'jr_mt_template\');
        }
        if ($themetestdrive) {
            // note: default theme test drive filters are changed earlier on
            remove_filter(\'pre_option_stylesheet\', \'themedrive_get_stylesheet\'); remove_filter(\'pre_option_template\', \'themedrive_get_template\');
            $stylesheet = get_stylesheet(); $template = get_template();
            add_filter(\'pre_option_stylesheet\', \'themedrive_get_stylesheet\'); add_filter(\'pre_option_template\', \'themedrive_get_template\');
        }

        // set/get request URL values (URL path only)
        $requesturl = parse_url($_SERVER[\'REQUEST_URI\'],PHP_URL_PATH);
        $requesturls = get_option(\'theme_switch_request_urls\');

        // check for a temporary Theme Test Drive (querystring)
        if ( ($themetestdrive) && (isset($_REQUEST[\'theme\'])) && ($_REQUEST[\'theme\'] != \'\') ) {
             // add a transient style user page cookie for matching later
             $cookiedata = array();
             if ( (isset($_COOKIE[\'theme_test_drive\'])) && ($_COOKIE[\'theme_test_drive\'] != \'\') ) {
                $existingmatch = false;
                $i = 0; $cookiedata = explode(\',\',$_COOKIE[\'theme_test_drive\']);
                // remove transient IDs for expired transients
                foreach ($cookiedata as $transientkey) {
                    $transientdata = get_transient($transientkey);
                    if ($transientdata) {
                        $data = explode(\':\',$transientdata);
                        if ($data[0] == $requesturl) {
                            // update the existing transient data
                            $transientdata = $transientdebug = $requesturl.\':\'.$themestylesheet.\':\'.$themetemplate;
                            set_transient($transientkey,$transientdata,$expires);
                            $existingmatch = true; // no duplicates
                        }
                    } else {unset($cookiedata[$i]);}
                    $i++;
                }
            }
            // set the matching transient and cookie data
            if (!$existingmatch) {
                 $transientkey = \'theme_test_drive_session_\'.uniqid();
                 $transientdata = $transientdebug = $requesturl.\':\'.$themestylesheet.\':\'.$themetemplate;
                 set_transient($transientkey, $transientdata, $expires);
                 $cookiedata[] = $transientkey; $cookiedatastring = implode(\',\',$cookiedata);
                 setCookie(\'theme_test_drive\', $cookiedatastring, time()+$expires);
            }
            // maybe output debug info
            if ($debug) {
                echo "<!-- COOKIE DATA: "; print_r($cookiedata); echo " -->";
                echo "<!-- TRANSIENT DATA: ".$transientdebug." -->";
            }
        }
        elseif ($multiplesthemes) {
            // save/remove the requested URL path in the list
            if ( ($stylesheet == $themestylesheet) && ($template == $themetemplate) ) {
                // maybe remove this request from the stored URL list
                if ( (is_array($requesturls)) && (array_key_exists($requesturl,$requesturls)) ) {
                    unset($requesturls[$requesturl]);
                    if (count($requesturls) === 0) {delete_option(\'theme_switch_request_urls\');}
                    else {update_option(\'theme_switch_request_urls\',$requesturls);}
                }
            }
            else {
                // add this request URL to the stored list
                $requesturls[$requesturl][\'stylesheet\'] = $themestylesheet;
                $requesturls[$requesturl][\'template\'] = $themetemplate;
                update_option(\'theme_switch_request_urls\',$requesturls);
            }
            // maybe output debug info
            if ( (!is_admin()) && ($debug) ) {
                echo "<!-- REQUEST URL: ".$requesturl." -->";
                echo "<!-- STORED URLS: "; print_r($requesturls); echo " -->";
            }
        }

        // maybe output hidden ajax debugging frames
        if ( (!is_admin()) && ($debug) ) {
            echo "<iframe src=\'".admin_url(\'admin-ajax.php\')."?debug=1\' style=\'display:none;\'></iframe>";
            echo "<iframe src=\'".admin_url(\'admin-post.php\')."?debug=1\' style=\'display:none;\'></iframe>";
        }
    }
 }
}

SO网友:majick

对于您的特定用例(据我现在所知),如果访问源不同,那么您只想使用粘性查询,从而在用户级别而不是站点级别上运行(例如,所有帖子和/或页面选项)。。。

由于多个主题实际上可以通过cookie从粘滞查询“按原样”在管理中运行(默认情况下不会这样做,因为这会与它的站点范围选项冲突)。。。您可以通过包括select-theme.php...

但是,由于最好不要让它们影响使用默认主题的主页上的任何AJAX调用,因此您可以手动添加这些路径的列表以过滤掉它们(通过添加到$defaultthemepaths) 这要容易得多,但不会自动与多个主题的站点范围选项相匹配,您需要在此代码中手动添加默认主题URL。。。

add_action(\'plugins_loaded\',\'switched_theme_admin_fix\');
function switched_theme_admin_fix() {

    if (!is_admin()) {return;} // switch-themes.php already loads for non-admin

    // default theme URL paths (add to this list?)
    $defaultthemepaths = array(\'\',\'/\'); // \'home\' paths

    // get pagenow to check for admin-post.php as well
    global $pagenow;

    if ( ( (defined(\'DOING_AJAX\')) && (DOING_AJAX) ) || ($pagenow == \'admin-post.php\') ) {

        // set the referer path for URL matching
        $referer = parse_url($_SERVER[\'HTTP_REFERER\'],PHP_URL_PATH);

        // do not switch themes if called from a default theme URL path
        if (!in_array($referer,$defaultthemepaths)) {

            // full path to select-theme.php
            $selecttheme = WP_PLUGIN_DIR.\'/jonradio-multiple-themes\';
            $selecttheme .= \'/includes/select-theme.php\';

            // just in case multiple themes does update to load for admin
            $included = get_included_files();
            if (!in_array($selecttheme,$included)) {
                // adds the multiple themes stylesheet filters
                if (file_exists($selecttheme) {include($selecttheme);}
            }                  
         }
     }
 }