WordPress 템플릿 계층 에서 내가 가장 좋아하는 부분은 템플릿 을 선택하기 위해 WordPress에서 페이지를 편집 할 필요없이 슬러그로 페이지에 대한 템플릿 파일을 빠르게 만들 수 있다는 것입니다.
우리는 현재 이것을 할 수 있습니다 :
page- {slug} .php
그러나 나는 이것을 할 수 있기를 원합니다.
single- {post_type}-{slug} .php
예를 들어이라는 게시물 유형에서 review
‘My Great Review’라는 게시물에 대한 템플릿을 만들 수 있습니다.single-review-my-great-review.php
아무도 전에 이것을 설정 한 적이 있습니까? single-{post_type}-{slug}.php
답변
A) 핵심의 기초
Codex Template Hierarchy 설명 에서 볼 수 있듯이 single-{$post_type}.php
이미 지원됩니다.
B) 핵심 계층 확장
이제 내부에 약간의 필터와 후크가 있습니다 /wp-includes/template-loader.php
.
do_action('template_redirect');
apply_filters( 'template_include', $template )
- AND :
get_query_template( $type, ... )
이름이 지정된 특정 필터 :"$type}_template"
B.1) 작동 원리
- 템플릿 로더 파일 내에서 템플릿은 var / wp_query 조건부 쿼리에 의해로드됩니다
is_*()
. - 그런 다음 조건부 ( “단일”템플릿의 경우)가 트리거됩니다.
is_single() && $template = get_single_template()
- 이것은 다음 트리거
get_query_template( $type, $templates )
곳$type
입니다single
- 그런 다음
"{$type}_template"
필터가 있습니다
C) 해결책
우리가 단지 도착 하나의 템플릿으로 계층 구조를 확장 할 전에로드 실제 "single-{$object->post_type}.php"
템플릿, 우리는 계층 구조를 차단하고 템플릿 배열의 시작 부분에 새 템플릿을 추가합니다.
// Extend the hierarchy
function add_posttype_slug_template( $templates )
{
$object = get_queried_object();
// New
$templates[] = "single-{$object->post_type}-{$object->post_name}.php";
// Like in core
$templates[] = "single-{$object->post_type}.php";
$templates[] = "single.php";
return locate_template( $templates );
}
// Now we add the filter to the appropriate hook
function intercept_template_hierarchy()
{
add_filter( 'single_template', 'add_posttype_slug_template', 10, 1 );
}
add_action( 'template_redirect', 'intercept_template_hierarchy', 20 );
참고 : (기본 개체 슬러그 이외의 다른 것을 사용하려면) $slug
퍼머 링크 구조에 따라 조정 해야합니다. 전 세계에서 필요한 것을 사용하십시오 (object) $post
.
트랙 티켓
위의 접근 방식은 현재 지원 되지 않으므로 (이 방법으로 절대 경로 만 필터링 할 수 있음) trac 티켓 목록은 다음과 같습니다.
- post_type-> slug로 계층 확장
- 에 대한 필터를 소개합니다
get_query_template()
- 완전한 계층 구조 필터링-가장 유망한 티켓 ⤎ @scribu 의 cc 로이 티켓 팔로우
답변
템플릿 계층 구조 이미지에 따라 이러한 옵션이 표시되지 않습니다.
그래서 여기에 내가 어떻게 갈 것인가?
솔루션 1 (제 의견으로는 최고)
템플릿 파일을 만들어 검토에 연결
<?php
/*
Template Name: My Great Review
*/
?>
테마 디렉토리에 템플릿 PHP 파일을 추가하면 게시물의 편집 페이지에 템플릿 옵션으로 나타납니다.
해결책 2
이것은 아마도 template_redirect
후크를 사용하여 달성 될 수 있습니다 .
functions.php 파일에서 :
function my_redirect()
{
global $post;
if( get_post_type( $post ) == "my_cpt" && is_single() )
{
if( file_exists( get_template_directory() . '/single-my_cpt-' . $post->post_name . '.php' ) )
{
include( get_template_directory() . '/single-my_cpt-' . $post->post_name . '.php' );
exit;
}
}
}
add_action( 'template_redirect', 'my_redirect' );
편집하다
추가 file_exists
확인
답변
4 년 전의 최고 답변은 더 이상 작동하지 않지만 WordPress 코덱 은 해결책이 있습니다 .
<?php
function add_posttype_slug_template( $single_template )
{
$object = get_queried_object();
$single_postType_postName_template = locate_template("single-{$object->post_type}-{$object->post_name}.php");
if( file_exists( $single_postType_postName_template ) )
{
return $single_postType_postName_template;
} else {
return $single_template;
}
}
add_filter( 'single_template', 'add_posttype_slug_template', 10, 1 );
?>
답변
페이지 템플릿 사용
확장성에 대한 다른 접근 방식은 page
사용자 정의 게시물 유형 의 게시물 유형 에서 페이지 템플릿 드롭 다운 기능을 복제하는 것 입니다.
재사용 가능한 코드
코드 복제는 좋은 습관이 아닙니다. 시간이 지나면 개발자가 관리하기가 어려울 때 코드베이스에 심각한 팽창이 발생할 수 있습니다. 모든 단일 슬러그에 대한 템플릿을 생성하는 대신 일대일 사후 템플릿 대신 재사용 할 수있는 일대 다 템플릿이 필요할 것입니다.
코드
# Define your custom post type string
define('MY_CUSTOM_POST_TYPE', 'my-cpt');
/**
* Register the meta box
*/
add_action('add_meta_boxes', 'page_templates_dropdown_metabox');
function page_templates_dropdown_metabox(){
add_meta_box(
MY_CUSTOM_POST_TYPE.'-page-template',
__('Template', 'rainbow'),
'render_page_template_dropdown_metabox',
MY_CUSTOM_POST_TYPE,
'side', #I prefer placement under the post actions meta box
'low'
);
}
/**
* Render your metabox - This code is similar to what is rendered on the page post type
* @return void
*/
function render_page_template_dropdown_metabox(){
global $post;
$template = get_post_meta($post->ID, '_wp_page_template', true);
echo "
<label class='screen-reader-text' for='page_template'>Page Template</label>
<select name='_wp_page_template' id='page_template'>
<option value='default'>Default Template</option>";
page_template_dropdown($template);
echo "</select>";
}
/**
* Save the page template
* @return void
*/
function save_page_template($post_id){
# Skip the auto saves
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
elseif ( defined( 'DOING_AJAX' ) && DOING_AJAX )
return;
elseif ( defined( 'DOING_CRON' ) && DOING_CRON )
return;
# Only update the page template meta if we are on our specific post type
elseif(MY_CUSTOM_POST_TYPE === $_POST['post_type'])
update_post_meta($post_id, '_wp_page_template', esc_attr($_POST['_wp_page_template']));
}
add_action('save_post', 'save_page_template');
/**
* Set the page template
* @param string $template The determined template from the WordPress brain
* @return string $template Full path to predefined or custom page template
*/
function set_page_template($template){
global $post;
if(MY_CUSTOM_POST_TYPE === $post->post_type){
$custom_template = get_post_meta($post->ID, '_wp_page_template', true);
if($custom_template)
#since our dropdown only gives the basename, use the locate_template() function to easily find the full path
return locate_template($custom_template);
}
return $template;
}
add_filter('single_template', 'set_page_template');
이것은 약간의 대답이지만 웹에서는 아무도 내가 알 수있는 한이 방법을 문서화하지 않았기 때문에 가치가 있다고 생각했습니다. 이것이 누군가를 돕기를 바랍니다.
답변
필자의 경우 앨범 분류법으로 연결된 앨범 및 트랙 사용자 정의 게시물 유형이 있습니다. 앨범 분류에 따라 앨범 및 트랙 게시물에 다른 단일 템플릿을 사용할 수 있기를 원했습니다.
위의 Kaiser의 답변을 바탕 으로이 코드를 작성했습니다. 잘 작동한다.
노트. add_action ()이 필요하지 않았습니다.
// Add an additional template option to the template hierarchy
add_filter( 'single_template', 'add_albumtrack_taxslug_template', 10, 1 );
function add_albumtrack_taxslug_template( $orig_template_path )
{
// at this point, $orig_template_path is an absolute located path to the preferred single template.
$object = get_queried_object();
if ( ! (
// specify another template option only for Album and Track post types.
in_array( $object->post_type, array( 'gregory-cpt-album','gregory-cpt-track' )) &&
// check that the Album taxonomy has been registered.
taxonomy_exists( 'gregory-tax-album' ) &&
// get the Album taxonomy term for the current post.
$album_tax = wp_get_object_terms( $object->ID, 'gregory-tax-album' )
))
return $orig_template_path;
// assemble template name
// assumption: only one Album taxonomy term per post. we use the first object in the array.
$template = "single-{$object->post_type}-{$album_tax[0]->slug}.php";
$template = locate_template( $template );
return ( !empty( $template ) ? $template : $orig_template_path );
}
이제 single-gregory-cpt-track-tax-serendipity.php라는 템플릿을 만들 수 있으며 single-gregory-cpt-album-tax-serendipity.php를 사용하면 WP가 자동으로 사용합니다. ‘tax-serendipity’는 첫 번째 앨범 분류 용어의 슬러그입니다.
참고로 ‘single_template’필터 후크는
/wp-includes/theme.php에 선언되어 있습니다 .get_query_template()
샘플 코드에 대해 Kaiser에게 감사합니다.
건배, 그레고리
답변
Brians 코드를 업데이트 한 결과 드롭 다운 상자를 사용하지 않을 때 “default”템플릿 옵션이 wp_page_template에 저장되어 default라는 템플릿을 찾게되었습니다. 이 변경 사항은 저장시 “default”옵션 만 확인하고 대신 포스트 메타를 삭제합니다 (템플릿 옵션을 기본값으로 다시 변경 한 경우 유용함)
elseif (MY_CUSTOM_POST_TYPE === $ _POST [ 'post_type']) { if (esc_attr ($ _ POST [ '_ wp_page_template']) === "default") : delete_post_meta ($ post_id, '_wp_page_template'); 다른 : update_post_meta ($ post_id, '_wp_page_template', esc_attr ($ _ POST [ '_ wp_page_template'])); 엔디 프; }