将项目添加到页面编辑屏幕上的页面模板下拉菜单

时间:2015-08-07 作者:Sisir

我正在用MVC方法开发一个WP主题。它只有index.php, functions.phpstyles.css 在父目录上。因此,我不想在其上放置页面模板,而是希望通过视图类以编程方式提供它们,而编辑屏幕的功能保持不变。

用户需要在编辑屏幕上选择页面模板选项。如何将项目成功添加到模板下拉列表中?

我试图勾搭上theme_page_templates 滤器

Example code:

add_filter( \'theme_page_templates\', function($templates){

    $templates[\'my-page-template.php\'] = "My Page Template";

    return $templates;

});
由于使用了array_intersect_assoc() 在筛选的数组上,删除添加的页面模板项。我不明白为什么要使用这个函数。似乎您只能从列表中删除页面模板,但无法使用给定的筛选器添加新模板。

还有别的办法吗?

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

我想我会给你提供另一种方法。它也有点黑客化,但它是通用的,允许您简单地注册要使用的文件名和标签,如下所示:

if ( class_exists( \'WPSE_196995_Page_Templates\' ) ) {   
    WPSE_196995_Page_Templates::register_page_template(
        \'My Page Template\',
        \'my-page-template.php\'
    );
}
您可以将上述代码添加到主题的functions.php 文件

为了使以上内容能够实际工作,我实现了一个自包含的类,可以用作插件,也可以复制到functions.php:

<?php   
/**
 * Plugin Name: WPSE 196995 Page Templates
 *
 * Class WPSE_196995_Page_Templates
 *
 * Allows registering page templates via code.
 */
class WPSE_196995_Page_Templates {

    static $registered_templates = array();

    static function on_load() {

        /**
         * Add registered page templates to \'page_template\' cache.
         * @note This hook is called just before page templates are loaded
         */
        add_action( \'default_page_template_title\', array( __CLASS__, \'_default_page_template_title\' ) );
    }

    /**
     * Register page templates
     *
     * @param string $label
     * @param string $filename
     */
    static function register_page_template( $label, $filename ) {

        self::$registered_templates[ $filename ] = $label;

    }

    /**
     * Add registered page templates to \'page_template\' cache.
     *
     * @param string $title
     *
     * @return string mixed
     */
    static function _default_page_template_title( $title ) {

        /**
         * @var WP_Theme $theme
         */
        $theme = wp_get_theme();

        /**
         * Access the cache the hard way since WP_Theme makes almost everything private
         */
        $cache_hash = md5( $theme->get_stylesheet_directory() );

        /**
         * Get the page templates as the \'page_templates\' cache will already be primed
         */
        $page_templates = wp_cache_get( $key = "page_templates-{$cache_hash}", $group = \'themes\' );

        /**
         * Add in registered page templates
         */
        $page_templates += self::$registered_templates;

        /**
         * Now update the cache, which is what the get_page_templates() uses.
         */
        wp_cache_set( $key, $page_templates, $group, 1800 );

        /**
         * We are using this hook as if it were an action.
         * So do not modify $title, just return it.
         */
        return $title;

    }

}
WPSE_196995_Page_Templates::on_load();
该类提供register_page_template() 方法,但要实际添加页面模板,它会更新\'page_templates\' 在对象缓存中设置。

因为WordPress制作了WP_Themeprivate, 但幸运的是,他们使用了可公开访问的WordPress对象缓存来存储这些值。并通过更新\'default_page_template_title\' 钩子,在生成页面模板下拉列表并发送到浏览器之前调用,我们可以让WordPress根据需要显示您的页面模板。

SO网友:Sisir

使用一个丑陋的黑客:-/。如果稍后使用jQuery,我将更新答案。解决方案仍然需要有模板文件,但模板文件的代码从index.php

我做了一个新的template/ 目录并将所有页面模板放在那里使用template_include 要重定向到的筛选器index.php

代码

Blank Page Template Example

<?php
/*
Template Name: No Sidebar
 *
 * */

Filter

add_filter( \'template_include\', function ($template ) {

    if ( !is_page_template()  )
        return $template;

    return locate_template( array( \'index.php\' ), true );

}, 99);
I have created a trac ticket 允许通过过滤器添加模板。

结束