🧭 1. Background: Adding a Poetry Microcontent Module to the WordPress Header
While optimizing the WordPress site header, I wanted to add a lightweight “cultural microcontent component” to display:
- Tang poetry
- Song poetry
- Southern Tang poetry
The goals were:
✔ Do not affect layout
✔ Do not affect performance
✔ Maintain header stability
✔ Provide a subtle cultural atmosphere

🧪 2. Version One: Attempting CSS Animation for Scrolling Poetry
The initial implementation used CSS animation:
CSS
animation: poetryScroll 14s linear infinite;And output the poetry via PHP:
PHP
return '<div class="poetry-marquee-wrapper"> <span class="poetry-marquee-static">' . esc_html($random) . '</span></div>';⚠️ Issues Encountered:
- ❌ Slight jitter in the Header layout
- ❌ Unstable FSE Row structure
- ❌ Abnormal truncation of long verses
- ❌ Misalignment in different language environments
- ❌ UI layer background conflicts

🧠 3. Key Decision: Abandoning Animation for a Static Component
Final conclusion:
❗The Header area is not suitable for complex animation components
Therefore, the overall approach converged to:
- ❌ Remove animation
- ✔ Switch to static display
- ✔ Strengthen PHP content control
🧩 4. Final Implementation (Stable PHP Version)
PHP
function wp_header_poetry() {
$files = [
'唐诗' => WP_CONTENT_DIR . '/uploads/tangshi-sanbai-shou.json',
'宋词' => WP_CONTENT_DIR . '/uploads/songci-sanbai-shou.json',
'南唐' => WP_CONTENT_DIR . '/uploads/nantang.json',
];
$pool = [];
foreach ($files as $type => $file) {
if (!file_exists($file)) continue;
$json = file_get_contents($file);
$data = json_decode($json, true);
if (!is_array($data)) continue;
foreach ($data as $item) {
if (
!isset($item['author'], $item['paragraphs']) ||
!is_array($item['paragraphs']) ||
empty($item['paragraphs'])
) {
continue;
}
$author = trim($item['author']);
$paragraphs = array_map('trim', $item['paragraphs']);
$text = implode('', $paragraphs);
// =========================
// ✂️ 智能截断(优化体验)
// =========================
if (mb_strlen($text, 'UTF-8') > 60) {
$text = mb_substr($text, 0, 60, 'UTF-8');
$pos1 = mb_strrpos($text, '。', 0, 'UTF-8');
$pos2 = mb_strrpos($text, ',', 0, 'UTF-8');
$pos1 = ($pos1 === false) ? 0 : $pos1;
$pos2 = ($pos2 === false) ? 0 : $pos2;
$pos = max($pos1, $pos2);
if ($pos > 30) {
$text = mb_substr($text, 0, $pos + 1, 'UTF-8');
}
}
// =========================
// 🏷 标题处理
// =========================
$title = ($type === '宋词')
? ($item['rhythmic'] ?? '')
: ($item['title'] ?? '');
$title = trim($title);
// =========================
// 🧱 拼接展示内容
// =========================
$display = "【{$type}】";
if (!empty($title)) {
$display .= "《{$title}》";
}
$display .= " {$author}:{$text}";
if (mb_strlen($display, 'UTF-8') <= 90) {
$pool[] = $display;
}
}
}
if (empty($pool)) {
return '';
}
$random = $pool[array_rand($pool)];
return '<div class="poetry-marquee-wrapper">
<span class="poetry-marquee-static">' . esc_html($random) . '</span>
</div>';
}
echo wp_header_poetry();
🎨 5. Final CSS (Stable Version)
CSS
.poetry-marquee-wrapper {
display: inline-flex;
align-items: center;
padding: 0 10px;
min-width: 0;
}
.poetry-marquee-static {
font-size: 14px;
line-height: 1;
opacity: 0.75;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
min-width: 0;
}
.wp-block-group.is-layout-flex {
align-items: center;
}
header.wp-block-template-part {
box-sizing: border-box;
}
🧭 6. Final Layout Structure in the Theme Editor (After Correction)
The correct structure of the current Header in FSE:
Plaintext
Header (Template Part)
└── Group (Outer Container)
└── Row (Flex Layout)
├── Poetry Shortcode(Left side)
├── Search(Right group)
└── Language Switcher(Right group)Key points:
- ✔ The Row must be unified
- ✔ Left and right alignment relies on flex
- ✔ Poetry must be within the same Row

📦 7. Poetry Data Source (GitHub)
This system uses structured JSON poetry data:
- Three Hundred Tang Poems
- Three Hundred Song Poems
- Southern Tang poetry
🔗 Data Source
Plaintext
https://github.com/chinese-poetry/chinese-poetry📁 JSON Structure Explanation
JSON
{
"author": "作者",
"title": "标题(唐诗/南唐)",
"rhythmic": "词牌名(宋词)",
"paragraphs": [
"诗句1",
"诗句2"
]
}🧠 Data Processing Rules
- Concatenate paragraphs directly
- Do not add extra punctuation (to avoid “。,” issues)
- Automatically truncate to 60 characters
- The Header only displays one entry

🚀 8. Engineering Convergence Summary
This implementation went through three phases:
1️⃣ Animation Phase
- CSS marquee
- Layout jitter
- Unstable ❌
2️⃣ Debugging Phase
- flex + padding + FSE adjustments
- Increased complexity ❌
3️⃣ Convergence Phase (Final)
- Static component ✔
- PHP content control ✔
- Minimized CSS ✔
- Stable structure ✔
🧠 9. Final Conclusion
The core takeaway from this optimization is:
❗The Header area should prioritize stability over visual complexity

