定义没有自己的.php文件的自定义页面模板

时间:2014-04-30 作者:MikO

是否有任何方法可以从某个函数/过滤器/挂钩定义页面模板,而无需任何。在页面顶部包含注释以声明模板名称的php文件?

例如,不要这样做:

一些自定义页面模板。php

/**
* Template Name: Some Custom Page Template
*/
另一个自定义页面模板。php
/**
* Template Name: Another Custom Page Template
*/
我想知道我是否可以做以下事情:

功能。php

wp_some_function_to_define_templates( \'Some Custom Page Template\' );
wp_some_function_to_define_templates( \'Another Custom Page Template\' );

EDIT:我正在写一个复杂的、有点实验性的WP主题-它是WP允许的面向对象的,我有控制器类来决定在每个页面中显示什么,DAO类来从DB中检索数据,细枝模板来生成视图等等。。。

我对代码进行了大量的扩展,以至于我的页面模板变成了一行代码,在这里我调用一些控制器并让它完成工作,最终呈现一个小树枝模板。所以我决定把电话转到控制器,转到template_include 过滤,这样我甚至不需要在页面模板中放置任何代码。。。

我可能会去掉页面模板,但我仍然需要它们以某种方式对页面进行分组,为它们设置一些高级自定义字段组,等等。。。

因此,我最终得到了大约15个PHP文件,这些文件的顶部只包含一条带有模板名称的注释,这正是我希望通过从某个函数定义这些模板来避免的。。。

我是在试图重新发明轮子吗?也许在某种意义上,但我认为它正在成为一个非常酷的主题,非常可维护和可修改。。。

3 个回复
最合适的回答,由SO网友:gmazzap 整理而成

WordPress从文件头读取模板,然后在缓存中设置它们。使用wp_cache_set() nad从md5 has的样式表文件夹派生的键。

因此,只要覆盖该缓存,我们就可以显示所需的模板。要覆盖该缓存,我们需要调用wp_cache_set() 再次使用相同的键。

首先,让我们编写一个函数来检索要显示的模板。我们可以通过多种方式设置模板:选项、配置文件、过滤器或它们的组合:

function get_custom_page_templates() {
  $templates = array();
  // maybe by options? --> $templates = get_option( \'custom_page_templates\' );
  // maybe by conf file? --> $templates = include \'custom_page_templates.php\';
  return apply_filters( \'custom_page_templates\', $templates );
}
之后,我们需要在WordPress保存缓存之后检索页面编辑中的模板。此外,我们需要在发布编辑表单以允许保存时再次获取它们。

我们可以使用\'edit_form_after_editor\' 第一个范围的挂钩,\'load-post.php\'\'load-post.new\' 对于第二个:

add_action( \'edit_form_after_editor\', \'custom_page_templates_init\' );
add_action( \'load-post.php\', \'custom_page_templates_init_post\' );
add_action( \'load-post-new.php\', \'custom_page_templates_init_post\' );

function custom_page_templates_init() {
  remove_action( current_filter(), __FUNCTION__ );
  if ( is_admin() && get_current_screen()->post_type === \'page\' ) {
    $templates = get_custom_page_templates(); // the function above
    if ( ! empty( $templates ) )  {
      set_custom_page_templates( $templates );
    }
  }
}

function custom_page_templates_init_post() {
  remove_action( current_filter(), __FUNCTION__ );
  $method = filter_input( INPUT_SERVER, \'REQUEST_METHOD\', FILTER_SANITIZE_STRING );
  if ( empty( $method ) || strtoupper( $method ) !== \'POST\' ) return;
  if ( get_current_screen()->post_type === \'page\' ) {
    custom_page_templates_init();
  }
}
我们必须做的最后一件事是set_custom_page_templates() 编辑缓存以包含模板的函数,确保合并由文件头定义的任何模板:

function set_custom_page_templates( $templates = array() ) {
  if ( ! is_array( $templates ) || empty( $templates ) ) return;
  $core = array_flip( (array) get_page_templates() ); // templates defined by file
  $data = array_filter( array_merge( $core, $templates ) );
  ksort( $data );
  $stylesheet = get_stylesheet();
  $hash = md5( get_theme_root( $stylesheet ) . \'/\' . $stylesheet );
  $persistently = apply_filters( \'wp_cache_themes_persistently\', false, \'WP_Theme\' );
  $exp = is_int( $persistently ) ? $persistently : 1800;
  wp_cache_set( \'page_templates-\' . $hash, $data, \'themes\', $exp );
}
运行此代码后,只需使用中使用的方法即可设置自定义模板get_custom_page_templates() 函数,这里我使用过滤器:

add_filter( \'custom_page_templates\', function( $now_templates ) {

  $templates = array(
    \'some-custom-page-template\' => \'Some Custom Page Template\',
    \'another-custom-page-template\' => \'Another Custom Page Template\' ,
  );

  return array_merge( $now_templates, $templates );

} );
你就完了。

SO网友:s_ha_dum

如果我理解你,你可以用template_include 钩例如:

add_filter( \'template_include\', \'phpless_template\');
function phpless_template( $template ) {  
  get_header();
  // some php
  get_footer();
  die;
}

SO网友:Marco Panichi

我向您建议一种更简单的解决方法:

在配置/功能/索引文件中定义配置变量$config_template = false; (*)

  • 创建一个文件夹“include”(可能您已经有了)
  • 将文件放在那里一些自定义页面模板。php和另一个自定义页面模板。在这些文件中,php只需为$config\\u模板指定一个值,然后需要使用的页面来呈现循环,例如:$config_template = \'some-custom-page\'; require( "../index.php" );
  • 在这个文件(index.php)中,您可以根据$config\\u template的值随心所欲地使用此方法,您没有强制执行WP的正常工作流(这从来都不是一个好主意),但您可以保持项目足够干净。

    (*)您可能已经在使用某些对象属性来管理配置。您将把$config\\u模板变量放在那里

  • 结束