Como posso adicionar uma opção à lista de modelos de página em um plug-in?

10

Estive procurando nas últimas duas horas uma maneira de criar um modelo de página personalizado a partir de um plug-in, mas ainda não tive sorte.

O que estou especificamente tentando fazer é adicionar uma opção à lista de modelos de página disponíveis ao editar uma página e não usar outro método comoif( is_page( 'page-slug' ) ) { /* etc */ }

Existe uma variável global que eu possa modificar para fazer isso?

Editar:

Atualmente, estou usando esse código, com base no link que m0r7if3r me deu em um comentário, o problema é que ele executará essa função ao visualizar a página, mas não ao editar a página (para preencher a lista suspensa com os modelos de página) :

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;
    }

}

Edição 2:

Parece que essa funcionalidade será lançada em uma atualização futura, li alguns trac tickets sobre isso e houve algumas discussões, mas nenhuma resposta real (esperando pelo 3.4). Irá listar os URLs dos tickets trac aqui daqui a pouco.

Edição 3:

O código acima funciona, MAS, o único problema que estou tendo neste momento é que não há nenhum modelo sendo adicionado à lista suspensa ao editar / adicionar uma nova página. Estou tentando algumas coisas e vou atualizar minha pergunta em breve.

Jared
fonte
2
Você já tentou algo parecido com isso ?
mor7ifer
@ m0r7if3r (Se você tentar isso, por favor deixe uma mensagem como trabalhou fora - Graças)
kaiser
@ Kaiser Eu tentei o código que ele recomendou, o único link que falta é obter a meta box para adicionar o modelo à lista suspensa (tanto quanto eu sei!).
Jared
@ Jared Veja esta resposta minha para uma pergunta semelhante e os tickets trac relacionados na parte inferior da a. Adicione seu código) Se ele não estiver sendo exibido em todas as páginas, você estará usando os ganchos errados para executar a instância. Quais ganchos você está usando?
Kaiser
@ kaiser Estou usando o page_templategancho, o código acima na minha edição é o que está sendo usado atualmente. Preciso usar o template_redirectgancho e adicionar o page_templatefiltro lá?
Jared

Respostas:

4

Filtros? Qualquer um?

Não filtro para ajudar: page_template_dropdown($template);é usado para criar a lista suspensa e não é filtrável.

Esgueirando-se para a matriz de modelos?

Para criar o conteúdo suspenso, a caixa meta principal é usada get_page_templates(). Por dentro, a função se parece com o seguinte:

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

Mas, ao examinar get_themes();, não há possibilidade de interceptar a lista de modelos. Além disso, temos o problema: não há chance de obter um modelo fora do diretório de temas ...

... Fingindo um tema!

A teoria e suas desvantagens…

Você pode usar register_theme_directory()para adicionar um diretório de temas adicionais onde você pode colocar modelos. Portanto, o mais fácil seria registrar também o seu plugin como pasta de temas:

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

Nota: É aqui que não tenho certeza se funcionará .

Durante a ativação do plug-in: Em seguida, você deve colocar um style.css.phparquivo dentro da sua templatespasta. Isso permitiria adicionar variáveis ​​ao seu arquivo. Essa variável seria o tema principal. E o tema pai deve ser simplesmente o tema ativo no momento. Atualize seu tema ativo para o seu plug-in.

Desvantagem # 2: Sobre a interface do usuário »Aparência«… Talvez adicione uma nota de que este "Tema" não foi criado para ser usado como Tema real. Deixo o resto de »Evite ativar esse tema« até a sua imaginação. Enfim: Deveria funcionar.

Desvantagem # 2: Este truque evitará temas infantis com êxito. Você pode ter um tema principal. Nada mais.

kaiser
fonte
Portanto, estou supondo que não exista uma maneira real de usar modelos de página personalizados de qualquer tema inativo, correto? Eu poderia registrar um diretório de temas, mas os modelos não estão disponíveis para uso, a menos que esse tema esteja ativo.
Jared
11
Na verdade não. Simplesmente não deveria ser e, portanto, falta de núcleo. Você já tentou o link para o ipstenu acima? Eu já tentei seguir esse caminho, mas acabei em um caminho morto - com outra solução. A melhor aposta seria seguir os ingressos, pressionar e vinculá-los onde quer que esteja. : /
kaiser
2

Como sugestão para uma possível solução alternativa, você já pensou em usar o sistema de arquivos WordPress para gravar um arquivo de modelo de página do seu plug-in no diretório de temas ativo atual? Dependendo de quanto controle você deseja sobre esse processo, seu plug-in pode gravar o arquivo na ativação e removê-lo na desinstalação. Como alternativa, você pode criar arquivos de modelo de página dinamicamente a partir da interface do usuário do plug-in usando um formulário para passar determinados valores, como o nome do modelo da página, que deve aparecer na caixa suspensa da tela de pós-edição. Em teoria, você também pode remover o modelo da página da interface do usuário do plug-in com o clique de um botão e adicionar vários modelos para diferentes fins. Há um bom post sobre o uso do sistema de arquivos no blog de Otto. Eu não tenho o link comigo agora, mas você pode procurá-lo.

Espero que eles lançem o que você pretendia fazer como um gancho no próximo lançamento principal.

Adão
fonte
11
Eu tinha um método exatamente como este funcionando antes, mas tive muitos problemas quando tentei, porque quando um usuário alternava temas, ele não excluía o arquivo de modelo e, se copiava o tema ativo e o colocava em outro site , eles corriam o risco de enviar um arquivo de modelo personalizado que não funcionaria. Eu sei que existem várias soluções alternativas para isso, mas eu realmente quero que isso seja automático . +1 para a sugestão.
Jared
11
Oi Jared, eu também estava preocupado com o mesmo problema. A única solução que eu poderia pensar em estender ainda mais esse método alternativo seria fazer com que o plug-in na ativação recebesse o nome do tema atual; se um usuário desativar / alternar temas, você poderá excluir o arquivo de modelo desse tema e reescrevê-lo para o recém-ativado. tema. Dê uma olhada neste link, onde ele criou seus próprios ganchos de ativação / desativação para verificar temas. Com um pouco de código extra, acho que isso é possível.
Adam
Absolutamente, acho que pode funcionar. Vou tentar e postar os resultados na minha pergunta. Obrigado pelo link, isso ajuda!
Jared
1

Eu dei uma olhada na fonte e, surpreendentemente, não parece haver uma maneira de fazer isso! Meu hack sugerido seria adicionar uma segunda caixa meta com um menu suspenso substituição de tema / segundo tema. Em seguida, conecte-se a este filtro:

# wp-includes/theme.php line 751 in 3.3.1:
return apply_filters( "{$type}_template", locate_template( $templates ) );

para retornar seu arquivo de tema se ele tiver sido substituído. Obviamente, você gostaria de adicionar apenas add_filter se for a postagem que deseja.

Se você quiser ser chique, você pode descartar a caixa original e recriá-la (por meio de filtros, é claro, sem modificar o código principal).

Eu também sugeriria adicionar um ticket trac solicitando essa funcionalidade (se ainda não houver um).

Matthew Boynes
fonte
11
concordar com sugerir isso para trac.
helgatheviking
Ele já parece estar no trac: core.trac.wordpress.org/ticket/15803
Jared
11
Acabei de investigar isso em outro Q sobre modelos de tipo de postagem única . Você pode encontrar os ingressos Trac no final da resposta. Vamos torcer para o 3.4.
Kaiser
1

Eu fiz isso no passado removendo o metabox do modelo de página padrão e adicionando seu próprio metabox. Eu tive o novo metabox usar o get_page_templates embutido e, em seguida, adicionei os outros que eu precisava programaticamente. Em um save, ele pode atualizar o modelo da página, exatamente como o wordpress.

gruvii
fonte
Você se importaria de mostrar o código completo? Atualmente, é apenas um conceito aproximado. Obrigado.
kaiser
1

Confira o gancho theme_page_templates, usado pela get_page_templatesfunção, filtro adicionado desde 3.9 atualizado em 4.4:

apply_filters( 'theme_page_templates', $page_templates, $this, $post );
William Gu
fonte
explicado mais detalhadamente aqui: wordpress.stackexchange.com/a/255820/75495
cjbj
-2

Um resultado de pesquisa com o DuckDuckGo, adicionar um modelo de página do wordpress, apareceu na minha página wpmu.org, intitulada WordPress Custom Page Template Tutorial .

Essencialmente, dentro do diretório do tema, wp-content / themes / your-theme , copie um modelo de página existente para um novo nome de arquivo php de sua escolha. Edite o novo arquivo, tendo o cuidado de alterar o valor mágico da propriedade "Nome do modelo:" no comentário na parte superior do arquivo.

Isso era tudo o que havia para fazer. É possível que esse seja um recurso que pós-data da pergunta. Estou usando o WP 3.5 com o tema twenty_eleven.

Também é possível que haja maneiras mais limpas de estender um tema. Edições como essa podem ser substituídas por atualizações de temas. Mea Culpa.

Douglas Lovell
fonte
Preciso de uma solução para adicionar o modelo à lista suspensa de um plug-in, não de um tema. :(
Jared