如何从插件向页面模板列表添加选项?

时间:2012-02-13 作者:Jared

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

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

是否可以修改全局变量来执行此操作?

Edit:

根据@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;
    }

}

Edit 2:

这项功能似乎将在未来的更新中发布,我读了不少关于这方面的trac票证,并进行了一些讨论,但没有真正的答案(希望是3.4)。稍后将在此处列出trac票证URL。

Edit 3:

上面的代码可以工作,但是,目前我唯一的问题是,在编辑/添加新页面时,没有将模板添加到下拉列表中。我正在尝试一些事情,并将很快更新我的问题。

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

过滤器?有人吗

那里没有过滤器来帮助: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\' );
注意:这就是我不确定它是否会起作用的地方。

During plugin activation: 那么你应该style.css.php 在您的templates 文件夹这将允许您向文件中添加变量。然后,此变量将成为父主题。父主题应该是当前活动的主题。然后将活动主题更新到插件。

Drawback #2: 关于»外观«UI&hellip

Drawback #2: 这个技巧将成功避免子主题。您可以有一个父主题。没什么了。

SO网友:Adam

作为一个潜在解决方案的建议,您是否考虑过使用WordPress文件系统将页面模板文件从插件写入当前的活动主题目录?根据您对此过程的控制程度,您可以让插件在激活时写入文件,并在卸载时将其删除。或者,您可以使用表单从插件UI中动态创建页面模板文件,以传递某些值,例如页面模板名称,该名称将显示在编辑后屏幕的下拉框中。理论上,您还可以单击按钮从插件UI中删除页面模板,并为不同目的添加多个模板。在奥托的博客上有一篇关于使用文件系统的好文章。我现在没有与我的链接,但你可以搜索它。

我希望他们在下一个核心版本中通过挂钩的方式发布您打算做的事情。

SO网友:Matthew Boynes

我浏览了源代码,但令人震惊的是,似乎没有办法做到这一点!我的建议是添加第二个带有主题覆盖/第二个主题下拉列表的元框。然后连接到此过滤器:

# wp-includes/theme.php line 751 in 3.3.1:
return apply_filters( "{$type}_template", locate_template( $templates ) );
如果主题文件已被覆盖,则返回该文件。当然,如果这是您想要的帖子,您只需要添加\\u过滤器。

如果你想变得别致,你可以废弃原来的盒子并重新创建它(当然是通过过滤器,而不是修改核心代码)。

我还建议添加trac ticket 请求该功能(如果还没有该功能)。

SO网友:gruvii

我在过去通过删除默认页面模板元盒,然后添加您自己的元盒来实现这一点。我让新的metabox使用内置的get\\u page\\u模板,然后添加了编程所需的其他模板。在保存时,它可以像wordpress一样更新页面模板。

SO网友:William Gu

检查挂钩theme_page_templates, 由使用get_page_templates 函数,自4.4中更新的3.9以来添加的过滤器:

apply_filters( \'theme_page_templates\', $page_templates, $this, $post );

SO网友:Douglas Lovell

使用DuckDuckGo的搜索结果add a wordpress page template 在wpmu上为我找到了答案。标题为的组织页面WordPress Custom Page Template Tutorial.

本质上,在主题目录wp-content/themes/your-theme中,将现有页面模板复制到您选择的新php文件名。编辑新文件,注意更改文件顶部注释中的magic“Template Name:”属性值。

这就是全部。有可能这是一个功能,张贴日期的问题。我正在将WP 3.5与twenty\\u-eleven主题结合使用。

也有可能有更简洁的方式来扩展主题。这样的编辑可能会被主题更新覆盖。我有罪。

结束

相关推荐