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

ThinkPHP 內容分頁實現:UEditor 分頁符解析與靜態路由配置

     編輯:PHP 相關知識

ThinkPHP 內容分頁實現:UEditor 分頁符解析與靜態路由配置

在 ThinkPHP 開發的 CMS 系統中,長文章分頁是常見需求。本文詳細說明如何配合 UEditor 的分頁符 _ueditor_page_break_tag_ 實現內容分割、頁碼生成、URL 美化與靜態快取路由配置。

一、後台編輯器配置分頁符

UEditor 預設分頁符為 _ueditor_page_break_tag_,可在 ueditor.config.js 自訂:

// ueditor.config.js
pageBreakTag: '_ueditor_page_break_tag_', // 預設值,建議保持
// 或自訂更短的標記
// pageBreakTag: '[pagebreak]',

二、控制器邏輯:分割內容與頁碼處理

<?php
namespace Home\Controller;
use Think\Controller;

class ArticleController extends Controller {
    public function detail($id, $p = 1) {
        $id = (int)$id;
        $p = max(1, (int)$p);
        
        $article = M('Article')->find($id);
        if (!$article) $this->error('文章不存在');
        
        // 1. 分割內容
        $pages = explode('_ueditor_page_break_tag_', $article['content']);
        $totalPages = count($pages);
        
        // 2. 邊界檢查
        if ($p > $totalPages) $p = $totalPages;
        
        // 3. 當前頁內容(陣列索引從 0 開始)
        $currentContent = $pages[$p - 1] ?? '';
        
        // 4. 生成分頁 HTML
        $pageHtml = $this->buildPageHtml($totalPages, $p, $id);
        
        $this->assign([
            'article' => $article,
            'content' => $currentContent,
            'pageHtml' => $pageHtml,
            'currentPage' => $p,
            'totalPages' => $totalPages,
        ]);
        $this->display();
    }
    
    private function buildPageHtml(int $total, int $current, int $id): string {
        if ($total <= 1) return '';
        
        // 當前 URL 基礎(去除舊的 p 參數)
        $url = U('Article/detail', ['id' => $id], '', true); // 獲取路由生成的 URL
        $parse = parse_url($url);
        $baseUrl = $parse['path'];
        $query = [];
        if (isset($parse['query'])) parse_str($parse['query'], $query);
        unset($query['p']);
        $queryStr = $query ? '?' . http_build_query($query) : '';
        
        $html = '';
        return $html;
    }
}

三、模板顯示

<!-- Article/detail.html -->
<article class="article-detail">
  <h1>{$article.title}</h1>
  <div class="meta">
    作者:{$article.author} | 發布:{$article.create_time|date='Y-m-d H:i'} | 分類:{$article.category_name}
  </div>
  
  <div class="content">
    {$content}  <!-- 當前頁內容 -->
  </div>
  
  <!-- 分頁導航 -->
  {$pageHtml}
  
  <!-- SEO:rel=prev/next -->
  <?php if ($currentPage > 1): ?>
    <link rel="prev" href="{:U('Article/detail', ['id'=>$article.id, 'p'=>$currentPage-1])}">
  <?php endif; ?>
  <?php if ($currentPage < $totalPages): ?>
    <link rel="next" href="{:U('Article/detail', ['id'=>$article.id, 'p'=>$currentPage+1])}">
  <?php endif; ?>
</article>

<style>
.article-pagination ul { display: flex; gap: 4px; list-style: none; padding: 10px 0; justify-content: center; }
.article-pagination a { padding: 6px 12px; border: 1px solid #ddd; border-radius: 3px; color: #333; text-decoration: none; }
.article-pagination a:hover { background: #f5f5f5; }
.article-pagination .active span { padding: 6px 12px; background: #337ab7; color: #fff; border-radius: 3px; }
.article-pagination .ellipsis { padding: 6px 8px; color: #999; }
</style>

四、靜態快取路由配置(關鍵步驟)

ThinkPHP 靜態快取預設不支援動態參數,需在配置中顯式聲明 p 參數:

<?php
// Application/Common/Conf/config.php
return [
    // ... 其他配置
    'HTML_CACHE_ON' => true,           // 開啟靜態快取
    'HTML_CACHE_TIME' => 3600,         // 快取秒數
    'HTML_FILE_SUFFIX' => '.shtml',    // 偽靜態後綴
    'HTML_CACHE_RULES' => [
        'Article:detail' => [
            '{:module}/{:controller}/{:action}_{id}_{p}', // 關鍵:加入 {p} 參數
            3600,
            'p' => ['p' => 1] // 預設值
        ],
        // 列表頁等其他規則...
    ],
];

生成的靜態檔案結構:

/Runtime/Html/Home/Article_detail_123_1.shtml   // 第 1 頁
/Runtime/Html/Home/Article_detail_123_2.shtml   // 第 2 頁
...

五、Nginx 靜態檔案直接服務配置

# nginx.conf
location / {
    # 嘗試直接服務靜態快取檔案
    try_files /Runtime/Html/$uri @thinkphp;
}

location @thinkphp {
    fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root/index.php;
    include fastcgi_params;
}

六、SEO 優化:rel=prev/next 與 Canonical

在模板 <head> 中動態輸出:


<?php if ($totalPages > 1): ?>
  <?php if ($currentPage == 1): ?>
    <link rel="canonical" href="{:U('Article/detail', ['id'=>$article.id], '', true)}">
  <?php else: ?>
    <link rel="canonical" href="{:U('Article/detail', ['id'=>$article.id, 'p'=>$currentPage], '', true)}">
  <?php endif; ?>
  <?php if ($currentPage > 1): ?>
    <link rel="prev" href="{:U('Article/detail', ['id'=>$article.id, 'p'=>$currentPage-1], '', true)}">
  <?php endif; ?>
  <?php if ($currentPage < $totalPages): ?>
    <link rel="next" href="{:U('Article/detail', ['id'=>$article.id, 'p'=>$currentPage+1], '', true)}">
  <?php endif; ?>
<?php endif; ?>

七、常見問題排查

問題原因解決
分頁連結點擊仍顯示第 1 頁內容靜態快取規則缺少 {p} 參數在 HTML_CACHE_RULES 中加入 _{p} 並設定預設值
UEditor 內容儲存的分頁符不生效編輯器配置與解析不一致確認 pageBreakTag 與 explode 參數完全一致
靜態檔案未生成目錄權限、快取開關、規則匹配檢查 Runtime/Html 可寫、HTML_CACHE_ON、控制器名匹配
頁碼過多顯示擁擠未做省略號處理參考 buildPageHtml 只顯示當前頁附近 ±2 頁

掌握這套流程,即可在 ThinkPHP 專案中實現 SEO 友好、支援靜態快取的文章分頁功能。

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