it-swarm.com.de

Erstellen Sie eine benutzerdefinierte Archivseite für einen benutzerdefinierten Beitragstyp in einem Plugin

Ich schreibe ein Plugin, das einen benutzerdefinierten Beitragstyp mit dem Namen "my_plugin_lesson" erstellt:

$args = array (
    'public' => true,
    'has_archive' => true,
    'rewrite' => array('slug' => 'lessons', 'with_front' => false)
);
register_post_type ('my_plugin_lesson', $args);

Der benutzerdefinierte Beitragstyp verfügt über ein Archiv. Die URL des Archivs lautet:

http://example.com/lessons

Ich möchte das Aussehen dieses Archivs anpassen. Ich möchte die Beiträge in einem Tabellenformat und nicht im Standardarchiv für WordPress-Blogbeiträge auflisten. Ich verstehe, dass eine benutzerdefinierte Archivvorlage im Design erstellt werden kann, indem die Datei archive-my_plugin_lesson.php erstellt wird. Ich möchte jedoch, dass das Plugin mit jedem Thema funktioniert.

Wie kann ich den Inhalt der Archivseite ändern, ohne Themendateien hinzuzufügen oder zu ändern?

Edit: Ich verstehe, dass ich den archive_template Filter Hook verwenden könnte. Dies ersetzt jedoch lediglich die Themenvorlage, die immer noch themenspezifisch sein muss. Beispielsweise benötigt fast jede Designvorlage die Funktionen get_header, get_sidebar und get_footer, aber wie lautet die ID des Inhalts <div>? Dies ist in jedem Thema anders.

Ich möchte den Inhalt selbst durch meinen eigenen Inhalt ersetzen und diesen anstelle der Archivseite für meinen benutzerdefinierten Beitragstyp verwenden.

7
Ben Miller

Was Sie brauchen, ist das Einbinden von template_include filter und das selektive Laden Ihrer Vorlage in das Plugin.

Wenn Sie vorhaben, Ihr Plugin zu verbreiten, sollten Sie als bewährte Methode prüfen, ob archive-my_plugin_lesson.php (oder möglicherweise myplugin/archive-lesson.php) im Theme vorhanden ist, wenn Sie die Plugin-Version nicht verwenden.

Auf diese Weise ist es für Benutzer einfach, die Vorlage durch ein Thema (oder ein untergeordnetes Thema) zu ersetzen, ohne den Plugin-Code zu bearbeiten.

Dies ist die Methode, die von gängigen Plugins verwendet wird, z. WooCommmerce, um nur einen Namen zu nennen.

add_filter('template_include', 'lessons_template');

function lessons_template( $template ) {
  if ( is_post_type_archive('my_plugin_lesson') ) {
    $theme_files = array('archive-my_plugin_lesson.php', 'myplugin/archive-lesson.php');
    $exists_in_theme = locate_template($theme_files, false);
    if ( $exists_in_theme != '' ) {
      return $exists_in_theme;
    } else {
      return plugin_dir_path(__FILE__) . 'archive-lesson.php';
    }
  }
  return $template;
}

Weitere Informationen zu Codex für

8
gmazzap

Sie können den Hook archive_template verwenden, um den Inhalt der Archivvorlage eines Themas zu verarbeiten, indem Sie das folgende Schema verwenden. Sie können jedoch natürlich immer nur einen Bruchteil der Themen verarbeiten, da eine Vorlage im Grunde alle alten enthalten kann Ding.

Das Schema besteht darin, die Vorlage in eine Zeichenfolge ($tpl_str) im archive_template-Filter zu laden, Ihren Inhalt zu ersetzen, die Zeichenfolge einzuschließen (mit dem Trick eval( '?>' . $tpl_str );) und dann eine leere Datei zurückzugeben, sodass die include in "wp-includes/template- loader.php "wird zu einem No-Op.

Nachfolgend finden Sie eine gehackte Version von Code, den ich in einem Plugin verwende. Sie zielt auf "klassische" Vorlagen ab, die get_template_part verwenden und sich eher mit der Verarbeitung einzelner Vorlagen als mit dem Archivieren befassen, sollte Ihnen aber den Einstieg erleichtern. Das Plugin hat ein Unterverzeichnis namens "templates", das eine leere Datei ("null.php") und Inhaltsvorlagen (zB "content-single-posttype1.php", "content-archive-postype1.php") enthält. sowie eine Fallback-Vorlage "single.php" für den Einzelfall und verwendet eine benutzerdefinierte Version von get_template_part, die in diesem Verzeichnis gesucht wird.

define( 'MYPLUGIN_FOLDER', dirname( __FILE__ ) . '/' );
define( 'MYPLUGIN_BASENAME', basename( MYPLUGIN_FOLDER ) );

add_filter( 'single_template', 'myplugin_single_template' );
add_filter( 'archive_template', 'myplugin_archive_template' );

function myplugin_single_template( $template ) {
    static $using_null = array();

    // Adjust with your custom post types.
    $post_types = array( 'posttype1', );

    if ( is_single() || is_archive() ) {
        $template_basename = basename( $template );
        // This check can be removed.
        if ( $template == '' || substr( $template_basename, 0, 4 ) == 'sing' || substr( $template_basename, 0, 4 ) == 'Arch' ) {
            $post_type = get_post_type();
            $slug = is_archive() ? 'archive' : 'single';
            if ( in_array( $post_type, $post_types ) ) {
                // Allow user to override.
                if ( $single_template = myplugin_get_template( $slug, $post_type ) ) {
                    $template = $single_template;
                } else {
                    // If haven't gone through all this before...
                    if ( empty( $using_null[$slug][$post_type] ) ) {
                        if ( $template && ( $content_template = myplugin_get_template( 'content-' . $slug, $post_type ) ) ) {
                            $tpl_str = file_get_contents( $template );
                            // You'll have to adjust these regexs to your own case - good luck!
                            if ( preg_match( '/get_template_part\s*\(\s*\'content\'\s*,\s*\'' . $slug . '\'\s*\)/', $tpl_str, $matches, PREG_OFFSET_CAPTURE )
                            || preg_match( '/get_template_part\s*\(\s*\'content\'\s*,\s*get_post_format\s*\(\s*\)\s*\)/', $tpl_str, $matches, PREG_OFFSET_CAPTURE )
                            || preg_match( '/get_template_part\s*\(\s*\'content\'\s*\)/', $tpl_str, $matches, PREG_OFFSET_CAPTURE )
                            || preg_match( '/get_template_part\s*\(\s*\'[^\']+\'\s*,\s*\'' . $slug . '\'\s*\)/', $tpl_str, $matches, PREG_OFFSET_CAPTURE ) ) {
                                $using_null[$slug][$post_type] = true;
                                $tpl_str = substr( $tpl_str, 0, $matches[0][1] ) . 'include \'' . $content_template . '\'' . substr( $tpl_str, $matches[0][1] + strlen( $matches[0][0] ) );
                                // This trick includes the $tpl_str.
                                eval( '?>' . $tpl_str );
                            }
                        }
                    }
                    if ( empty( $using_null[$slug][$post_type] ) ) {
                        // Failed to parse - look for fall back template.
                        if ( file_exists( MYPLUGIN_FOLDER . 'templates/' . $slug . '.php' ) ) {
                            $template = MYPLUGIN_FOLDER . 'templates/' . $slug . '.php';
                        }
                    } else {
                        // Success! "null.php" is just a blank zero-byte file.
                        $template = MYPLUGIN_FOLDER . 'templates/null.php';
                    }
                }
            }
        }
    }
    return $template;
}

function myplugin_archive_template( $template ) {
    return myplugin_single_template( $template );
}

Der benutzerdefinierte get_template_part:

/*
 * Version of WP get_template_part() that looks in theme, then parent theme, and finally in plugin template directory (sub-directory "templates").
 * Also looks initially in "myplugin" sub-directory if any in theme and parent theme directories so that plugin templates can be kept separate.
 */
function myplugin_get_template( $slug, $part = '' ) {
    $template = $slug . ( $part ? '-' . $part : '' ) . '.php';

    $dirs = array();

    if ( is_child_theme() ) {
        $child_dir = get_stylesheet_directory() . '/';
        $dirs[] = $child_dir . MYPLUGIN_BASENAME . '/';
        $dirs[] = $child_dir;
    }

    $template_dir = get_template_directory() . '/';
    $dirs[] = $template_dir . MYPLUGIN_BASENAME . '/';
    $dirs[] = $template_dir;
    $dirs[] = MYPLUGIN_FOLDER . 'templates/';

    foreach ( $dirs as $dir ) {
        if ( file_exists( $dir . $template ) ) {
            return $dir . $template;
        }
    }
    return false;
}

Der Vollständigkeit halber hier die Fallback-Datei "single.php", die den benutzerdefinierten get_template_part verwendet:

<?php
get_header(); ?>

    <div id="primary" class="content-area">
        <div id="content" class="clearfix">
            <?php while ( have_posts() ) : the_post(); ?>

            <?php if ( $template = myplugin_get_template( 'content-single', get_post_type() ) ) include $template; else get_template_part( 'content', 'single' ); ?>

                <?php
                    // If comments are open or we have at least one comment, load up the comment template
                    if ( comments_open() || '0' != get_comments_number() ) :
                        comments_template();
                    endif;
                ?>

            <?php endwhile; ?>

        </div><!-- #content -->
    </div><!-- #primary -->

<?php get_sidebar(); ?>
<?php get_footer(); ?>
6
bonger

Ich habe über dieselbe Frage nachgedacht, und dies ist die hypothetische Lösung, die ich mir ausgedacht habe:

  • Erstellen Sie im Plugin einen Shortcode, der Ihre Archivschleife nach Ihren Wünschen ausgibt.
  • Aktivieren Sie beim Erstellen des benutzerdefinierten Beitragstyps nicht die Option "Archivieren".
  • Fügen Sie ein Stylesheet hinzu, das alle Stile Ihres Loop-Inhalts steuert.

Bei der Aktivierung des Plugins erstellen Sie eine Seite mit wp_insert_post, wobei der Name dem Post-Typ und der Inhalt dem Shortcode entspricht.

Sie können im Shortcode Optionen für zusätzliche Formatvorlagen bereitstellen oder dem Post-Container Klassen hinzufügen, die themenspezifischen oder benutzerdefinierten Formatvorlagen entsprechen. Der Benutzer kann durch Bearbeiten der Seite auch vor/nach der Schleife zusätzlichen Inhalt hinzufügen.

1
SkyShab

Sie können den Filter single_template verwenden. Ein grundlegendes Beispiel aus aus dem Codex :

function get_custom_post_type_template($single_template) {
     global $post;

     if ($post->post_type == 'my_post_type') {
          $single_template = dirname( __FILE__ ) . '/post-type-template.php';
     }
     return $single_template;
}

add_filter( "single_template", "get_custom_post_type_template" );
0
Eyal