현재 템플릿 파일 이름 가져 오기


57

템플릿에서 사용 된 파일의 현재 이름을 표시하는 것으로 나타났습니다.

function get_template_name () {
    foreach ( debug_backtrace() as $called_file ) {
        foreach ( $called_file as $index ) {
            if ( !is_array($index[0]) AND strstr($index[0],'/themes/') AND !strstr($index[0],'footer.php') ) {
                $template_file = $index[0] ;
            }
        }
    }
    $template_contents = file_get_contents($template_file) ;
    preg_match_all("Template Name:(.*)\n)siU",$template_contents,$template_name);
    $template_name = trim($template_name[1][0]);
    if ( !$template_name ) { $template_name = '(default)' ; }
    $template_file = array_pop(explode('/themes/', basename($template_file)));
    return $template_file . ' > '. $template_name ;
}

출처 : 페이지에서 페이지 템플릿 이름 가져 오기

백엔드, 템플릿 선택 상자 에서이 추한 추가 항목을 얻는 것을 제외하고는 매우 잘 작동합니다.

스크린 샷

아무도 그것을 고치는 방법을 알고 있습니까? 백엔드에서이 함수가 왜 호출되는지 모르겠습니다. 다음과 같은 조건부 함수 is_frontend()가 있습니까? 아마도 문제를 해결할 수 있습니까?


2
@chodorowicz- functions.php버그로 선택하기 위해 한 걸음은 멈출 것이지만 , 전제에 전적으로 동의 할 것입니다. 설상가상으로 워드 프레스 핵심 코드를 스캔하고이 문제를 처리 할 수있는 후크가있을 수있는 곳이 약 5 곳 있지만 아직 발견되지 않았습니다. core.trac.wordpress.org에 티켓을 올리는 것이 좋습니다 .
MikeSchinkel

@ MikeSchinkel-의견에 감사드립니다.하지만 template_includet31os가 제안한 후크가 문제를 해결하지 않습니까? 아니면 내가 당신을 오해했을 수도 있습니다.
chodorowicz

1
@MikeSchinkel는 - 이미 패치 :이 core.trac.wordpress.org/ticket/16689
chodorowicz

1
현재 템플릿을 표시하기 위해 새 플러그인을 만들었습니다. wordpress.org/extend/plugins/display-template-name

4
^ 즉. 내 대답에서 코드를 가져 와서 플러그인으로 래핑했습니다. 그리고 당신은 원산지에 대한 신용을 제공하지 않고 자신이나 WP
스택 교환

답변:


68

template_include필터 중에 전역 변수를 설정 한 다음 나중에 전역 Vairable을 확인하여 어떤 템플릿이 포함되었는지 확인할 수 있습니다.

자연스럽게 파일과 함께 완전한 경로를 원하지 않으므로 PHP basename기능을 사용하여 파일 이름으로 자르는 것이 좋습니다 .

예제 코드 :
전역을 설정하는 함수와 호출하는 함수 두 가지

add_filter( 'template_include', 'var_template_include', 1000 );
function var_template_include( $t ){
    $GLOBALS['current_theme_template'] = basename($t);
    return $t;
}

function get_current_template( $echo = false ) {
    if( !isset( $GLOBALS['current_theme_template'] ) )
        return false;
    if( $echo )
        echo $GLOBALS['current_theme_template'];
    else
        return $GLOBALS['current_theme_template'];
}

그런 다음 get_current_template테마 파일에서 필요할 때 마다 template_include작업을 시작한 후에 자연스럽게 발생해야한다는 점에 주목할 수 있습니다 (템플릿 파일 내에서 호출 된 경우 걱정할 필요가 없습니다).

페이지 템플릿 is_page_template()의 경우 페이지 템플릿의 경우에만 도움이되는을 염두에두고 있습니다 ( 모든 기능을 훨씬 덜 잡습니다 ).

위에서 사용하거나 참조한 기능에 대한 정보 :


대박! 더 간단한 방법이 있어야한다는 것을 알았습니다.
racl101

하나는 내 디버깅 기능 목록의 맨 위에 추가합니다.
Jules

22

분명히 이것으로 충분합니다.

add_action('wp_head', 'show_template');
function show_template() {
    global $template;
    echo basename($template);
}

또는 템플릿에서 직접 사용하십시오 (HTML 주석의 footer.php에 에코하는 경향이 있습니다)

<?php global $template; echo basename($template); ?>

1
get-template-part에서는 작동하지 않으므로, 예를 들어 single.php 만 표시되며 파일은 포함되어 있지 않습니다.
m-torin

그래 그건 사실이야. 포함 된 파일의 이름을 얻으려면 아마도 다음과 같은 것을 사용해야합니다.echo __FILE__;
chodorowicz

예를 들어 기본 템플릿을 백 오피스의 게시물에 할당하지 않고 수정하는 경우에 좋습니다. 예를 들어 사용자 지정 경로와 template_include 필터를 사용합니다. 감사합니다.
Luca Reghellin

루프 내에서 어떻게 할 수 있습니까? 각 템플릿 파일의 한 페이지에 URL을 출력하려고합니다.
JacobTheDev

@JacobTheDev 아마도 사용 중 echo __FILE__-이것이 작동하지 않기 때문에 기본 템플릿 만 표시됩니다
chodorowicz

17

get_template_part () 와 같은 네이티브 WP 함수 와 PHP의 네이티브에는 테마 파일이 사용되는 모든 파일 목록을 가져 와서 테마에 속하지 않는 항목 (또는 부모와 자식 조합이 사용될 때의 테마)을 필터링하는 가장 안정적인 방법이 포함되어 있습니다. :

$included_files = get_included_files();
$stylesheet_dir = str_replace( '\\', '/', get_stylesheet_directory() );
$template_dir   = str_replace( '\\', '/', get_template_directory() );

foreach ( $included_files as $key => $path ) {

    $path   = str_replace( '\\', '/', $path );

    if ( false === strpos( $path, $stylesheet_dir ) && false === strpos( $path, $template_dir ) )
        unset( $included_files[$key] );
}

var_dump( $included_files );

9

다른 답변에 추가 (더 달콤한 코드)가 있습니다.

템플릿 이름

현재 페이지 템플릿 이름을 얻으려면 다음 줄을 사용하십시오.

is_page() AND print get_page_template_slug( get_queried_object_id() );

파일 이름

현재 템플릿 파일 이름 만 에코 하려면 다음을 수행하십시오.

편집 : 여기 클래스에 싸인 플러그인의 새로운 버전이 있습니다. 페이지 맨 아래의 종료 후크에 현재 템플리트 파일 이름과 템플리트 계층 구조 파일 이름이 모두 표시됩니다.

플러그인이 말하는 것 :

  • 자녀 / 현재 주제의 부모 템플릿이 있습니까?
  • 템플릿이 하위 폴더에서 제공됩니까? 예인 경우 : 이름을 알려줍니다
  • 템플릿 파일 이름

다음 코드를 파일에 복사하고 이름을 지정하고 wpse10537_template_info.php플러그인 디렉토리에 업로드 한 후 활성화하십시오.

<?php
/** Plugin Name: (#10537) »kaiser« Get Template file name */

if ( ! class_exists( 'wpse10537_template_name' ) )
{
    add_action( 'plugins_loaded', array( 'wpse10537_template_name', 'init' ) );

class wpse10537_template_name
{
    protected static $instance;

    public $stack;

    public static function init()
    {
        is_null( self :: $instance ) AND self :: $instance = new self;
        return self :: $instance;
    }

    public function __construct()
    {
        if ( is_admin() )
            return;

        add_action( 'wp', array( $this, 'is_parent_template' ), 0 );
        add_action( 'wp', array( $this, 'get_template_file' ) );
        add_action( 'template_include', array( $this, 'get_template_name' ) );
        add_action( 'shutdown', array( $this, 'get_template_name' ) );
    }

    public function get_template_name( $file )
    {
        if ( 'template_include' === current_filter() )
        {
            $this->to_stack(
                 "Template file"
                ,basename( $file )
            );
            return $file;
        }

        // Return static var on echo call outside of filter
        if (
            current_user_can( 'manage_options' )
            AND defined( 'WP_DEBUG' )
            AND WP_DEBUG 
        )
            return print implode( " &ndash; ", $this->stack );
    }

    public function get_template_file()
    {
        if ( ! is_post_type_hierarchical( get_post_type() ) )
            return;

        $slug = get_page_template_slug( get_queried_object_id() );
        if ( ! strstr( $slug, "/" ) )
            return $this->to_stack( "Template", $slug );

        $this->to_stack(
             "Subdirectory"
            ,strstr( $slug, "/", true )
        );

        $this->to_stack(
             "Template (in subdirectory)"
            ,str_replace( "/", "", strstr( $slug, "/" ) )
        );
    }

    public function is_parent_template()
    {
        if ( ! is_null( wp_get_theme()->parent ) )
            return $this->to_stack( 'from parent theme' );

        $this->to_stack( 'from current/child theme' );
    }

    public function to_stack( $part, $item = '' )
    {
        $this->stack[] = "{$part}: {$item}";
    }
} // END Class wpse10537_template_name

} // endif;

이 플러그인은 MU 플러그인으로도 실행할 수 있습니다.

그런 다음 wpse10537_get_template_name()언제라도 테마 템플릿과 같이 언제든지 호출 할 수 있습니다 . 이렇게하면 전역 네임 스페이스가 복잡해지지 않습니다.


1
template_redirect아무것도 전달하지 않고 있습니다 template_include. 또한 정적 변수가 채워져있는 대신 필터 내부를 확인합니다. 일부 코드가 후크 추가 시간을 실행하기로 결정하면 문제가 발생할 수 있습니다.
Rarst

@Rarst Done / Fixed. 힌트와 필터 이름을 지적 해 주셔서 감사합니다.
카이저

5

템플릿 이름은 postmeta 테이블에 저장되므로 루프의 어딘가에 넣으면됩니다.

$template = get_post_meta( $post->ID, '_wp_page_template', true );
echo "Template: " . $template;

2
예, 이에 대해 알고 있지만 문제는 페이지에 템플릿이 설정된 경우에만 작동한다는 것입니다. 내가 게시 한 코드의 멋진 점은 현재 페이지 에서 ,, 또는 다른 파일을 사용 front-page.php하고 있는지 알려줍니다 . 코드는 사용자 정의 페이지 템플리트가있는 페이지에 대해서만 템플리트 이름을 표시합니다. index.phpsingle.phppage.php
chodorowicz

아 죄송합니다-귀하의 질문에 대한 오해.
Simon Blackbourn

@SimonBlackbourn 그것은 내 요구 사항에 대한 도움입니다. 감사.
KarSho

3

이것은 OP의 모든 질문을 다루지는 않지만 아래 코드는 정규 표현식보다 템플릿보다 더 우아합니다.

페이지 템플리트를 사용하는 페이지에 있고 페이지 템플리트의 이름 (예 : 템플리트 PHP 파일의 맨 위에 주석에 정의한 사람이 읽을 수있는 이름)을 얻으려면 다음을 사용할 수 있습니다. 이 작은 덩어리 :

if ( is_page() && $current_template = get_page_template_slug( get_queried_object_id() ) ){
    $templates = wp_get_theme()->get_page_templates();
    $template_name = $templates[$current_template];
}

템플릿을 사용할 때 내장 WordPress body_class함수가 생성 하는 어리 석고 긴 클래스 이름이 너무 아파서 템플릿 이름을 얻고 싶었습니다 . 운좋게도 그 함수의 끝에 필터 훅이있어 자신 만의 클래스 이름을 추가 할 수 있습니다. 여기 내 필터가 있습니다. 누군가가 유용하다고 생각하기를 바랍니다.

add_filter( 'body_class', 'gs_body_classes', 10, 2 );
function gs_body_classes( $classes, $class ){
    if ( is_page() && $current_template = get_page_template_slug( get_queried_object_id() ) ){
        $templates = wp_get_theme()->get_page_templates();
        $template_name = str_replace( " ", "-", strtolower( $templates[$current_template] ) );

        $classes[] = $template_name;
    }

    return $classes;
}

이 필터는 페이지 템플릿의 이름을 바꾸고 공백을 대시로 바꾸고 모든 것을 소문자로 만들어 다른 모든 WordPress 클래스처럼 보입니다.


0

preg_match_all회선에 문제가 있습니다. 대신 이것을 시도하십시오 :

preg_match_all("/Template Name:(.*)\n/siU",$template_contents,$template_name);

또한 if (!is_admin()) { .... }프런트 엔드에서만 작업을 실행할 수 있습니다 .


제안 해 주셔서 감사합니다. 그들은 문제를 해결하지 못했지만 좀 나를 해결책으로 안내했습니다. 이 템플릿리스트를 생성하는 동안 WP는,도에보고되는 것으로 나타났다 functions.php발견 "/Template Name:(.*)\n/siU"따라서 처리 functions.php로 템플릿 파일을. 나는 이것이 WP 버그라고 생각하며,이 파일을 보지 않아야합니다. 해결책 : 파일을 서브 디렉토리로 이동하십시오.
chodorowicz

@ chodorowicz : 그것은 WP의 버그가 아니며 함수의 버그입니다.
wyrfel

따라서 기본적으로 WP는 파일에 문자열 "템플릿 이름 :"(설명 포함)을 넣지 못하게 functions.php합니다. 개인적으로, 그것은 버그이지만 (작지만 어쨌든) 그것은 토론에 달려 있습니다. 함수 자체가 버그라고 말할 수 없다고 생각합니다.
chodorowicz

WP는 당신이 아무것도하는 것을 금지하지 않습니다. 그러나 WP는 debug_backtrace ()를 반복하여 사용중인 템플릿 파일을 찾을 수 있다고 약속하지 않습니다. WP 지원 포럼에서 찾은다고해서 공식적으로 지원되는 코드는 아닙니다. 보시다시피, 함수는 footer.php를 명시 적으로 추출합니다. functions.php를 제외한 다른 조건을 추가 할 수도 있습니다. BTW : 함수가 Template Name각 파일 내에서 찾지 않고 루프가 오래 전에 끝났습니다.
wyrfel

문제는 없었습니다 debug_backtrace()-모든 코드를 제거하고 그냥 떠날 수 있습니다 preg_match_all("/Template Name.... 또는 심지어 // Template Name:WP functions.php가 템플릿 파일로 처리 하지만 의견에 감사드립니다. 이것은 말할 수없는 독특한 문제입니다. 버그입니다. t31os 솔루션은 깨끗하고 전체 문제를 해결합니다. 인사합니다.
chodorowicz 2013

0

함께 플레이 :

echo '<ul><li>'.implode('</li><li>', str_replace(str_replace('\\', '/', ABSPATH).'wp-content/', '', array_slice(str_replace('\\', '/', get_included_files()), (array_search(str_replace('\\', '/', ABSPATH).'wp-includes/template-loader.php', str_replace('\\', '/', get_included_files())) + 1)))).'</li></ul>';

글 :

현재 페이지를 제공하는 템플릿 페이지를 어떻게 알 수 있습니까?

경우 admin-bar stuff경로는 정상, 또는 다른 파일에 표시되고, 파일 이름을 변경 template-loader.php하면에서 휴식 할 필요가 무엇 filname : 코드 줄에.

관리자 표시 줄에서이 옵션이 필요한 경우 올바른 목록 (가장 빠른 시간) 을 사용 하여이 목록 의 끝에 파일이 입력되지 않도록 하십시오. 예를 들면 다음과 같습니다.

add_action('admin_bar_menu', 'my_adminbar_template_monitor', -5);

우선 -5로드해야합니다. 핵심은이 라인을 적시에 렌더링하는 것입니다.

"현재"템플리트 파일을 리턴하지 않지만 현재 페이지로드에 사용중인 모든 현재 파일을 리턴합니다. 어쩌면 그 아이디어에서 일부 논리로 "잘라낼"수도 있습니다.

get_included_files()"마지막"키 파일, 사이드 바 위젯 또는 무언가에 의해 바닥 글에 사용 된 propably 마지막 템플릿 파일 / part의 포함 등록 마지막이다. 아마도 cos mutiple 포함 파일은 get_included_files ()에서 다시 등록 / 채우지 않습니다.

그렇지 않으면, 이 문제를 해킹하기 위해 강렬함이 분명해야합니다 . 포함 된 파일이 포함되기 전에는 포함 된 파일을 포함 된 것으로보고 할 방법이 없습니다 . 그런 다음 시나리오를 사용하기에 늦었습니다.

대부분의 "시간" 은 다음 과 같습니다.

$template = get_current_loaded_template();
if($template == 'single-product.php') add_filter('the_title' ....
if($template == 'format-gallery.php') add_action('post_thumbnail' ....

그러나 템플릿이의 Wordpress 핵심 방법 외부에로드 된 경우에는 불가능 합니다 get_template_part. 대신 필요를 다시 디자인하십시오! 어쩌면 loop_start(), in_the_loop()add_action('the_post')데이터 템플릿의 따라 루프 내에서 각 항목에 대해 거 부하 이잖아 변경하는 당신이 원하는 솔루션을 가지고 있습니다.


-3
global $post;
$templateName = get_page_template_slug( $post->ID );
//echo $templateName;
var_dump( $templateName );
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.