如何用Laravel结合DOMDocument创建数据库驱动的目录页面?
在Laravel中使用DOMDocument生成数据库驱动的目录页面
1. 准备数据库与模型
首先创建存储章节数据的数据库表,用于支撑目录和页面内容:
生成迁移文件
php artisan make:migration create_sections_table
编写迁移字段
在生成的迁移文件中定义章节表结构:
public function up() { Schema::create('sections', function (Blueprint $table) { $table->id(); $table->string('title'); // 章节标题 $table->text('content'); // 章节内容 $table->string('slug')->unique(); // 锚点用的唯一标识 $table->integer('order')->default(0); // 章节排序顺序 $table->timestamps(); }); }
执行迁移
php artisan migrate
创建Section模型
php artisan make:model Section
在模型中设置可填充字段:
class Section extends Model { use HasFactory; protected $fillable = ['title', 'content', 'slug', 'order']; }
2. 控制器中用DOMDocument生成目录HTML
在控制器中从数据库拉取章节数据,通过DOMDocument构建目录的HTML结构:
<?php namespace App\Http\Controllers; use App\Models\Section; use DOMDocument; class ContentController extends Controller { public function index() { // 按排序顺序取出所有章节 $sections = Section::orderBy('order')->get(); // 初始化DOMDocument,指定UTF-8编码避免中文乱码 $dom = new DOMDocument('1.0', 'UTF-8'); $dom->formatOutput = true; // 格式化输出的HTML结构 // 创建目录容器div $tocDiv = $dom->createElement('div'); $tocDiv->setAttribute('id', 'table-of-contents'); // 添加目录标题 $tocTitle = $dom->createElement('h2', '目录'); $tocDiv->appendChild($tocTitle); // 创建无序列表 $list = $dom->createElement('ul'); // 循环章节生成列表项 foreach ($sections as $section) { $listItem = $dom->createElement('li'); $link = $dom->createElement('a'); $link->setAttribute('href', "#{$section->slug}"); $link->nodeValue = $section->title; $listItem->appendChild($link); $list->appendChild($listItem); } $tocDiv->appendChild($list); // 将DOM节点转为HTML字符串 $tocHtml = $dom->saveHTML($tocDiv); return view('content.index', compact('sections', 'tocHtml')); } }
3. 视图中展示目录与章节内容
创建视图文件resources/views/content/index.blade.php,输出目录和章节内容:
<!DOCTYPE html> <html> <head> <title>目录页面</title> <style> #table-of-contents { position: fixed; top: 20px; right: 20px; background: #f5f5f5; padding: 15px; border-radius: 8px; min-width: 200px; } #table-of-contents ul { list-style: none; padding-left: 0; } #table-of-contents li { margin: 8px 0; } .section { margin: 40px 0; max-width: 800px; } </style> </head> <body> <!-- 输出DOMDocument生成的目录HTML,用{!! !!}避免转义 --> {!! $tocHtml !!} <!-- 循环展示数据库中的章节内容 --> @foreach($sections as $section) <div class="section"> <h2 id="{{ $section->slug }}">{{ $section->title }}</h2> <p>{!! $section->content !!}</p> </div> @endforeach </body> </html>
4. 关键注意事项
- 输出HTML字符串时必须使用
{!! !!}语法,否则Laravel会自动转义HTML标签 - DOMDocument初始化时指定UTF-8编码,避免中文内容出现乱码
- 通过数据库的
order字段可以灵活控制章节在目录和页面中的展示顺序 - 若章节内容包含富文本HTML,同样用
{!! !!}输出以保留格式
内容的提问来源于stack exchange,提问作者irankhostravi
相关产品推荐
相关产品推荐

