สร้างหน้าเก็บถาวรที่กำหนดเองสำหรับประเภทโพสต์ที่กำหนดเองในปลั๊กอิน


11

ฉันกำลังเขียนปลั๊กอินที่สร้างประเภทโพสต์ที่กำหนดเองชื่อ "my_plugin_lesson":

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

ประเภทโพสต์ที่กำหนดเองมีไฟล์เก็บถาวรและ URL ของไฟล์เก็บถาวรคือ:

http://example.com/lessons

ฉันต้องการปรับแต่งรูปลักษณ์ของไฟล์เก็บถาวรนี้; ฉันต้องการแสดงรายการโพสต์ในรูปแบบตารางแทนที่จะเป็นไฟล์เก็บถาวรโพสต์บล็อก WordPress มาตรฐาน ฉันเข้าใจว่าสามารถสร้างเทมเพลตการเก็บถาวรแบบกำหนดเองในชุดรูปแบบโดยสร้างarchive-my_plugin_lesson.phpไฟล์ อย่างไรก็ตามฉันต้องการให้ปลั๊กอินทำงานกับธีมใด ๆ

ฉันจะแก้ไขเนื้อหาของหน้าไฟล์เก็บถาวรโดยไม่ต้องเพิ่มหรือแก้ไขไฟล์ธีมได้อย่างไร

แก้ไข: ฉันเข้าใจว่าฉันสามารถใช้archive_templateตะขอตัวกรองได้ อย่างไรก็ตามสิ่งนี้ไม่ได้แทนที่แม่แบบชุดรูปแบบซึ่งยังคงต้องมีเฉพาะชุดรูปแบบ ยกตัวอย่างเช่นเพียงเกี่ยวกับแม่แบบธีมทุกคนจะต้องget_header, get_sidebarและget_footerฟังก์ชั่น แต่สิ่งที่ควร ID ของเนื้อหา<div>จะเป็นอย่างไร สิ่งนี้แตกต่างกันในทุกธีม

สิ่งที่ฉันต้องการจะทำคือการแทนที่เนื้อหาด้วยเนื้อหาของตัวเองและใช้แทนหน้าการเก็บถาวรสำหรับประเภทโพสต์ที่กำหนดเองของฉัน

คำตอบ:


12

สิ่งที่คุณต้องการคือ hooking template_includefilter และเลือกโหลดเทมเพลตของคุณภายในปลั๊กอิน

ตามแนวทางปฏิบัติที่ดีหากคุณวางแผนที่จะเผยแพร่ปลั๊กอินของคุณคุณควรตรวจสอบว่าarchive-my_plugin_lesson.php(หรืออาจmyplugin/archive-lesson.php) มีอยู่ในธีมหรือไม่หากไม่ใช้เวอร์ชันปลั๊กอิน

ด้วยวิธีนี้ง่ายสำหรับผู้ใช้แทนที่แม่แบบผ่านชุดรูปแบบ (หรือชุดรูปแบบลูก) โดยไม่ต้องแก้ไขรหัสปลั๊กอิน

นี่เป็นวิธีการที่ปลั๊กอินยอดนิยมใช้เช่น WooCommmerce แค่พูดชื่อเดียว

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

ข้อมูลเพิ่มเติมเกี่ยวกับ Codex สำหรับ


สิ่งนี้ยังคงแทนที่ไฟล์เท็มเพลตของธีมใช่ไหม ฉันจะใส่อะไรลงในไฟล์ archive-lesson.php ของปลั๊กอินได้บ้าง? มันจะต้องแตกต่างกันในการทำงานกับแต่ละธีม แม้แต่ชุดรูปแบบ "Twenty" เริ่มต้นก็ไม่เห็นด้วยกับส่วนของ div / section ที่ล้อมรอบเนื้อหา
Ben Miller - จำ Monica

7

คุณสามารถใช้archive_templatehook เพื่อประมวลผลเนื้อหาของแม่แบบเก็บถาวรของชุดรูปแบบโดยใช้รูปแบบด้านล่าง แต่แน่นอนว่าคุณจะสามารถดำเนินการเศษส่วนของชุดรูปแบบที่นั่นได้เพียงเพราะแม่แบบนั้นสามารถมีสิ่งเก่า ๆ .

แบบแผนคือการโหลดแม่แบบลงในสตริง ( $tpl_str) ในarchive_templateตัวกรองแทนที่เนื้อหาของคุณรวมถึงสตริง (ใช้เคล็ดลับeval( '?>' . $tpl_str );) แล้วส่งคืนไฟล์เปล่าเพื่อให้includeใน "wp-include / template-loader.php" กลายเป็นไม่มี -op

ด้านล่างเป็นรหัสเวอร์ชันที่แฮ็กที่ฉันใช้ในปลั๊กอินซึ่งมีเป้าหมายเทมเพลต "คลาสสิค" ที่ใช้get_template_partและเกี่ยวข้องกับการประมวลผลเทมเพลตเดียวมากกว่าที่เก็บถาวร แต่ควรช่วยคุณในการเริ่มต้น การตั้งค่าคือปลั๊กอินมีไดเรกทอรีย่อยที่เรียกว่า "แม่แบบ" ซึ่งเก็บไฟล์ว่าง ("null.php") และแม่แบบเนื้อหา (เช่น "content-single-posttype1.php", "content-archive-postype1.php") เช่นเดียวกับเทมเพลตย้อนกลับ "single.php" สำหรับกรณีเดียวและใช้ประโยชน์จากรุ่นที่กำหนดเองของget_template_partที่มีลักษณะในไดเรกทอรีนี้

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

กำหนดเอง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;
}

เพื่อความสมบูรณ์นี่คือการย้อนกลับ "single.php" ซึ่งใช้การกำหนดเองget_template_part:

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

1

ฉันไตร่ตรองคำถามเดียวกันและนี่เป็นวิธีแก้ปัญหาเชิงสมมุติฐานที่ฉันได้รับ:

  • ภายในปลั๊กอินให้สร้างรหัสย่อที่ให้ผลลัพธ์การเก็บถาวรแบบวนซ้ำตามที่คุณต้องการ
  • เมื่อสร้างประเภทโพสต์ที่กำหนดเองอย่าเปิดใช้งานตัวเลือก 'เก็บถาวร'
  • เพิ่มสไตล์ชีทที่ควบคุมสไตล์ทั้งหมดของเนื้อหาลูปของคุณ

เมื่อเปิดใช้งานปลั๊กอินให้สร้างหน้าโดยใช้ wp_insert_post โดยมีชื่อเป็นประเภทโพสต์และเนื้อหาเป็นรหัสย่อ

คุณสามารถให้ตัวเลือกในรหัสย่อสำหรับข้อควรพิจารณาเกี่ยวกับรูปแบบเพิ่มเติมหรือเพิ่มคลาสลงในคอนเทนเนอร์โพสต์เพื่อจับคู่สไตล์เฉพาะหรือสไตล์ที่กำหนดเอง ผู้ใช้ยังสามารถเพิ่มเนื้อหาเพิ่มเติมก่อน / หลังการวนซ้ำโดยการแก้ไขหน้า


แม้ฉันจะไม่ใช่ OP แต่ฉันก็กำลังมองหาวิธีแก้ไขปัญหาเดียวกัน ฉันได้ทำตามวิธีการด้านตรงข้ามมุมฉากของคุณและตอนนี้ฉันสามารถยืนยันได้ในทางปฏิบัติด้วย
Lucio Crusca

เฮ้เยี่ยมมาก! ดีใจที่มันมีประโยชน์สำหรับใครบางคน ฉันลืมเรื่องนี้ไปหมดแล้ว
SkyShab

0

single_templateคุณสามารถใช้ตัวกรอง ตัวอย่างพื้นฐานที่นำมาจาก 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" );

ฉันคิดว่าตัวกรองขอเกี่ยวกับแม่แบบเก็บถาวรนั้นเป็นarchive_templateแต่ฉันไม่คิดว่าสิ่งนี้จะใช้ได้กับสิ่งที่ฉันพยายามทำ ฉันแก้ไขคำถามด้วยข้อมูลเพิ่มเติม
Ben Miller - จดจำ Monica
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.