เกลียดที่จะเป็นผู้แบกรับข่าวร้าย แต่WordPress ทำการโค้ดฟังก์ชันของเทมเพลทของหน้าลงในประเภทโพสต์"หน้า"อย่างน้อยใน v3.0 (ที่อาจมีการเปลี่ยนแปลงในรุ่นอนาคต แต่ไม่มีความคิดริเริ่มเฉพาะที่ฉันตระหนักถึงการเปลี่ยนแปลง ดังนั้นนี่เป็นหนึ่งในไม่กี่ครั้งที่ฉันพยายามหาวิธีหลีกเลี่ยงบางสิ่งโดยไม่ต้องแฮ็คคอร์)
วิธีแก้ปัญหาที่ฉันเกิดขึ้นคือการคัดลอกรหัสที่เกี่ยวข้องจาก WordPress core และปรับเปลี่ยนตามความต้องการของเรา นี่คือขั้นตอน (หมายเลขบรรทัดมาจาก v3.0.1):
คัดลอกpage_attributes_meta_box()
ฟังก์ชั่นจากบรรทัด 535 /wp-admin/includes/meta-boxes.php
และปรับเปลี่ยนให้เหมาะสม
รหัสadd_meta_boxes
เบ็ดเพื่อเพิ่มสารที่สร้างขึ้นใน # 1
คัดลอกget_page_templates()
ฟังก์ชั่นจากบรรทัด 166 /wp-admin/includes/theme.php
และปรับเปลี่ยนให้เหมาะสม
คัดลอกpage_template_dropdown()
ฟังก์ชั่นจากบรรทัด 2550 /wp-admin/includes/template.php
และแก้ไขให้เหมาะสม
เพิ่มเทมเพลตโพสต์ในธีมของคุณ
รหัสsave_post
เบ็ดเพื่อเปิดใช้งานการจัดเก็บชื่อไฟล์แม่แบบโพสต์เมื่อบันทึก
รหัสsingle_template
เบ็ดเพื่อเปิดใช้งานการโหลดแม่แบบโพสต์สำหรับโพสต์ที่เกี่ยวข้อง
ไปกับมัน!
1. คัดลอกpage_attributes_meta_box()
ฟังก์ชั่น
ในฐานะที่เป็นขั้นตอนแรกของเราท่านต้องคัดลอกpage_attributes_meta_box()
ฟังก์ชั่นจากบรรทัด 535 ของและฉันได้เลือกที่จะเปลี่ยนชื่อ/wp-admin/includes/meta-boxes.php
post_template_meta_box()
เนื่องจากคุณขอเฉพาะเทมเพลตของหน้าเว็บฉันจึงตัดรหัสเพื่อระบุโพสต์หลักและระบุลำดับที่ทำให้รหัสง่ายขึ้นมาก ฉันยังเลือกที่จะใช้ postmeta สำหรับสิ่งนี้แทนที่จะพยายามนำpage_template
คุณสมบัติของวัตถุกลับมาใช้ใหม่เพื่อหลีกเลี่ยงและความไม่ลงรอยกันที่อาจเกิดขึ้นจากการมีเพศสัมพันธ์โดยไม่ได้ตั้งใจ ดังนั้นนี่คือรหัส:
function post_template_meta_box($post) {
if ( 'post' == $post->post_type && 0 != count( get_post_templates() ) ) {
$template = get_post_meta($post->ID,'_post_template',true);
?>
<label class="screen-reader-text" for="post_template"><?php _e('Post Template') ?></label><select name="post_template" id="post_template">
<option value='default'><?php _e('Default Template'); ?></option>
<?php post_template_dropdown($template); ?>
</select>
<?php
} ?>
<?php
}
2. รหัสadd_meta_boxes
เบ็ด
ขั้นต่อไปคือการเพิ่ม metabox โดยใช้add_meta_boxes
hook:
add_action('add_meta_boxes','add_post_template_metabox');
function add_post_template_metabox() {
add_meta_box('postparentdiv', __('Post Template'), 'post_template_meta_box', 'post', 'side', 'core');
}
3. คัดลอกget_page_templates()
ฟังก์ชั่น
ฉันคิดว่ามันจะทำให้รู้สึกถึงความแตกต่างระหว่างแม่แบบหน้าและหลังแม่แบบจึงต้องมีget_post_templates()
ฟังก์ชั่นบนพื้นฐานget_page_templates()
จากบรรทัด /wp-admin/includes/theme.php
166 แต่แทนที่จะใช้Template Name:
เครื่องหมายซึ่งแม่แบบหน้าใช้ฟังก์ชันนี้ใช้Post Template:
เครื่องหมายแทนซึ่งคุณสามารถดูด้านล่าง
ผมก็กรองออกตรวจสอบfunctions.php
(ไม่แน่ใจว่าget_page_templates()
เคยทำงานได้อย่างถูกต้องโดยไม่ต้องว่า แต่สิ่งที่!)และสิ่งเดียวที่เหลือคือการอ้างอิงการเปลี่ยนแปลงคำpage
เพื่อpost
สำหรับการอ่านการบำรุงรักษาลงที่ถนน:
function get_post_templates() {
$themes = get_themes();
$theme = get_current_theme();
$templates = $themes[$theme]['Template Files'];
$post_templates = array();
if ( is_array( $templates ) ) {
$base = array( trailingslashit(get_template_directory()), trailingslashit(get_stylesheet_directory()) );
foreach ( $templates as $template ) {
$basename = str_replace($base, '', $template);
if ($basename != 'functions.php') {
// don't allow template files in subdirectories
if ( false !== strpos($basename, '/') )
continue;
$template_data = implode( '', file( $template ));
$name = '';
if ( preg_match( '|Post Template:(.*)$|mi', $template_data, $name ) )
$name = _cleanup_header_comment($name[1]);
if ( !empty( $name ) ) {
$post_templates[trim( $name )] = $basename;
}
}
}
}
return $post_templates;
}
4. คัดลอกpage_template_dropdown()
ฟังก์ชั่น
คัดลอกpage_template_dropdown()
มาจากบรรทัด 2550 ของ/wp-admin/includes/template.php
เพื่อสร้างpost_template_dropdown()
และเปลี่ยนเป็นสายget_post_templates()
แทน:
function post_template_dropdown( $default = '' ) {
$templates = get_post_templates();
ksort( $templates );
foreach (array_keys( $templates ) as $template )
: if ( $default == $templates[$template] )
$selected = " selected='selected'";
else
$selected = '';
echo "\n\t<option value='".$templates[$template]."' $selected>$template</option>";
endforeach;
}
5. เพิ่มเทมเพลตโพสต์
ขั้นตอนต่อไปคือการเพิ่มเทมเพลตโพสต์สำหรับการทดสอบ ใช้Post Template:
เครื่องหมายที่กล่าวถึงในขั้นตอนที่ 3 คัดลอกsingle.php
จากชุดรูปแบบของคุณไปยังsingle-test.php
และเพิ่มส่วนหัวของความคิดเห็นต่อไปนี้ ( อย่าลืมแก้ไขบางสิ่งsingle-test.php
เพื่อให้คุณสามารถบอกได้ว่ากำลังโหลดแทนsingle.php
) :
/**
* Post Template: My Test Template
*/
เมื่อคุณทำตามขั้นตอน # 1 ถึง # 5 แล้วคุณจะเห็นmetabox "เทมเพลตโพสต์"ปรากฏในหน้าเครื่องมือแก้ไขบทความ:
(ที่มา: mikeschinkel.com )
6. รหัสsave_post
เบ็ด
หลังจากที่คุณมีตัวแก้ไขกำลังสองคุณต้องบันทึกชื่อไฟล์เทมเพลตของหน้าเป็น postmeta เมื่อผู้ใช้คลิก "เผยแพร่" นี่คือรหัสสำหรับ:
add_action('save_post','save_post_template',10,2);
function save_post_template($post_id,$post) {
if ($post->post_type=='post' && !empty($_POST['post_template']))
update_post_meta($post->ID,'_post_template',$_POST['post_template']);
}
7. รหัสsingle_template
เบ็ด
และสุดท้ายคุณต้องได้รับ WordPress ใช้เทมเพลตโพสต์ใหม่ของคุณ คุณทำอย่างนั้นโดยการขอsingle_template
และส่งคืนชื่อเทมเพลตที่คุณต้องการสำหรับโพสต์เหล่านั้นที่ได้รับมอบหมาย:
add_filter('single_template','get_post_template_for_template_loader');
function get_post_template_for_template_loader($template) {
global $wp_query;
$post = $wp_query->get_queried_object();
if ($post) {
$post_template = get_post_meta($post->ID,'_post_template',true);
if (!empty($post_template) && $post_template!='default')
$template = get_stylesheet_directory() . "/{$post_template}";
}
return $template;
}
และที่เกี่ยวกับมัน!
หมายเหตุที่ฉันไม่ได้คำนึงถึงประเภทกำหนดเองโพสต์post_type=='post'
เท่านั้น ในความเห็นของฉันเกี่ยวกับประเภทโพสต์ที่กำหนดเองจะต้องมีความแตกต่างระหว่างประเภทโพสต์ที่แตกต่างกันและในขณะที่ไม่ยากเกินไปฉันไม่ได้ลองที่นี่