web-dev-qa-db-ja.com

複数のパークドメインのルート相対リンク

同じserver/wpインストールを指す5つのドメインがあります。ドメイン名は重要であり、私の訪問者は私のサイトを閲覧するときに自分の優先ドメインに留まることができる必要があります。

すべてのリンクが訪問者によって指定されたドメイン/ホストを指すようにwp(または.htaccessまたは...)を設定する方法を教えてください。

今のところ、Dashboard/General/Site Addressをに設定した場合 site-A.comサイトを次のようにロードします。 site-B.comリンクはまだ指す site-A.com の代わりに site-B.com;たとえば、http://site-B.com/blog/this-is-my-home/をロードします。ロードされたページ内のリンクはまだ指す site-A.com の代わりに site-B.com

私の古いMTシステムでは、私はすべてのリンクをルート相対として定義することができたので、すべてのリンクは現在のドメインを指していました。これはWPで可能ですか?

乾杯、
グレゴリー

2
Gregory

私のテーマ(Chip BennettによるOenologyの子テーマ)とリンクを生成するwp-includeで関数呼び出しを追跡し、home_url()関数を見つけて、私のサイト用にこれらの関数を記述しました。

function gregory_make_relative($url='') {
    return preg_replace( '#^https?://[^/]+/#iu', '/', $url, 1 );
}
add_filter( 'home_url', 'gregory_make_relative', 11, 1 );

ドメインの後に/を含めるように意図的にgrep検索し、home_url('')を使用してBlogの指定されたドメインを返し、WordPress SEOを介して<head>でそのドメインに真の正規URLを指定できるようにしました次の機能を使用します(つまり、ページの読み込みに使用されるドメインに関係なく、正規リンクは同じになります。つまり、「コンテンツの重複」はありません)。

function gregory_wpseo_canonical_add_domain( $canonical ) {
    return home_url('').$canonical;
}
add_filter( 'wpseo_canonical', 'gregory_wpseo_canonical_add_domain', 10, 1 );

これまでのところ、それは本当にうまく機能しますが、フィードまたは私が最終的に実装するeコマースソリューションに悪影響を与えるかどうか疑問に思います。コメント、メモ、ヒント、警告は大歓迎です:-)

更新

単純なhome_url()(つまり、パスが指定されていない)がシステム全体で使用されるため、grep-searchの末尾の/は使用できません。私はそれを削除し、正規のURLでドメインを指定する別の方法を見つけなければなりませんでした。そのため、wp-includesを使用したもう少しの調査により、関数は次のようになります。

function gregory_make_relative($url='') {
    return preg_replace( '#^https?://[^/]+#iu', '', $url, 1 );
}
add_filter( 'home_url', 'gregory_make_relative', 11, 1 );

function gregory_wpseo_canonical_add_domain( $canonical ) {
    // get_option() is defined in wp-includes/functions.php and is used by get_home_url()
    return get_option('home').$canonical;
}
add_filter( 'wpseo_canonical', 'gregory_wpseo_canonical_add_domain', 10, 1 );


更新2

最初に登場したよりも難しい;-)私のコードは次のようになりました。フィードが影響を受けます。 リンクを生成する関数チェーンのどこかで、フィードは_SERVER ['HTTP_Host']を使用しているようです。 そこでオプションを調べなければなりません。

/* FILTERS TO PRODUCE ROOT-RELATIVE URLs */
// define WP_SITEURL because the formula in wp-includes/functions::wp_guess_url() makes a
// false assumption and appends $_SERVER['REQUEST_URI'] to the base_url.
define('WP_SITEURL', 'http://my.domain.hk/', true );

// strip the domain
function gregory_make_relative( $url='' ) {
    return preg_replace( '#^https?://[^/]+#iu', '', $url, 1 );
}
add_filter( 'site_url', 'gregory_make_relative', 11, 1 );
add_filter( 'home_url', 'gregory_make_relative', 11, 1 );
add_filter( 'template_directory_uri', 'gregory_make_relative', 11, 1 );
add_filter( 'stylesheet_directory_uri', 'gregory_make_relative', 11, 1 );
add_filter( 'script_loader_src', 'gregory_make_relative', 11, 1 );

function gregory_make_stylehref_relative( $tag='' ) {
    // $wp_styles->do_item() passes this along to the filter:
    // "<link rel='$rel' id='$handle-rtl-css' $title href='$rtl_href' type='text/css' media='$media' />\n"
    $matches = array();
    if( !preg_match( '#^(.+ +href=\')(.+)(\' +type=.+)$#iu', $tag, &$matches ))
        return $tag;
    $matches[2] = gregory_make_relative($matches[2]);
    return $matches[1].$matches[2].$matches[3];
}
add_filter( 'style_loader_tag', 'gregory_make_stylehref_relative', 11, 1 );

function gregory_wpseo_canonical_add_domain( $canonical='' ) {
    // get_option is defined in wp-includes/functions.php and is used by get_home_url() to get the home url.
    return get_option('home').$canonical;
}
add_filter( 'wpseo_canonical', 'gregory_wpseo_canonical_add_domain', 10, 1 );


更新3-WPSEO

wPSEOには、プレースホルダーを使用するオプションを含む、RSS投稿の前後にテキスト/リンクを追加するオプションがあります。それらのプレースホルダーの1つは%%BLOGLINK%%です。残念ながら、ルート相対フィルターを配置すると、%% BLOGLINK %%は空の文字列を生成しましたが、これはフィードには役立ちませんでした。このコードはその問題を修正します(他の選択肢は単にWPSEOのRSS設定でリンクをハードコードすることでしたが、おそらくより賢いことです:-)

// a change for WPSEO's %%BLOGLINK%% code.
// I changed get_bloginfo() to get_bloginfo_rss() in wpseo/frontend/class-frontend.php to allow this.
// without these changes, %%BLOGLINK%% is printed into the rss feeds as an empty string.
function gregory_set_domain_in_rss_urls( $info, $show ) {
    // copied from wp-includes/general-template.php::get_bloginfo()
    $url = true;
    if (strpos($show, 'url') === false &&
        strpos($show, 'directory') === false &&
        strpos($show, 'home') === false)
        $url = false;

    return ( !$url || !empty($info) ? $info : '/' );
}
add_filter( 'get_bloginfo_rss', 'gregory_set_domain_in_rss_urls', 11, 2 );

(その後、RSSアフターポストメッセージをハードコーディングすることに決めたため、上記のフィルターは私のテーマで無効になっています。)


更新4-preg_replace()はpreg_match()になります

Update 2に示されているgregory_make_stylehref_relative()関数を更新して、preg_match()の代わりにpreg_replace()を使用しました。これは古いコードです:

    $href = preg_replace( '#^(.+ +href=\')(.+)(\' +type=.+)$#iu', '$2', $tag );
    $href = gregory_make_relative($href);
    return preg_replace( '#^(.+ +href=\')(.+)(\' +type=.+)$#iu', '$1'.$href.'$3', $tag );


更新5-get_avatar()

別のフィルター、今回はget_avatar()のため、スキーマと現在のドメインがwpのblank.gifへのパスに含まれます。これらがないと、gifが見つかりロードされません。スキーマがなければ、Gravatarは代わりに独自の企業アバターをロードします。

function gregory_avatar_add_domain( $avatar ) {
    // look for urlencode( includes_url('images/blank.gif')) in the $avatar string.
    // if found, encode the schema and domain, insert it into the $avatar string.
    $gif = includes_url('images/blank.gif'); // from get_avatar()
    if( preg_match( '|^https?://|i', $gif ))
        // the url already includes the schema (and domain).
        return $avatar;
    $gif = urlencode($gif);
    $schema = is_ssl() ? 'https://' : 'http://'; // from wp_guess_url()
    $domain = urlencode( $schema . $_SERVER['HTTP_Host'] );
    return str_replace( $gif, $domain.$gif, $avatar );
}
add_filter( 'get_avatar', 'gregory_avatar_add_domain', 11, 1 );


更新6-redirect_canonical()

フィルタは、クエリ文字列を含む受信URLで問題を引き起こしていました。 URLのscheme://domainは、://domainに切り刻まれます。問題を特定するのに数時間かかりましたが、wp-includes/canonical.php :: redirect_canonical()にあり、フィルターフックにより問題を修正することができました。ここにフィルターがあります:

function gregory_redirect_canonical_addScheme( $redirect_url ) {
    // redirect_canonical() requires (but doesn't need) a fully qualified url.
    // get_permalink() in the second iteration of redirect_canonical()
    // (redirect_canonical() calls itself) usually switches to the domain specified in the
    // WP Settings. but if we do the same, redirect_canonical() doesn't recognise the
    // permalink as a redirect, and WP doesn't update the url in the User Agent's Address bar.
    if( preg_match( '|^https?://|i', $redirect_url ))
        // fully qualified url. leave it alone.
        return $redirect_url;
    if( substr( $redirect_url, 0, 3 ) == '://' )
        // no scheme specified in $redirect during the
        // second pass through redirect_canonical().
        return (is_ssl() ? 'https' : 'http') . $redirect_url;
    if( substr( $redirect_url, 0, 1 ) == '/' )
        // root-relative url.
        return (is_ssl() ? 'https://' : 'http://').$_SERVER['HTTP_Host'].$redirect_url;
    // relative url. not root-relative.
    return (is_ssl() ? 'https://' : 'http://').$_SERVER['HTTP_Host'].'/'.$redirect_url;
}
add_filter( 'redirect_canonical', 'gregory_redirect_canonical_addScheme', 11, 1 );


質問がまだ回答済みとマークされていないことに注意してください。これらのフィルターが今後どのような結果をもたらすかわからないためです。より多くの時間とテストが必要です。

乾杯、
グレゴリー
(WordPress 3.3.2)

2
Gregory

絶対URLに戻す

ルート相対URLの実装はかなり可能ですが、WPは絶対URLを使用するように記述されており、絶対URLが必要なため複雑です。私が欲しいのは、自分のサイトにアクセスしている人が、指定したドメインと同じドメインを使っているすべてのリンクを見ることができることだけであることに気付きました。これはルート相対URLの使用を強制するものではありません。そのため、関連するすべてのURLのドメインを訪問者が指定したドメインに置き換えるようにコードを書き換えました。 完全なコードはるかに単純です

// set the url's domain to that of the current Host, IGNORING any specified subdomains.
// (other WordPress users may need to retain the subdomains)
function gregory_use_Host_domain( $url='' ) {

    $myDomains = '(?:domain1|domain2|domain3|xn--domain4|xn--domain5)';
    $matches = array();

    // get the current Host domain. ignore/remove any subdomain.
    if( 1 != preg_match( '!.*('.$myDomains.'\.hk)!iu', $_SERVER['HTTP_Host'], &$matches )) // preg_match returns 1 if the pattern was found.
        // the current Host is not one of the above specified domains! weird. this will probably never happen, but just in case...
        return $url;
    $thisDomain = ( is_ssl() ? 'https://' : 'http://' ).$matches[1];

    if( 1 == preg_match( '!^(?:https?://[^/]*'.$myDomains.'\.hk)(/.*)?$!iu', $url, &$matches ))
        // fully qualified url.
        return $thisDomain.$matches[1];
    if( substr( $url, 0, 1 ) == '/' )
        // root-relative url.
        return $thisDomain.$url;
    // relative url but not root-relative.
    return $thisDomain.'/'.$url;

}
add_filter( 'site_url', 'gregory_use_Host_domain', 11, 1 );
add_filter( 'home_url', 'gregory_use_Host_domain', 11, 1 );

/*
 * CONTENT_URL()
 * this function directly affects the template_ and stylesheet_ directory uri results,
 * but they don't matter as far as the visitor is concerned. they're not going to directly
 * access those particular url's.
 *
 * SPAM-FREE-WORDPRESS PLUGIN
 * the Spam-Free-Wordpress plugin uses plugin_dir_url() and plugin_dir_path() to get the paths to its resources,
 * but we're not going to worry about specifying the domain for these items.
 * wp's plugin_dir_url() uses wp's plugins_url()
 * wp's plugin_dir_path() uses php's dirname()
 */


// a filter to specify the 'domain1.hk' domain for WPSEO's canonical links.
// one specific domain for all content canonical links. no 'duplicate' content.
function gregory_wpseo_specify_canonical_domain( $canonical='' ) {

    $matches = array();
    if( 1 != preg_match( '!^(?:https?://[^/]+)(/.*)?$!iu', $canonical, &$matches ))
        return $canonical;
    // get_option is defined in wp-includes/functions.php and is used by get_home_url() to get the home url.
    return get_option('home').$matches[1];
}
add_filter( 'wpseo_canonical', 'gregory_wpseo_specify_canonical_domain', 10, 1 );

乾杯、
グレゴリー
(ワードプレス3.4.2)

0
Gregory