Benutzerdefinierter Beitragstyp, keine Einzelansicht erforderlich, und Permalink-Umschreibungen mit Hash in URI erforderlich

8

Wir verwenden CPTs, um eine Seite mit häufig gestellten Fragen auf einer Website zu verwalten, auf der die Frage der Titel des Beitrags und die Antwort der Inhalt des Beitrags ist. Es gibt eine Hauptseite für die FAQs, auf der alle Beiträge angezeigt werden (FAQ-Archivseite). Mit dieser Struktur brauchen wir wirklich keine einzelne Ansicht für FAQs und möchten sie in der Site-Struktur weglassen. Um Permalinks zu adressieren, möchten wir sie so einstellen, dass sie so etwas wie example.com/faq/#uniqueIdentifier sind. Wir denken, dass wir den #uniqueIdentifier verwenden, um einem Div auf der Archivseite mit der Antwort zu entsprechen und in einigen Fällen darauf aufmerksam zu machen Mode. Der uniqueIdentifier kann eine Post-ID, ein FAQ-Fragentitel, Daten aus einer Meta-Box oder etwas anderes sein.

Lassen Sie mich noch einmal zusammenfassen, was wir brauchen, um Folgendes zu erreichen:

(1) Schreiben Sie die FAQ-Permalinks neu, um / faq / # etwas zu sein, und

(2) Stellen Sie sicher, dass alle / faq / links zur Archivvorlage und nicht einzeln weitergeleitet werden

Ich bin meistens ein Noob, aber ziemlich gut darin, mich durch die Dinge zu fummeln. Ich habe jedoch noch nie versucht, etwas umzuschreiben, daher würde ich mich über eine bestimmte Richtung freuen.

Vielen Dank.

Daxitude
quelle

Antworten:

12

Hallo @daxitude:

Lassen Sie mich zunächst vorschlagen, dass Sie es sich noch einmal überlegen. Wenn Sie nicht für jede FAQ eine eigene FAQ-Seite haben:

  1. Sie reduzieren Ihre Oberfläche für die Suchmaschinenoptimierung und reduzieren den potenziellen Verkehr, den Sie möglicherweise erhalten, und

  2. Sie machen es jemandem unmöglich, eine bestimmte FAQ per E-Mail mit einem Freund zu teilen und / oder mit seinem Netzwerk auf Facebook, Twitter usw. zu teilen. (Als Benutzer bin ich immer frustriert von Website-Entwicklern, die mir keine direkte URL erlauben zu einem Artikel und zwinge mich stattdessen, auf die Seite zu verlinken, auf der alle Artikel aufgelistet sind.)

Wenn Sie dies dennoch tun möchten, gehen Sie wie folgt vor:

1.) Verwenden Sie den 'post_type_link'Haken

Verwenden Sie den 'post_type_link'Hook, um die URL wie im folgenden Beispiel * zu ändern (ich gehe davon aus, dass Ihr benutzerdefinierter Beitragstyp lautet 'faq'). Fügen Sie der functions.phpDatei Ihres Themas Folgendes hinzu :

add_action('post_type_link','yoursite_post_type_link',10,2);
function yoursite_post_type_link($link,$post) {
  $post_type = 'faq';
  if ($post->post_type==$post_type) {
    $link = get_post_type_archive_link($post_type) ."#{$post->post_name}";
  }
  return $link;
}

2.) unset($wp_rewrite->extra_permastructs['faq'])

Dies ist ein Hack , aber es ist ein erforderlicher Hack, um das zu tun, was Sie wollen. Verwenden Sie einen 'init'Haken, um unset($wp_rewrite->extra_permastructs['faq']). Es entfernt die Umschreiberegel, die register_post_type()hinzugefügt wird. Ich füge einen Anruf hinzu, register_post_type()damit ich Ihnen und anderen ein vollständiges Beispiel geben kann:

add_action('init','yoursite_init');
function yoursite_init() {
  register_post_type('faq',array(
      'labels' => array(
      'name' => _x('FAQs', 'post type general name'),
      'singular_name' => _x('FAQ', 'post type singular name'),
      'add_new' => _x('Add New', 'faq'),
      'add_new_item' => __('Add New FAQ'),
      'edit_item' => __('Edit FAQ'),
      'new_item' => __('New FAQ'),
      'view_item' => __('View FAQ'),
      'search_items' => __('Search FAQs'),
      'not_found' =>  __('No FAQs found'),
      'not_found_in_trash' => __('No FAQs found in Trash'),
      'parent_item_colon' => '',
      'menu_name' => 'FAQs'
    ),
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true,
    'show_in_menu' => true,
    'query_var' => true,
    'rewrite' => array('slug'=>'faqs'),
    'capability_type' => 'post',
    'has_archive' => 'faqs',
    'hierarchical' => false,
    'supports' => array('title','editor','author','thumbnail','excerpt')
  ));

  global $wp_rewrite;
  unset($wp_rewrite->extra_permastructs['faq']);  // Removed URL rewrite for specific FAQ 
  $wp_rewrite->flush_rules(); // THIS SHOULD BE DONE IN A PLUGIN ACTIVATION HOOK, NOT HERE!
}

Das ist alles.

Natürlich ist die obige Verwendung $wp_rewrite->flush_rules()in einem 'init'Hook eine wirklich schlechte Praxis und sollte wirklich nur einmal durchgeführt werden, also habe ich ein vollständiges und in sich geschlossenes Plugin implementiert, das aufgerufen wird FAQ_Post_Type, es richtig zu machen. Dieses Plugin fügt einen FAQ-Beitragstyp mit den gewünschten URL-Regeln hinzu und verwendet a register_activation_hook(), um die Umschreiberegeln zu leeren. Die Aktivierung ist offensichtlich eines der wenigen Dinge, die Plugin-Code anstelle von Code erfordern, der in der functions.phpDatei eines Themas ausgeführt werden kann.

Hier ist der Code für das FAQ_Post_TypePlugin. Fühlen Sie sich frei, für Ihre Anforderungen zu ändern:

<?php
/*
Plugin Name: FAQ Post Type
Description: Answers the question "Custom post type, no need for single view, plus want permalink rewrites that include hash in URI" on WordPress Answers.
Plugin URL: http://wordpress.stackexchange.com/questions/12762/custom-post-type-no-need-for-single-view-plus-want-permalink-rewrites-that-incl
*/
if (!class_exists('FAQ_Post_Type')) {
  class FAQ_Post_Type {
    static function on_load() {
      add_action('post_type_link', array(__CLASS__,'post_type_link'),10,2);
      add_action('init', array(__CLASS__,'init'));
    }
    static function post_type_link($link,$post) {
      if ('faq'==$post->post_type) {
        $link = get_post_type_archive_link('faq') ."#{$post->post_name}";
      }
      return $link;
    }
    static function init() {
      register_post_type('faq',array(
          'labels' => array(
          'name' => _x('FAQs', 'post type general name'),
          'singular_name' => _x('FAQ', 'post type singular name'),
          'add_new' => _x('Add New', 'faq'),
          'add_new_item' => __('Add New FAQ'),
          'edit_item' => __('Edit FAQ'),
          'new_item' => __('New FAQ'),
          'view_item' => __('View FAQ'),
          'search_items' => __('Search FAQs'),
          'not_found' =>  __('No FAQs found'),
          'not_found_in_trash' => __('No FAQs found in Trash'),
          'parent_item_colon' => '',
          'menu_name' => 'FAQs'
        ),
        'public' => true,
        'publicly_queryable' => true,
        'show_ui' => true,
        'show_in_menu' => true,
        'query_var' => true,
        'rewrite' => array('slug'=>'faqs'),
        'capability_type' => 'post',
        'has_archive' => 'faqs',
        'hierarchical' => false,
        'supports' => array('title','editor','author','thumbnail','excerpt'),
      ));
      global $wp_rewrite;
      unset($wp_rewrite->extra_permastructs['faq']);  // Remove URL rewrite for specific FAQ
    }
    static function activate() {
      global $wp_rewrite;
      $wp_rewrite->flush_rules();
    }
  }
  FAQ_Post_Type::on_load();
  register_activation_hook(__FILE__,array('FAQ_Post_Type','activate'));
}

Sie können die Flush-Regeln möglicherweise auch innerhalb 'init'von beibehalten, indem Sie einen Optionswert prüfen, wenn Sie dies bevorzugen:

// Add this code in your 'init' hook at your register_post_type('faq',...)
if (!get_option('faq_rewrite_rules_updated')) {
  global $wp_rewrite;
  unset($wp_rewrite->extra_permastructs['faq']);  // Remove URL rewrite for specific FAQ
  $wp_rewrite->flush_rules();
  update_option('faq_rewrite_rules_updated',true);
}

Deine Entscheidung.

Wie auch immer, lassen Sie mich wissen, wenn es Anwendungsfälle gibt, bei denen Sie feststellen, dass dies nicht der Fall ist.

MikeSchinkel
quelle
Hallo @MikeSchinkel. BEEINDRUCKEND! Sie sind sicherlich eine hilfreiche Person. Ich stimme von ganzem Herzen Ihren Überlegungen Nr. 1 und Nr. 2 zu, aber ich glaube, wir haben diese Bedenken größtenteils angesprochen. Für # 1 - da wir die vollständige Frage und Antwort auf der cpt-Archivseite anzeigen, wäre eine einzelne Ansicht für jede FAQ nicht doppelter Inhalt und daher nicht unbedingt günstig für SEO? Darüber hinaus haben wir das Gefühl, dass eine ganze Seite für nur eine FAQ-Frage ein bisschen mit dem Arm wedelt, und wir möchten den Leuten den Inhalt lieber schneller liefern, als durch weitere Links klicken zu müssen, um dorthin zu gelangen.
Daxitude
(Anscheinend gibt es Zeichenbeschränkungen für Kommentare und ich bin eine ausführliche Person!) Für # 2 - alles nach dem Hash im Uri wird mit einem Div auf der Seite abgeglichen, die die Antwort enthält. Alle anderen Antworten werden beim Laden der Seite ausgeblendet und die übereinstimmenden Antwortfolien werden geöffnet. Auf diese Weise behalten wir die Möglichkeit, Links zu teilen und zu speichern, vollständig bei ... solange wir nicht launisch werden und diese Struktur aus irgendeinem dummen Grund ändern.
Daxitude
Was Ihre Antwort betrifft, ist Schritt 1 fantastisch! Ich war bisher mit diesem Haken nicht vertraut und hatte eine so saubere Lösung nicht erwartet. Aus Neugier stelle ich fest, dass Sie Schritt 1 und nicht Schritt 2 implementieren können. Dadurch werden FAQ-Links an die entsprechende URL gesendet, aber auch die einzelnen Seiten bleiben erhalten. Wir verlinken sie jedoch nie über die Website. Scheint dies ein vernünftiger Weg zu sein? Vielen Dank.
Daxitude
@daxitude - Es ist besser, die Indizierung von Suchmaschinen auf einer Archivseite zu verbieten und ihnen die Indizierung der einzelnen Seiten zu ermöglichen. Die zwei wichtigsten Dinge für SEO sind Seiten, <title>und <h1>Heading</h1>Sie erhalten nur eine davon auf einer Archivseite, aber jeweils eine für einzelne FAQ-Seiten. Ich bin damit einverstanden, dass alle FAQ-Inhalte auf der Archivseite am besten sind, aber Sie können den gesamten Inhalt auf der Hauptseite und eine Drilldown-Seite für diejenigen bereitstellen, die dies wünschen (einschließlich Suchmaschinen) , und es schadet sicherlich nichts. Fügen Sie einfach einen "Permalink" in der Nähe der FAQ-Frage hinzu.
MikeSchinkel
@daxitude - Warum habe ich # 2 nicht implementiert? Das ist der Zweck des Codes, der der Überschrift "2.) unset($wp_rewrite->extra_permastructs['faq'])" folgt , was ich natürlich argumentiere, dass Sie nicht verwenden. :)
MikeSchinkel