Получить ID страницы по шаблону

2 нояб. 2014 г., 10:01:58
Просмотры: 53.6K
Голосов: 26

Я хочу узнать, возможно ли получить ID страницы с определенным шаблоном. Возможно ли получить ID страницы, которая назначена шаблону "page-special.php"?

0
Все ответы на вопрос 6
7
54

Когда создаётся страница, назначенный ей шаблон сохраняется как пользовательское поле (метаданные) записи, аналогично другим пользовательским полям. Ключ meta_key имеет значение _wp_page_template, а значение meta_value будет содержать имя файла шаблона страницы.

Вы можете использовать функцию get_pages для получения всех страниц, у которых в meta_value указан определённый шаблон:

$pages = get_pages(array(
    'meta_key' => '_wp_page_template',
    'meta_value' => 'page-special.php'
));
foreach($pages as $page){
    echo $page->ID.'<br />';
}

ОБНОВЛЕНИЕ 23-07-2015

Если нужны только ID страниц, лучше использовать функцию get_posts, указав page как тип записи (post_type), а ids в качестве значения параметра fields. Это обеспечит более быстрый и оптимизированный запрос, так как из базы данных будет возвращён только столбец с ID записей, а не все данные страниц.

(Требуется PHP 5.4 и выше)

$args = [
    'post_type' => 'page',
    'fields' => 'ids',
    'nopaging' => true,
    'meta_key' => '_wp_page_template',
    'meta_value' => 'page-special.php'
];
$pages = get_posts( $args );
foreach ( $pages as $page ) 
    echo $page . '</br>';
2 нояб. 2014 г. 10:20:40
Комментарии

Привет, спасибо. Не слишком ли это "тяжело"? (перебор всех страниц)

user3800799 user3800799
2 нояб. 2014 г. 10:29:57

Зависит от количества страниц. На самом деле, я не знаю более быстрого нативного способа получить эти данные. Если у вас много страниц, я бы предложил использовать транзиенты для хранения этих данных и сбрасывать/удалять транзиент только при публикации новой страницы.

Pieter Goosen Pieter Goosen
2 нояб. 2014 г. 10:35:38

Всегда пожалуйста, рад был помочь. Удачи :-)

Pieter Goosen Pieter Goosen
2 нояб. 2014 г. 10:44:35

@user3800799 Я обновил пост, если вас интересует только получение идентификаторов и больше ничего

Pieter Goosen Pieter Goosen
23 июл. 2015 г. 13:47:58

Вы также можете использовать set_transient (https://codex.wordpress.org/Transients_API), если не хотите слишком часто обращаться к базе данных.

Chris Andersson Chris Andersson
19 мая 2016 г. 15:09:38

@ChrisAndersson Если у вас не сотни страниц, использование transient здесь будет практически бесполезным. Мой код выполняет только один сверхбыстрый запрос к базе данных, так как мы запрашиваем только ID записей, что значительно повышает производительность. Transients выполняют два запроса к базе при каждой загрузке страницы, хотя могут быть чуть быстрее. Transients полезны только для ресурсоемких операций

Pieter Goosen Pieter Goosen
19 мая 2016 г. 15:30:36

Спасибо, это именно то, что я искал :). У меня есть шаблон блога, который я подключаю в своей теме... Очень полезно получать ID страницы, назначенной шаблону блога, вместо того чтобы вводить его вручную каждый раз!

Jordan Carter Jordan Carter
15 июл. 2019 г. 22:49:15
Показать остальные 2 комментариев
0

Если ваш шаблон страницы находится во вложенной папке, например theme-folder/page-templates/page-template.php, то следующий запрос будет работать:

$page_details = get_pages( array(
 'post_type' => 'page',
 'meta_key' => '_wp_page_template',
 'hierarchical' => 0,
 'meta_value' => 'page-templates/page-template.php'
));

Приведенный выше код также отображает и дочерние страницы.

Спасибо

7 февр. 2018 г. 00:51:18
0

Вот полная функция, совместимая с WPML и Polylang. Автор: https://github.com/cyrale/

/**
* Поиск страницы с определённым шаблоном.
*
* @param string $template Имя файла шаблона.
* @param array  $args     (Опционально) Дополнительные параметры, аналогично get_posts().
* @param bool   $single   (Опционально) Возвращать одно значение или массив.
*
* @return Будет возвращён массив объектов WP_Post, если $single равен false. Если $single равен true, вернёт объект WP_Post при успешном поиске, иначе FALSE.
*/
if (!function_exists('get_page_by_template')) {
    function get_page_by_template($template, $args = array(), $single = true) {
        $pages_by_template = wp_cache_get('pages_by_template', 'cyrale');
        if (empty($pages_by_template) || !is_array($pages_by_template)) {
            $pages_by_template = array();
        }
        if (!isset($pages_by_template[$template])) {
            $args = wp_parse_args(array(
                'posts_per_page' => -1,
                'post_type'      => 'page',
                'suppress_filters'  => 0,
                'meta_query'     => array(
                    array(
                        'key'   => '_wp_page_template',
                        'value' => $template,
                    ),
                ),
            ), $args);
            $pages = get_posts($args);
            $pages_by_template[$template]= array(
                'single' => !empty($pages) && is_array($pages) ? reset($pages) : false,
                'pages'  => $pages,
            );
        }
        wp_cache_set('pages_by_template', $pages_by_template, 'cyrale');
        return $pages_by_template[$template][$single ? 'single' : 'pages'];
    }
}
12 нояб. 2019 г. 13:24:08
0

Ниже представлен более детализированный скрипт, который учитывает язык, если это необходимо. ОБРАТИТЕ ВНИМАНИЕ, что он предполагает использование Polylang, а не WPML.

function get_post_id_by_template($template,$lang_slug = null){
  global $wpdb;
  $wh = ($lang_slug) ? " AND t.slug = %s" : "";

  $query = $wpdb->prepare(
    "SELECT DISTINCT p.ID
    FROM $wpdb->posts p
    INNER JOIN $wpdb->postmeta meta ON meta.post_id = p.ID
    INNER JOIN $wpdb->term_relationships tr ON meta.post_id = tr.object_id
    INNER JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
    INNER JOIN $wpdb->terms t ON tt.term_id = t.term_id
    WHERE p.post_status = 'publish' AND meta.meta_key = %s AND meta.meta_value = %s" . $wh,
    '_wp_page_template',
    $template,
    $lang_slug
  );

  $ids = $wpdb->get_results($query);

  if($ids && isset($ids[0])){
    $p = $ids[0];
    return $p->ID;
  } else {
    return false;
  }
}// get_post_id_by_template
20 авг. 2018 г. 15:52:49
2
function kavkaz_get_page($page_template_filename){
    // Получаем страницы с указанным шаблоном
    $pages = get_pages( array(
        'meta_key' => '_wp_page_template',
        'meta_value' => $page_template_filename
    ) );

    $url = null;
    
    // Если страница найдена, получаем её URL
    if(isset($pages[0])) {
        $url = $pages[0]->guid;
    }
    
    // Возвращаем экранированный URL
    return esc_url( $url );
}
25 мар. 2022 г. 16:05:17
Комментарии

Это выглядит примерно так же, как два верхних ответа, поиск через get_pages() по meta_key? Я также думаю, что ->guid неверен: он может быть URL, но это не гарантировано. Вместо этого я бы передал объект страницы (или просто ID) в get_permalink().

Rup Rup
25 мар. 2022 г. 18:23:12

Ваш ответ можно улучшить, добавив дополнительную подтверждающую информацию. Пожалуйста, [отредактируйте], чтобы добавить больше деталей, таких как ссылки или документация, чтобы другие могли подтвердить правильность вашего ответа. Вы можете найти больше информации о том, как писать хорошие ответы, в справочном центре.

User User
2 апр. 2022 г. 19:41:27
0

Вы можете напрямую запросить таблицу postmeta:

global $wpdb;
$template = 'page-special';
$sql = "select post_id from {$wpdb->postmeta} where meta_key = '{$template}.php'";
$pages = $wpdb->get_col($sql);
var_dump($pages);
10 июн. 2022 г. 16:27:50