Como mover arquivos de modelos de páginas como page- {slug} .php para um subdiretório?

8

Eu quero mover arquivos de modelo de página como page-{slug}.php para um subdiretório dentro do meu tema, de forma que o WordPress os reconheça automaticamente. Se os modelos de página do referido formulário não existirem no subdiretório, o WordPress deve retornar às regras de carregamento de modelos padrão. Como posso conseguir isso?

Nota-1: Esta pergunta e respostas correspondentes são mais genéricas para modelos de página e link menciona template-parts/page , o que não é a mesma coisa.

Observação 2: eu tenho vários arquivos de modelo de página page-{slug}.php , por isso quero movê-los para o subdiretório para uma organização de arquivos mais organizada.

    
por chevallier 22.08.2018 / 14:43

1 resposta

10

Como os modelos de página são carregados:

De acordo com o padrão Hierarquia de modelos do WordPress , uma solicitação page carrega um modelo com base na prioridade e nos nomes indicados abaixo:

  1. Custom Page Template : se definido no editor de páginas.
  2. page-{slug}.php
  3. page-{url-encoded-slug}.php : apenas para caracteres multibyte.
  4. page-{id}.php
  5. page.php
  6. singular.php
  7. index.php

Entre esses, singular.php e index.php não são não , na verdade, modelos de página. singular.php é o modelo de fallback para qualquer tipo de postagem e index.php é o modelo de fallback definitivo para qualquer coisa que um modelo do WordPress deva carregar. Então, os primeiros cinco são modelos de páginas.

Como injetar arquivos de modelo de um subdiretório na hierarquia:

A função principal do WordPress get_page_template() gera o array de hierarquia de modelos page necessário e antes de decidir exatamente qual arquivo de modelo carregar da hierarquia, o WordPress dispara o gancho de filtro page_template_hierarchy . Portanto, a melhor maneira de adicionar um subdiretório, onde o WordPress irá procurar por page-{slug}.php templates automaticamente, é usar esse filtro e injetar os nomes de arquivos apropriados em relação a esse subdiretório dentro da matriz de hierarquia de modelos de páginas.

  

Observação: o gancho de filtro original é um gancho de filtro dinâmico definido como {$type}_template_hierarchy , que está localizado no arquivo wp-includes/template.php . Portanto, quando o $type for page , o gancho do filtro se tornará page_template_hierarchy .

Agora, para o nosso propósito, vamos injetar o nome do arquivo sub-directory/page-{slug}.php logo antes de page-{slug}.php na matriz da hierarquia de modelos passar para a função de retorno de chamada de hooks. Dessa forma, o WordPress carregará sub-directory/page-{slug}.php arquivo, se existir, caso contrário, seguirá a hierarquia de carregamento de modelo de página normal. Obviamente, para manter a consistência, ainda daremos a Custom Page Template uma prioridade maior em comparação ao nosso arquivo sub-directory/page-{slug}.php . Assim, a hierarquia modificada de modelos de páginas se tornará:

  1. Custom Page Template : se definido no editor de páginas.
  2. sub-directory/page-{slug}.php
  3. sub-directory/page-{url-encoded-slug}.php : apenas para caracteres multibyte.
  4. page-{slug}.php
  5. page-{url-encoded-slug}.php : apenas para caracteres multibyte.
  6. page-{id}.php
  7. page.php

Amostra functions.php CODE:

Se você planeja fazer essa alteração apenas em um único tema, use o seguinte CODE no arquivo functions.php do seu tema ativo:

// defining the sub-directory so that it can be easily accessed from elsewhere as well.
define( 'WPSE_PAGE_TEMPLATE_SUB_DIR', 'page-templates' );

function wpse312159_page_template_add_subdir( $templates = array() ) {
    // Generally this doesn't happen, unless another plugin / theme does modifications
    // of their own. In that case, it's better not to mess with it again with our code.
    if( empty( $templates ) || ! is_array( $templates ) || count( $templates ) < 3 )
        return $templates;

    $page_tpl_idx = 0;
    if( $templates[0] === get_page_template_slug() ) {
        // if there is custom template, then our page-{slug}.php template is at the next index 
        $page_tpl_idx = 1;
    }

    $page_tpls = array( WPSE_PAGE_TEMPLATE_SUB_DIR . '/' . $templates[$page_tpl_idx] );

    // As of WordPress 4.7, the URL decoded page-{$slug}.php template file is included in the
    // page template hierarchy just before the URL encoded page-{$slug}.php template file.
    // Also, WordPress always keeps the page id different from page slug. So page-{slug}.php will
    // always be different from page-{id}.php, even if you try to input the {id} as {slug}.
    // So this check will work for WordPress versions prior to 4.7 as well.
    if( $templates[$page_tpl_idx] === urldecode( $templates[$page_tpl_idx + 1] ) ) {
        $page_tpls[] = WPSE_PAGE_TEMPLATE_SUB_DIR . '/' . $templates[$page_tpl_idx + 1];
    }

    array_splice( $templates, $page_tpl_idx, 0, $page_tpls );

    return $templates;
}
add_filter( 'page_template_hierarchy', 'wpse312159_page_template_add_subdir' );

Exemplo de plug-in:

Se você deseja seguir a mesma organização de arquivos de modelo em vários temas, é melhor manter esse recurso separado do tema. Nesse caso, em vez de modificar o arquivo functions.php do tema com o CÓDIGO de amostra acima, você precisará criar um plug-in simples com o mesmo CÓDIGO de amostra.

Salve o seguinte CÓDIGO com um nome de arquivo, por exemplo page-slug-template-subdir.php no seu diretório plugins do WordPress:

<?php
/*
Plugin Name:  WPSE Page Template page-slug.php to Sub Directory
Plugin URI:   https://wordpress.stackexchange.com/a/312159/110572
Description:  Page Template with page-{slug}.php to a Sub Directory
Version:      1.0.0
Author:       Fayaz Ahmed
Author URI:   https://www.fayazmiraz.com/
*/

// defining the sub-directory so that it can be easily accessed from elsewhere as well.
define( 'WPSE_PAGE_TEMPLATE_SUB_DIR', 'page-templates' );

function wpse312159_page_template_add_subdir( $templates = array() ) {
    // Generally this doesn't happen, unless another plugin / theme does modifications
    // of their own. In that case, it's better not to mess with it again with our code.
    if( empty( $templates ) || ! is_array( $templates ) || count( $templates ) < 3 )
        return $templates;

    $page_tpl_idx = 0;
    if( $templates[0] === get_page_template_slug() ) {
        // if there is custom template, then our page-{slug}.php template is at the next index 
        $page_tpl_idx = 1;
    }

    $page_tpls = array( WPSE_PAGE_TEMPLATE_SUB_DIR . '/' . $templates[$page_tpl_idx] );
                                                                                  uded in the
    // page template hierarchy just before the URL encoded page-{$slug}.php template file.
    // Also, WordPress always keeps the page id different from page slug. So page-{slug}.php will
    // always be different from page-{id}.php, even if you try to input the {id} as {slug}.
    // So this check will work for WordPress versions prior to 4.7 as well.
    if( $templates[$page_tpl_idx] === urldecode( $templates[$page_tpl_idx + 1] ) ) {
        $page_tpls[] = WPSE_PAGE_TEMPLATE_SUB_DIR . '/' . $templates[$page_tpl_idx + 1];
    }

    array_splice( $templates, $page_tpl_idx, 0, $page_tpls );

    return $templates;
}
// the original filter hook is {$type}_template_hierarchy,
// wihch is located in wp-includes/template.php file
add_filter( 'page_template_hierarchy', 'wpse312159_page_template_add_subdir' );

Uso:

  

Com qualquer um dos códigos acima, o WordPress reconhecerá page-{slug}.php arquivos de modelo no diretório page-templates do seu tema automaticamente.

     

Por exemplo, você tem uma página about . Portanto, se ele não tiver um custom page template definido no editor, o WordPress procurará THEME/page-templates/page-about.php modelo e, se isso não existir, o WordPress procurará THEME/page-about.php modelo e assim por diante (ou seja, a hierarquia de modelos de páginas padrão).

    
por Fayaz 27.08.2018 / 15:04