开发一个儿童主题,如何禁用家长模板?

时间:2013-04-19 作者:alex

我正在基于twentyeleven开发一个简单的儿童主题。但我注意到,当您添加新页面时,twentyeleven有一个showcase和侧栏模板。如何从函数中禁用这些模板。php?我只想显示子主题中的模板

当做

3 个回复
SO网友:MikeSchinkel

正如@toscho提到的,这很棘手。但这是可行的。

基本上,您需要找到在生成模板下拉列表之前和之后调用的动作挂钩,并调用ob_start() 启动输出缓冲和ob_get_clean() 捕获缓冲的HTML。这个\'submitpage_box\'\'edit_page_form\' 钩子将分别对此起作用。

捕获缓冲HTML后,您需要获取子页面模板列表,不幸的是,这需要您从WordPress复制大量代码,因为core无法使代码可重用,从而仅获取子模板的页面模板列表。您可以在方法中找到所需的代码get_child_page_templates() 下面的代码几乎完全是WordPress核心所需代码的组合。

一旦有了这两个缓冲HTML,就需要获得删除<options>s来自<select> 这些模板不是子主题中的页面模板,但请确保包含\'default\' 选项您可以通过一对复杂的正则表达式来实现这一点preg_match()preg_match_all() 功能和aforeach() 循环,只将子主题模板的HTML添加到列表中,然后将它们合并回列表之前和之后的HTML<option>s

把这些都打包成我打过的电话Omit_Parent_Theme_Page_Templates 您可以将其放入主题functions.php 文件或包含在你正在构建的插件和viola中,父页面模板消失了。

这是我的Omit_Parent_Theme_Page_Templates 您需要的类:

<?php
class Omit_Parent_Theme_Page_Templates {
  function __construct() {
    add_action( \'submitpage_box\', array( $this, \'_submitpage_box\' ) );
    add_action( \'edit_page_form\', array( $this, \'_edit_page_form\' ) );
  }
  function _submitpage_box() {
    ob_start();
  }
  function _edit_page_form() {
    $html = ob_get_clean();
    $select_regex = \'<select\\s*name="page_template"\\s*id="page_template".*?>\';
    preg_match( "#^(.*{$select_regex})(.*?)(</select>.*)$#sm", $html, $outer_match );
    preg_match_all( "#(<option\\s*value=\'([^\']+)\'.*?>(.*?)</option>)#sm", $outer_match[2], $inner_matches, PREG_SET_ORDER );
    $child_page_templates = $this->_get_child_page_templates();    
    foreach( $inner_matches as $index => $matches )
      if ( isset( $child_page_templates[$matches[2]] ) )
        $child_page_templates[$matches[2]] = $inner_matches[$index][0];

    $html = $outer_match[1] . implode( "\\n", $child_page_templates ). $outer_match[3];
    echo $html;
  }
  private function _get_child_page_templates() {
    $child_page_templates = array( \'default\' => true );
    $files = wp_get_theme()->get_files( \'php\', 1 );
    foreach ( $files as $file => $full_path ) {
      if ( ! preg_match( \'|[^]]Template Name:(.*)$|mi\', file_get_contents( $full_path ), $header ) )
        continue;
      $child_page_templates[ $file ] = true;
    }
    return $child_page_templates;
  }

}
new Omit_Parent_Theme_Page_Templates();
因为WordPress没有为您想要的内容提供挂钩,所以这段代码比我们想要的要复杂得多。它使用了一种技术—修改输出缓冲区中捕获的HTML—通常是;黑客"Eid 或name 的属性<select> 或者从根本上改变页面模板的工作方式,这两者都不太可能。

当然,如果其他插件决定也使用相同的技术修改页面模板,但方式不兼容,那么该插件可能会破坏此代码,反之亦然。

但我怀疑这一切都太可能了,如果你在自己的网站上使用,我一点也不担心,但是我会稍微担心在一个广泛分布的插件中发布代码,但只会稍微担心一点。:)

更新:

啊,真见鬼。决定将其转换为插件并在WordPress插件库中发布,请单击here 访问它。我想我还没有担心到不发表它的地步

SO网友:andrezrv

从3.9开始,您可以使用theme_page_templates 滤器

您只需要使用以下内容:

add_filter( \'theme_page_templates\', \'my_remove_page_template\' );
function my_remove_page_template( $pages_templates ) {
    unset( $pages_templates[\'onecolumn-page.php\'] );
    return $pages_templates;
}
进一步阅读:

SO网友:Robbert

要生成下拉列表,WordPress调用page_template_dropdown(), 哪个呼叫get_page_templates(), (至少从WP 3.4开始)调用wp_get_theme()->get_page_templates() (即。WP:Theme::get_page_templates() 对于活动主题)。

后一种方法循环遍历实际主题.php 文件以查找具有Template Name: 标头并缓存结果。到目前为止,在任何一点都没有提供任何操作或过滤器。

作为Mike回答的替代方案,我们可以修改缓存。与正则表达式相比,它对输出的处理不那么刻薄,但仍然刻薄。让我们把它挂在admin_head-post.php 操作,因此它仅在显示post editor时运行。

在模板下面的示例中page-home.php 从列表中删除。

add_action("admin_head-post.php", "my_admin_head_post");

function my_admin_head_post() {
    // Run template fetching once so the template list is cached.
    $templates = wp_get_theme()->get_page_templates();

    // Generate cache hash, just like WP_Theme::__construct() does.
    $cache_hash = md5(WP_CONTENT_DIR."/themes/".get_stylesheet());
    $cache_key  = "page_templates-".$cache_hash;

    // Remove unwanted templates from the list and save changes.
    unset($templates[\'page-home.php\']);
    wp_cache_replace($cache_key, $templates, "themes", 1800);
}
对于您的特定问题,如果要从列表中删除父主题的模板,幸运的是有一个公共方法WP_Theme::parent() 将主题的父级作为另一个WP_Theme 对象以下(未测试的)代码应该可以做到这一点:

function my_admin_head_post() {
    $theme  = wp_get_theme();
    $parent = $theme->parent();

    if(!is_a($parent, "WP_Theme"))
        return;

    $templates        = $theme->get_page_templates();
    $parent_templates = $parent->get_page_templates();

    $cache_hash = md5(WP_CONTENT_DIR."/themes/".get_stylesheet());
    $cache_key  = "page_templates-".$cache_hash;

    foreach($templates as $id => $template) {
        if(isset($parent_templates[$id]))
            unset($templates[$id]);
    }

    wp_cache_replace($cache_key, $templates, "themes", 1800);
}
Note: 由于无法再从下拉列表中选择已删除的模板,因此更新/发布以前使用该模板的现有页面将重置该页面的模板。

结束

相关推荐