首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

WordPress 透過頁面模板獲取頁面 ID:核心原理與實戰函數

     編輯:PHP 綜合知識

WordPress 使用自訂欄位 _wp_page_template 記錄頁面所用模板。本文解析核心機制,提供透過模板檔案名稱反查頁面 ID 的實戰函數,解決「動態獲取特定功能頁面連結」的常見需求。

核心機制:_wp_page_template 自訂欄位

模板類型 _wp_page_template 值 說明
預設模板 (page.php)default若從未更改模板,此欄位不存在
主題根目錄模板page-login.php檔案名稱,不含路徑
子目錄模板templates/page-login.php含相對路徑
區塊主題模板wp:template-slug區塊編輯器模板

關鍵點:欄位名以下劃線開頭 → 屬於「隱藏自訂欄位」,後台 UI 不顯示。

實戰函數:透過模板名稱獲取頁面 ID

/**
 * 根據頁面模板檔案名稱獲取發布狀態的頁面 ID
 * @param string $template 模板檔案名稱 (如 'page-login.php', 'templates/contact.php')
 * @return int|false 頁面 ID 或 false
 */
function get_page_id_from_template(string $template) {
    global $wpdb;
    
    $page_id = $wpdb->get_var($wpdb->prepare("
        SELECT pm.post_id 
        FROM {$wpdb->postmeta} pm
        JOIN {$wpdb->posts} p ON p.ID = pm.post_id
        WHERE pm.meta_key = '_wp_page_template'
        AND pm.meta_value = %s
        AND p.post_status = 'publish'
        AND p.post_type = 'page'
        LIMIT 1
    ", $template));
    
    return $page_id ? (int) $page_id : false;
}

使用場景與範例

1. 動態生成登入頁連結

$login_page_id = get_page_id_from_template('page-login.php');
if ($login_page_id) {
    echo '會員登入';
} else {
    echo '會員登入'; // 回退預設
}

2. 主題選項頁面綁定

// Customizer 設定
$wp_customize->add_setting('contact_page_template', [
    'default' => 'page-contact.php',
]);
$wp_customize->add_control('contact_page_template', [
    'label'   => '聯絡頁面模板',
    'type'    => 'select',
    'choices' => [
        'page-contact.php'   => '聯絡頁面 v1',
        'templates/contact2.php' => '聯絡頁面 v2',
    ],
]);

// 前台使用
$contact_template = get_theme_mod('contact_page_template', 'page-contact.php');
$contact_page_id = get_page_id_from_template($contact_template);
$contact_url = $contact_page_id ? get_permalink($contact_page_id) : home_url('/contact/');

3. 多語言站點模板綁定

// Polylang / WPML 相容:各語言建立對應模板頁面
$templates = [
    'en' => 'page-contact-en.php',
    'zh' => 'page-contact-zh.php',
    'ja' => 'page-contact-ja.php',
];
$current_lang = pll_current_language() ?? 'en';
$page_id = get_page_id_from_template($templates[$current_lang] ?? $templates['en']);

為什麼不用頁面標題/別名查詢?

方法 缺點
標題查詢 客戶可能修改標題、重複標題、多語言標題不同
別名查詢 客戶可能修改別名、別名衝突、需強制指定
ID 硬編碼 環境遷移 (開發/測試/生產) ID 不一致
模板查詢 模板檔案由開發者控制、部署一致、語意明確

進階:獲取所有使用特定模板的頁面

function get_page_ids_from_template(string $template): array {
    global $wpdb;
    return $wpdb->get_col($wpdb->prepare("
        SELECT pm.post_id 
        FROM {$wpdb->postmeta} pm
        JOIN {$wpdb->posts} p ON p.ID = pm.post_id
        WHERE pm.meta_key = '_wp_page_template'
        AND pm.meta_value = %s
        AND p.post_status = 'publish'
        AND p.post_type = 'page'
    ", $template));
}

// 使用:取得所有使用 'page-landing.php' 的頁面
$landing_pages = get_page_ids_from_template('page-landing.php');
foreach ($landing_pages as $page_id) {
    // 處理...
}

區塊主題 (FSE) 相容性

WordPress 5.9+ 區塊主題使用 wp:template-{slug} 格式:

// 區塊主題模板查詢
$block_template_slug = 'contact-form'; // 區塊編輯器中建立的模板 slug
$page_id = get_page_id_from_template('wp:template-' . $block_template_slug);

效能優化:快取查詢結果

function get_page_id_from_template_cached(string $template) {
    $cache_key = 'page_id_from_template_' . md5($template);
    $page_id = wp_cache_get($cache_key);
    
    if ($page_id === false) {
        $page_id = get_page_id_from_template($template);
        wp_cache_set($cache_key, $page_id, 'template_queries', HOUR_IN_SECONDS);
    }
    
    return $page_id;
}

總結

  • 核心鍵值:_wp_page_template 自訂欄位存儲模板關聯
  • 查詢邏輯:postmeta JOIN posts 過濾 post_status=publish + post_type=page
  • 優於別名/標題:開發者控制、部署一致、語意穩定
  • 適用場景:動態選單、主題選項綁定、多語言模板、功能頁面連結

掌握這個技巧,讓主題開發不再依賴脆弱的頁面 ID 或別名,實現真正可攜帶、可維護的模板綁定架構。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved