web-dev-qa-db-fra.com

Comment afficher le même contenu sur plusieurs URL?

Un client a actuellement un site Web configuré avec trois sous-sites distincts (exécutés sur une seule installation WordPress), chacun avec un thème légèrement différent (même présentation, même jeu de couleurs différent).

Je l'ai actuellement mis en place de sorte que chaque sous-site est une page, avec toutes ses pages comme des enfants. Header.php vérifie quelle page est le parent et inclut le style approprié.

Le problème vient de pages identiques sur tout le site, que le client souhaite voir accessibles depuis chaque sous-site en tant que page distincte.

Par exemple, la page about devrait être accessible à partir de/site1/about et/site2/about et utiliser le thème du site qui l'a demandé, mais afficher le même contenu sur les deux.

Je pourrais simplement créer les pages enfants et définir le rel = "canonique" pour référencer l'original, mais du point de vue de la maintenance, il serait préférable de ne disposer que d'une seule page pour extraire le contenu de chacun des sous-sites.

Et ainsi à la question, comment puis-je obtenir plusieurs URL/pages pour extraire leur contenu à partir d'une source unique?

EDIT: Voici un exemple de la structure souhaitée:

  • www.example.com - Affiche des liens vers les trois principaux services, ainsi que des informations générales
  • www.example.com/about - Affiche des informations sur le client, stylées pour correspondre à www.example.com.
  • www.example.com/service1 - Affiche la navigation liée au service spécifique, stylée dans sa propre couleur, avec des liens génériques (à propos, contact)
  • www.example.com/service1/about - Affiche la navigation et la feuille de style de/service1, mais en utilisant le contenu de www.example.com/about (et avec une référence canonique à www.example.com/about )

Ceci est ensuite répété pour/service2 et/service3.

5
Ross Bearman

Je suis toujours aux prises avec les exigences exactes, mais si je comprends bien, je pense que vous pouvez le faire pour atteindre vos objectifs si vous utilisez le code que je vous ai fourni ci-dessous, puis procédez comme suit:

  1. Créez une page pour chacun de vos services (cela ressemble à ce que vous avez déjà fait): /service1/, /service2/, etc.

  2. Créez une page "base" service, avec une URL de /base-service/; ne vous inquiétez pas, personne ne le verra jamais à l'extérieur du site.

  3. Attribuez /base-service/ en tant que parent (ou grand-parent) page pour toutes les "pages virtuelles partagées" enfants à répliquer sous chaque service.

  4. Créez toutes les pages spécifiques au service que vous souhaitez également et attribuez-les à la page appropriée (par exemple, "Service 2", par exemple.)

  5. Créez un modèle page dans votre thème pour vos services appelé page-service.php et assurez-vous que chacune de vos pages de service utilise ce modèle de page (nécessaire pour que nous puissions déterminer quelles pages sont destinées à être des services) .

Voici donc le code d'une classe que j'ai appelée Yoursite_SharedChildPages que vous pouvez stocker dans le fichier functions.php de votre thème ou dans un fichier .php d'un plug-in que vous écrivez peut-être pour votre site:

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();
}

Et voici quelques captures d'écran pouvant illustrer les étapes mentionnées ci-dessus:

  

  

  

  

  

Faites-moi savoir si ce n'est pas ce que vous recherchiez et/ou si vous rencontrez un problème qui doit être résolu par cette solution en plus de ce que j'ai codé. Bonne chance!

5
MikeSchinkel