플러그인에서 사용자 정의 게시물 유형에 대한 사용자 정의 아카이브 페이지 작성


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

필요한 것은 template_include필터를 연결 하고 플러그인 내부에 템플릿을 선택적으로로드하는 것입니다.

당신이 당신의 플러그인을 배포하려는 경우 경우에 좋은 방법으로, 당신은 확인해야합니다 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 파일에 무엇을 넣습니까? 각 테마로 작업하려면 서로 달라야합니다. 기본 "20"테마조차 내용을 둘러싸고있는 div / 섹션 컨테이너가 무엇인지에 동의하지 않습니다.
벤 밀러-모니카를 기억하십시오

7

당신은 사용할 수 archive_template아래의 방식을 사용하여 테마의 아카이브 템플릿의 내용을 처리하기 위해 훅을하지만, 분명히 당신은 오직 템플릿은 기본적으로 이전의 모든 것을 포함 할 수 주어진, 거기 주제의 일부를 처리 할 수 있습니다 .

체계는 필터 $tpl_str에서 템플릿을 문자열 ( ) 로로드하고 archive_template, 내용을 대체하고, 문자열을 포함하고 (트릭을 사용하여 eval( '?>' . $tpl_str );) 빈 파일을 반환하여 include"wp-includes / template-loader.php" no-op가됩니다.

다음은 플러그인에서 사용하는 해킹 된 코드 버전입니다.이 버전은 사용하는 "클래식"템플릿을 대상으로 get_template_part하며 아카이브보다 단일 템플릿을 처리하는 데 더 관심이 있지만 시작하는 데 도움이됩니다. 플러그인에는 빈 파일 ( "null.php")과 컨텐츠 템플릿 (예 : "content-single-posttype1.php", "content-archive-postype1.php")을 포함하는 "templates"라는 하위 디렉토리가 플러그인에 있습니다. 단일 사례에 대한 대체 템플릿 "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하지만 이것이 내가하려는 일에 효과가 있다고 생각하지 않습니다. 자세한 내용으로 질문을 편집했습니다.
벤 밀러-모니카
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.