更好、更简洁的解决方案不是使用自定义页面模板来定义页面布局*,而是使用自定义post meta来定义页面布局。
要实施:
创建Theme Option 对于Default static page layout, 包括所有可能的页面布局选项_page_layout
custom post meta 对于Page Layout, 其中包括一个“默认布局”选项,以及上述主题选项中使用的所有可能的布局选项body_class
filter 输出alayout-$layout
类转换为HTML<body>
标签,通过body_class()
模板标记,其中$layout
定义为:如果\'default\' == \'_page_layout\'
, 如果出现以下情况,请使用主题选项值\'$layout\' == \'_page_layout\'
, 使用$layout
来自Oenology的概念验证代码如下(注意:从原始版本修改而来,因为我为静态页面、单个博客帖子和归档索引页面的布局应用了自定义帖子元):
添加元框
/**
* Add Layout Meta Box
*
* @uses __()
* @uses add_meta_box()
*/
function oenology_add_layout_meta_box( $post ) {
global $wp_meta_boxes;
$context = \'side\'; // \'normal\', \'side\', \'advanced\'
$priority = \'default\'; // \'high\', \'core\', \'low\', \'default\'
add_meta_box(
\'oenology_layout\',
__( \'Static Page Layout\', \'oenology\' ),
\'oenology_layout_meta_box\',
\'page\',
$context,
$priority
);
}
// Hook meta boxes into \'add_meta_boxes\'
add_action( \'add_meta_boxes-page\', \'oenology_add_layout_meta_box\' );
/**
* Define Layout Meta Box
*
* Define the markup for the meta box
* for the "layout" post custom meta
* data. The metabox will consist of
* radio selection options for "default"
* and each defined, valid layout
* option for single blog posts or
* static pages, depending on the
* context.
*
* @uses oenology_get_option_parameters() Defined in \\functions\\options.php
* @uses checked()
* @uses get_post_custom()
*/
function oenology_layout_meta_box() {
global $post;
$option_parameters = oenology_get_option_parameters();
$custom = ( get_post_custom( $post->ID ) ? get_post_custom( $post->ID ) : false );
$layout = ( isset( $custom[\'_oenology_layout\'][0] ) ? $custom[\'_oenology_layout\'][0] : \'default\' );
$valid_layouts = $option_parameters[\'default_static_page_layout\'][\'valid_options\'];
?>
<p>
<input type="radio" name="_oenology_layout" <?php checked( \'default\' == $layout ); ?> value="default" />
<label>Default</label><br />
<?php foreach ( $valid_layouts as $valid_layout ) { ?>
<input type="radio" name="_oenology_layout" <?php checked( $valid_layout[\'name\'] == $layout ); ?> value="<?php echo $valid_layout[\'name\']; ?>" />
<label><?php echo $valid_layout[\'title\']; ?> <span style="padding-left:5px;"><em><?php echo $valid_layout[\'description\']; ?></em></span></label><br />
<?php } ?>
</p>
<?php
}
/**
* Validate, sanitize, and save post metadata.
*
* Validates the user-submitted post custom
* meta data, ensuring that the selected layout
* option is in the array of valid layout
* options; otherwise, it returns \'default\'.
*
* @uses oenology_get_option_parameters() Defined in \\functions\\options.php
* @uses array_key_exists()
* @uses update_post_meta()
*/
function oenology_save_layout_post_metadata(){
global $post;
$option_parameters = oenology_get_option_parameters();
$valid_layouts = array();
if ( \'post\' == $post->post_type ) {
$valid_layouts = $option_parameters[\'default_single_post_layout\'][\'valid_options\'];
} else if ( \'page\' == $post->post_type ) {
$valid_layouts = $option_parameters[\'default_static_page_layout\'][\'valid_options\'];
}
$layout = ( isset( $_POST[\'_oenology_layout\'] ) && array_key_exists( $_POST[\'_oenology_layout\'], $valid_layouts ) ? $_POST[\'_oenology_layout\'] : \'default\' );
update_post_meta( $post->ID, \'_oenology_layout\', $layout );
}
// Hook the save layout post custom meta data into
// publish_{post-type}, draft_{post-type}, and future_{post-type}
add_action( \'draft_page\', \'oenology_save_layout_post_metadata\' );
add_action( \'future_post\', \'oenology_save_layout_post_metadata\' );
add_action( \'future_page\', \'oenology_save_layout_post_metadata\' );
确定当前页面布局
/**
* Get Current Page Layout
*/
function oenology_get_current_page_layout() {
// Use default layout for 404 pages
if ( is_404() ) {
return \'default\';
}
// Otherwise, determine appropriate layout
$layout = \'\';
global $post;
global $oenology_options;
$custom = ( get_post_custom( $post->ID ) ? get_post_custom( $post->ID ) : false );
$custom_layout = ( isset( $custom[\'_oenology_layout\'][0] ) ? $custom[\'_oenology_layout\'][0] : \'default\' );
if ( ! is_admin() ) {
if ( is_attachment() ) {
$layout .= \'attachment\';
}
else if ( is_page() ) {
if ( \'default\' == $custom_layout ) {
$layout .= $oenology_options[\'default_static_page_layout\'];
} else {
$layout .= $custom_layout;
}
}
}
else if ( is_admin() ) {
if ( \'attachment\' == $post->post_type ) {
$layout .= \'attachment\';
}
else if ( \'page\' == $post->post_type ) {
if ( \'default\' == $custom_layout ) {
$layout .= $oenology_options[\'default_static_page_layout\'];
}
else {
$layout .= $custom_layout;
}
}
}
return $layout;
}
过滤体类别
/**
* Add layout CSS classes to the HTML body tag
*
* Filter Hook: body_class
*
* Filter \'body_class\' to include
* classes for page layout.
*
* @uses oenology_get_current_page_layout() Defined in \\functions\\custom.php
*
* @since Oenology 2.0
*/
function oenology_filter_body_class( $classes ) {
$layout = \'layout-\';
$layout .= oenology_get_current_page_layout();
$classes[] = $layout;
return $classes;
}
// Hook custom classes into \'body_class\'
add_filter( \'body_class\', \'oenology_filter_body_class\' );
*自定义页面模板实际上不是用于定义布局,而是用于定义自定义页面内容。