Adicionando itens à lista suspensa de modelos de página na tela Editar página

4

Estou desenvolvendo um tema WP com abordagem MVC. Só tem index.php , functions.php e styles.css no diretório pai. Portanto, não quero colocar modelos de página nele, em vez disso, quero fornecê-los programaticamente a partir de classes de exibição, enquanto a funcionalidade da tela de edição permanece a mesma.

Os usuários precisam ter a opção de seleção de modelos de página na tela de edição. Como faço para adicionar itens ao modelo suspenso?

Eu tentei entrar em theme_page_templates filtro.

Exemplo de código:

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

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

    return $templates;

});

Isso não funciona devido ao uso de array_intersect_assoc() no filtro matriz, que remove o item de modelo de página adicionado. Eu não entendo porque esta função é usada. Parece que você só pode remover o modelo de página da lista, mas não pode adicionar um novo usando o filtro fornecido.

Existe algum outro caminho?

    
por Sisir 07.08.2015 / 18:00

2 respostas

5

Eu pensei em fornecer uma outra abordagem. Também é um pouco hackish, mas é de propósito geral e permite que você simplesmente registre o nome do arquivo e o rótulo que deseja usar, assim:

if ( class_exists( 'WPSE_196995_Page_Templates' ) ) {   
    WPSE_196995_Page_Templates::register_page_template(
        'My Page Template',
        'my-page-template.php'
    );
}

Você pode adicionar o código acima ao arquivo functions.php do seu tema.

Para permitir que o trabalho acima funcione, implementei uma classe independente que poderia ser usada como um plug-in ou apenas copiada para 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();

A classe fornece o método register_page_template() , é claro, mas para realmente incluir o modelo de página, ele atualiza o valor de 'page_templates' definido no cache de objetos.

É um pouco hacky porque o WordPress fez a maioria dos métodos e propriedades do WP_Theme class private , mas felizmente eles usaram o cache de objetos do WordPress publicamente acessível para armazenar os valores. E atualizando o cache de objetos no 'default_page_template_title' hook, que é chamado logo antes de o menu suspenso de modelos de página ser gerado e enviado ao navegador, podemos fazer com que o WordPress exiba seu (s) modelo (s) de página, conforme desejado.

    
por MikeSchinkel 08.08.2015 / 18:33
1

Corri com um hack feio: - /. Vou atualizar a resposta Se eu for com o jQuery mais tarde. A solução ainda requer arquivos de modelo, mas o código para o arquivo de modelo é carregado a partir do index.php

  1. Eu fiz um novo diretório template/ e coloquei todo o modelo de página lá.
  2. Todos os modelos de página estão em branco. Precisamos apenas que eles apareçam no menu suspenso.
  3. Use o filtro template_include para redirecionar para index.php

Código

Exemplo de modelo de página em branco

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

Filtro

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

    if ( !is_page_template()  )
        return $template;

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

}, 99);

Eu criei um ticket do trac para permitir a adição de modelos via filtro.

    
por Sisir 08.08.2015 / 10:16