web-dev-qa-db-ja.com

複数のURLに同じコンテンツを表示する方法

クライアントは現在、それぞれわずかに異なるテーマ(同じレイアウト、異なる配色)を持つ3つの異なるサブサイト(単一のWordPressインストールを実行する)でセットアップされたWebサイトを持っています。

私は現在それを設定しているので、各サブサイトはページで、そのすべてのページは子としてです。 header.phpはどのページが親であるかをチェックし、適切なスタイルを含みます。

問題は、サイト全体で同一のページにあります。クライアントは、各サブサイトから別々のページとしてアクセスできるようにしたいと考えています。

例えば、aboutページは、/ site1/aboutおよび/ site2/aboutからアクセス可能であり、それを要求したサイトのテーマを使用する必要がありますが、両方に同じコンテンツを表示します。

子ページを作成し、rel = "canonical"を設定して元のページを参照することもできますが、メンテナンスの観点からは、各サブサイトでコンテンツを取得する単一ページが望ましいでしょう。

それでは、質問に対して、1つのソースからそれらのコンテンツを取得するための複数のURL /ページを取得する方法を教えてください。

編集:これは望ましい構造の例です:

  • www.example.com - 3つの主要サービスへのリンク、および一般情報を表示します。
  • www.example.com/about - www.example.comと一致するようにスタイル設定された、クライアントに関する情報を表示します。
  • www.example.com/service1 - 特定のサービスに関連したナビゲーションを、一般的なリンク(約、連絡先)と一緒に独自の色でスタイル設定して表示します。
  • www.example.com/service1/about - /service1のナビゲーションとスタイルシートを表示しますが、www.example.com/aboutのコンテンツを使用して(およびwww.example.com/aboutへの正規リンク参照を使用して) )

その後、これが/ service2と/ service3に対して繰り返されます。

5
Ross Bearman

私はまだ正確な要件に苦労していますが、正しく理解できれば、以下で提供するコードを使用して、次のことを行うことで目標を達成できると思います。

  1. サービスごとにページを作成します(既に完了しているようです):/service1//service2/など。

  2. URLが/base-service/;の "base"サービスページを作成します。心配しないで、誰もウェブサイトの外でこれを見ないでしょう。

  3. /base-service/を親(または祖父母)ページとして割り当て、すべての "virtual shared"各サービスで複製する子ページ。

  4. 必要なサービス固有のページを作成し、適切なページに割り当てます(つまり、「サービス2」など)

  5. page-service.phpというサービスの テーマのページテンプレート を作成し、各サービスページがそのページテンプレートを使用していることを確認しますどのページがサービスであるかを識別できます)

だから、私はYoursite_SharedChildPagesと呼んだクラスのコードをあなたのテーマのfunctions.phpファイル、またはあなたのサイトのために書いているかもしれないプラグインの.phpファイルに保存することができます:

if (!class_exists('Yoursite_SharedChildPages')) {
  class Yoursite_SharedChildPages {
    // If wanted we could enhance to allow these values to be defined in an 'init' hook
    static $PAGE_TEMPLATE = 'page-service.php';
    static $ABSTRACT_ROOT = 'base-service';
    static function on_load() {
      // Hook 'request' to route the request correctly
      add_filter('request',array(__CLASS__,'request'));
      // Hook 'page_link' to compose URLs correctly
      add_filter('page_link',array(__CLASS__,'page_link'));
    }
    static function request($query_vars) {
      if (!empty($query_vars['pagename'])) {
        // If the page URL rewrite matched meaning WordPress thinks it's a Page
        // Split the URL path by path segments (i.e. by slashes)
        $pagename = explode('/',$query_vars['pagename']);
        if ($pagename[0] == self::$ABSTRACT_ROOT) {
          // If the first path segment is the abstract root we care about
          if (count($pagename)==1) {
          // Don't allow anyone to visit this abstract root page
            $pagename = array('#'); // An invalid page name, so it will 404
          } else {
            // If it is a child page in which case redirect to the first service
            // This is important so the user can view the page after they edit it
            $pages = self::get_page_ids_by_template(self::$PAGE_TEMPLATE);
            if (isset($pages[0]) && $page = get_post($pages[0])) {
              // Assuming we have at least one page with the page template
              $pagename[0] = $page->post_name;
              // then redirect to it the first service found.
              wp_safe_redirect('/'.implode('/',$pagename).'/');
              exit;
            }
          }
        } else if (count($pagename)>1) {
          // If there are child pages
          if (get_page_by_path($query_vars['pagename'])) {
            // If it is an actual child page then just let it pass thru
          } else {
              // If a virtual child page then see if parent has the template
            $parent = get_page_by_path($pagename[0]);
            $pages = self::get_page_ids_by_template(self::$PAGE_TEMPLATE);
            if (in_array($parent->ID,$pages)) {
              // If virtual child of a service page, change parent to the abstract root
              $pagename[0] = self::$ABSTRACT_ROOT;
              $query_vars['pagename'] = implode('/',$pagename);
              // The URL doesn't match a virtual page, will appropriately get a 404
            }
          }
        } else {
          $pagename = false;
        }
      }
      if (is_array($pagename))
        $query_vars['pagename'] = implode('/',$pagename);
      return $query_vars;
    }
    static function get_page_ids_by_template($template) {
      // This can be performance optimized but I wouldn't worry about it 
      // until there is a performance issue
      global $wpdb;
      $sql = "SELECT post_id FROM {$wpdb->postmeta} " . 
             "WHERE meta_key='_wp_page_template' AND meta_value='%s'";
      return $wpdb->get_col($wpdb->prepare($sql,$template));
    }
    static function page_link($link) {
      $parts = explode('/',$link);
      if ($parts[3]==self::$ABSTRACT_ROOT) {
        // This is really only useful for links in the admin.
        if (!is_admin()) {
          global $wp_query;
          if (!empty($wp_query->query_vars['pagename'])) {
            $pagename = explode('/',$wp_query->query_vars['pagename']);
          }
        } else {
          // If we get a URL that uses the abstract root, assign it the first service.
          $pages = self::get_page_ids_by_template(self::$PAGE_TEMPLATE);
          if (isset($pages[0]) && $page = get_post($pages[0])) {
            // Assuming we have at least one page with the page template
            $parts[3] = $page->post_name;
            // then redirect to it the first service found.
            $link = implode('/',$parts);
          } else {
            $link = preg_replace('#^(https?://[^/]+)(/.*)$#','$1',$link);
          }
        }
      }
      return $link;
    }
  }
  Yoursite_SharedChildPages::on_load();
}

上記の手順を説明できるスクリーンショットを次に示します。

これがあなたが探していたものではない場合、および/または私がコーディングしたものに加えてこのソリューションで対処する必要があるものに遭遇した場合、私に知らせてください。がんばろう!

5
MikeSchinkel