问题描述

过去几个小时,我一直在寻找一种从插件中创建自定义页面模板的方法,但还没有运行。

我特别想做的是在编辑页面时向可用页面模板列表添加一个选项,而不是使用其他类似 if( is_page( 'page-slug' ) ) { /* etc */ }的方法

是否有全局变量我可以修改这样做?

编辑:

我正在使用这个代码,基于链接 @ m0r7if3r 给了我一个评论,问题是它会在查看页面时运行此功能,但在编辑页面时不会 (使用页面模板填充下拉列表) :

class JW_SiteGrader {

    private static $instance;

    private function __construct() {


        add_action( 'template_redirect', array( &$this, 'sitegrader_template_redirect' ), 20 );

    }

    public static function getInstance() {

        // Return the class data in a Singleton fashion
        if (self::$instance == null)
            self::$instance = new JW_SiteGrader();
        return self::$instance;

    }

    public function sitegrader_template_redirect() {

        add_filter( 'page_template', array( &$this, 'sitegrader_page_template' ), 10, 1 );

    }

    public function locate_plugin_template( $template_names, $load = false, $require_once = true ) {

        if ( !is_array( $template_names ) )
            return '';

        $located = '';

        $this_plugin_dir = WP_PLUGIN_DIR . '/' . str_replace( basename( __FILE__ ), '', plugin_basename( __FILE__ ) );

        foreach ( $template_names as $template_name ) {

            if ( !$template_name )
                continue;

            if ( file_exists( STYLESHEETPATH . '/' . $template_name ) ) {

                $located = STYLESHEETPATH . '/' . $template_name;
                break;

            } else if ( file_exists( TEMPLATEPATH . '/' . $template_name ) ) {

                $located = TEMPLATEPATH . '/' . $template_name;
                break;

            } else if ( file_exists( $this_plugin_dir .  $template_name ) ) {

                $located =  $this_plugin_dir . $template_name;
                break;

            }

        }

        if ( $load && '' != $located )
            load_template( $located, $require_once );

        return $located;
    }

    public function sitegrader_page_template( $template ) {

        $object = get_queried_object();

        if ( 'page' == $object->post_type ) {

            // New
            $templates[] = "page-sitegrader.php";
            // Like in core
            $templates[] = "page-{$object->post_type}.php";
            $templates[] = "page.php";

            return locate_template( $templates );

        }

        // return apply_filters('page_template', $template);
        return $template;
    }

}

编辑 2:

看来这个功能将在未来的更新中发布,我读了很多关于这个的 trac 门票,并且有一些讨论,但没有真正的答案 (希望 3.4) 。将列出 trac 门票网址在这里。

编辑 3:

上面的代码工作,但是,我在这一点上唯一的问题是编辑/添加新页面时没有模板添加到下拉列表中。我正在尝试几件事情,并会尽快更新我的问题。

最佳解决方案

过滤器?任何人?

没有帮助的过滤器:page_template_dropdown($template); 用于构建下拉列表,它不可过滤。

潜入模板阵列?

要构建下拉列表的内容,核心元框使用 get_page_templates()。从里面看,功能如下所示:

$themes = get_themes();
$theme = get_current_theme();
$templates = $themes[$theme]['Template Files'];

但是当查看 get_themes(); 时,那么接缝不可能拦截模板列表。更多的我们有问题,没有机会从主题目录外部获取模板…

伪造主题!

理论和它的缺点…

您可以使用 register_theme_directory()添加一个附加的主题目录,您可以在其中放置模板。所以最简单的事情就是将你的插件注册为主题文件夹:

// Register during init hook:
register_theme_directory( plugin_dir_path( __FILE__ ).'templates' );

注意:这是我不确定它是否可以工作的地方。

插件激活期间:您应该将 style.css.php 文件放在 templates 文件夹中。这将允许您添加变量到您的文件。这个变量将是父主题。父主题应该是目前活跃的主题。然后将您的活动主题更新为您的插件。

缺点#2:关于» 外观 «UI … 也许添加一个注释,这个”Theme” 不是用作实际的主题。我离开其余的» 避免激活这个主题 «填充你的想象力。无论如何:它应该工作。

缺点#2:这个技巧将成功避免儿童主题。您可以拥有一个父主题。而已。

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。