{"id":32247,"date":"2026-01-30T02:30:02","date_gmt":"2026-01-30T02:30:02","guid":{"rendered":"https:\/\/ukschoolsearch.ai\/?page_id=32247"},"modified":"2026-01-30T03:54:13","modified_gmt":"2026-01-30T03:54:13","slug":"newsletter","status":"publish","type":"page","link":"https:\/\/ukschoolsearch.ai\/index.php\/newsletter\/","title":{"rendered":"Newsletter"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"32247\" class=\"elementor elementor-32247\" data-elementor-settings=\"{&quot;ha_cmc_init_switcher&quot;:&quot;no&quot;}\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-8680d89 e-flex e-con-boxed wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no e-con e-parent\" data-id=\"8680d89\" data-element_type=\"container\" data-settings=\"{&quot;_ha_eqh_enable&quot;:false}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-2f39506 elementor-widget elementor-widget-html\" data-id=\"2f39506\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"zh-CN\">\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n    <title>Newsletter - UK School Search<\/title>\r\n    <style>\r\n        \/* \u5168\u5c40\u91cd\u7f6e *\/\r\n        .ns-app-wrapper * {\r\n            margin: 0;\r\n            padding: 0;\r\n            box-sizing: border-box;\r\n            -webkit-tap-highlight-color: transparent;\r\n        }\r\n\r\n        body {\r\n            font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\r\n            background-color: #f5f7fa;\r\n            color: #001733;\r\n            line-height: 1.6;\r\n        }\r\n\r\n        \/* \u5bb9\u5668 - PC\u7aef\u4f18\u5316\u5bbd\u5ea6 *\/\r\n        .ns-main-container {\r\n            max-width: 1000px;\r\n            margin: 0 auto;\r\n            padding: 0;\r\n        }\r\n\r\n        \/* --- \u9876\u90e8\u5de5\u5177\u680f --- *\/\r\n        .ns-toolbar {\r\n            width: 96%;\r\n            margin: 24px auto 20px auto;\r\n            display: flex;\r\n            align-items: center;\r\n            justify-content: space-between;\r\n            gap: 16px;\r\n        }\r\n\r\n        \/* \u641c\u7d22\u6846\u5bb9\u5668 *\/\r\n        .ns-search-box {\r\n            flex: 1;\r\n            height: 48px;\r\n            background: #fff;\r\n            border-radius: 24px;\r\n            display: flex;\r\n            align-items: center;\r\n            padding: 0 20px;\r\n            gap: 12px;\r\n            box-shadow: 0 4px 12px rgba(0,0,0,0.06); \r\n            transition: box-shadow 0.3s;\r\n            border: none !important; \/* \u5f3a\u5236\u53bb\u8fb9\u6846 *\/\r\n        }\r\n\r\n        .ns-search-box:focus-within {\r\n            box-shadow: 0 6px 16px rgba(0,0,0,0.1);\r\n        }\r\n\r\n        .ns-search-icon { \r\n            width: 18px; \r\n            height: 18px; \r\n            color: #999; \r\n            flex-shrink: 0;\r\n        }\r\n\r\n        \/* \u641c\u7d22\u8f93\u5165\u6846 *\/\r\n        .ns-input-field {\r\n            flex: 1; \r\n            height: 100%;\r\n            width: 100%;\r\n            font-size: 15px; \r\n            color: #001733; \r\n            \r\n            \/* \u6838\u5fc3\uff1a\u5f3a\u5236\u53bb\u9664\u6240\u6709\u8fb9\u6846\u548c\u80cc\u666f *\/\r\n            border: none !important; \r\n            outline: none !important; \r\n            background: transparent !important;\r\n            box-shadow: none !important;\r\n            -webkit-appearance: none;\r\n            appearance: none;\r\n        }\r\n        \r\n        \/* \u6d4f\u89c8\u5668\u517c\u5bb9\u6027\u6e05\u7406 *\/\r\n        .ns-input-field::-webkit-search-decoration,\r\n        .ns-input-field::-webkit-search-cancel-button,\r\n        .ns-input-field::-webkit-search-results-button,\r\n        .ns-input-field::-webkit-search-results-decoration {\r\n            -webkit-appearance: none;\r\n        }\r\n\r\n        \/* \u7b5b\u9009\u6309\u94ae *\/\r\n        .ns-filter-btn {\r\n            display: flex; \r\n            align-items: center; \r\n            gap: 6px;\r\n            padding: 10px 16px; \r\n            background: #fff;\r\n            border-radius: 24px; \r\n            box-shadow: 0 4px 12px rgba(0,0,0,0.06);\r\n            cursor: pointer; \r\n            transition: all 0.2s;\r\n            border: none !important;\r\n        }\r\n        \r\n        .ns-filter-btn:hover { \r\n            background-color: #fcfcfc; \r\n            transform: translateY(-1px);\r\n        }\r\n        \r\n        .ns-filter-text { font-size: 14px; color: #45484D; font-weight: 500; }\r\n\r\n        \/* --- \u5361\u7247\u5217\u8868 --- *\/\r\n        .ns-card-list {\r\n            width: 96%;\r\n            margin: 0 auto;\r\n            padding-bottom: 40px;\r\n        }\r\n\r\n        .ns-card {\r\n            width: 100%;\r\n            background: #fff;\r\n            border-radius: 16px;\r\n            margin-bottom: 20px;\r\n            position: relative;\r\n            display: flex;\r\n            overflow: hidden;\r\n            cursor: pointer;\r\n            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);\r\n            height: 180px; \r\n            transition: transform 0.2s, box-shadow 0.2s;\r\n            border: 1px solid rgba(0,0,0,0.03);\r\n        }\r\n\r\n        .ns-card:hover {\r\n            transform: translateY(-2px);\r\n            box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);\r\n        }\r\n\r\n        .ns-card-img-wrap {\r\n            width: 260px;\r\n            height: 100%;\r\n            flex-shrink: 0;\r\n            position: relative;\r\n        }\r\n\r\n        .ns-card-img {\r\n            width: 100%;\r\n            height: 100%;\r\n            object-fit: cover;\r\n            background: #f0f0f0;\r\n        }\r\n\r\n        .ns-card-content {\r\n            flex: 1;\r\n            padding: 20px 24px;\r\n            display: flex;\r\n            flex-direction: column;\r\n            justify-content: space-between;\r\n            min-width: 0;\r\n        }\r\n\r\n        .ns-card-header {\r\n            display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 8px;\r\n        }\r\n\r\n        .ns-card-number {\r\n            font-size: 16px; color: #074795; font-weight: 700;\r\n            font-family: 'Courier New', monospace;\r\n            background: rgba(7, 71, 149, 0.06);\r\n            padding: 2px 8px; border-radius: 6px;\r\n        }\r\n\r\n        .ns-card-date { font-size: 14px; color: #888; }\r\n\r\n        .ns-card-title {\r\n            font-size: 18px;\r\n            font-weight: 700; color: #1a1a1a;\r\n            margin-bottom: 8px;\r\n            white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\r\n        }\r\n\r\n        .ns-card-body {\r\n            font-size: 15px;\r\n            color: #555; line-height: 1.6;\r\n            display: -webkit-box;\r\n            -webkit-line-clamp: 3;\r\n            -webkit-box-orient: vertical;\r\n            overflow: hidden;\r\n        }\r\n\r\n        .ns-badge {\r\n            position: absolute; top: 10px; left: 10px;\r\n            padding: 4px 10px; border-radius: 6px;\r\n            color: #fff; font-size: 12px; font-weight: 600;\r\n            box-shadow: 0 2px 4px rgba(0,0,0,0.2); z-index: 2;\r\n        }\r\n        .ns-grad-1 { background: linear-gradient(135deg, #1F68F9, #0F4FD0); }\r\n        .ns-grad-2 { background: linear-gradient(135deg, #FF3F32, #E41700); }\r\n\r\n        \/* \u9aa8\u67b6\u5c4f *\/\r\n        .ns-sk-wrapper { width: 96%; margin: 0 auto; }\r\n        .ns-sk-card {\r\n            background: #fff; border-radius: 16px; margin-bottom: 20px;\r\n            height: 180px; display: flex; overflow: hidden; padding: 20px; gap: 20px;\r\n        }\r\n        .ns-sk-img { width: 260px; height: 100%; background: #eee; border-radius: 8px; }\r\n        .ns-sk-info { flex: 1; display: flex; flex-direction: column; gap: 14px; }\r\n        .ns-sk-line { height: 14px; background: #eee; border-radius: 4px; }\r\n        .ns-sk-line.short { width: 30%; }\r\n        .ns-sk-line.long { width: 90%; }\r\n        .ns-sk-img, .ns-sk-line {\r\n            background: linear-gradient(90deg, #f0f2f5 25%, #f9fafb 37%, #f0f2f5 63%);\r\n            background-size: 400% 100%; animation: ns-sk-loading 1.4s ease infinite;\r\n        }\r\n        @keyframes ns-sk-loading { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }\r\n\r\n        .ns-empty { text-align: center; padding: 80px 20px; color: #999; font-size: 16px; }\r\n        .ns-error { background: #fff3cd; border: 1px solid #ffc107; color: #856404; padding: 12px; border-radius: 8px; margin: 16px auto; width: 96%; display: none; text-align: center; }\r\n        .ns-error.active { display: block; }\r\n        \r\n        .loading { display: none; }\r\n\r\n        \/* \u79fb\u52a8\u7aef\u9002\u914d *\/\r\n        @media (max-width: 768px) {\r\n            .ns-main-container { max-width: 100%; }\r\n            .ns-toolbar { width: 94%; gap: 10px; margin: 16px auto; }\r\n            .ns-search-box { height: 40px; padding: 0 16px; }\r\n            .ns-card-list { width: 94%; }\r\n            \r\n            .ns-card { height: 120px; margin-bottom: 12px; border-radius: 12px; }\r\n            .ns-card-img-wrap { width: 120px; }\r\n            .ns-card-content { padding: 12px; }\r\n            .ns-card-number { font-size: 12px; }\r\n            .ns-card-date { font-size: 12px; }\r\n            .ns-card-title { font-size: 15px; margin-bottom: 4px; }\r\n            .ns-card-body { font-size: 13px; -webkit-line-clamp: 2; line-height: 1.4; }\r\n            .ns-badge { top: 6px; left: 6px; padding: 2px 6px; font-size: 10px; }\r\n            \r\n            .ns-sk-card { height: 120px; padding: 12px; gap: 12px; margin-bottom: 12px; }\r\n            .ns-sk-img { width: 100px; }\r\n        }\r\n    <\/style>\r\n<\/head>\r\n<body class=\"ns-app-wrapper\">\r\n\r\n    <div class=\"ns-main-container\">\r\n        <!-- \u9519\u8bef\u63d0\u793a -->\r\n        <div class=\"ns-error\" id=\"errorMessage\"><\/div>\r\n\r\n        <!-- \u641c\u7d22\u548c\u7b5b\u9009 -->\r\n        <div class=\"ns-toolbar\">\r\n            <div class=\"ns-search-box\">\r\n                <svg class=\"ns-search-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\">\r\n                    <circle cx=\"11\" cy=\"11\" r=\"8\"><\/circle>\r\n                    <path d=\"m21 21-4.35-4.35\"><\/path>\r\n                <\/svg>\r\n                <input \r\n                    type=\"text\" \r\n                    class=\"ns-input-field\" \r\n                    id=\"searchInput\"\r\n                    placeholder=\"\u8bf7\u8f93\u5165\u641c\u7d22\u5173\u952e\u8bcd\"\r\n                    autocomplete=\"off\"\r\n                >\r\n            <\/div>\r\n\r\n            <div class=\"ns-filter-btn\" id=\"filterButton\">\r\n                <span class=\"ns-filter-text\" id=\"filterText\">\u6700\u65b0<\/span>\r\n                <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#45484D\">\r\n                    <path d=\"M3 6h18M7 12h10M11 18h2\" stroke-width=\"2\" stroke-linecap=\"round\"\/>\r\n                <\/svg>\r\n            <\/div>\r\n        <\/div>\r\n\r\n        <!-- \u9aa8\u67b6\u5c4f -->\r\n        <div class=\"ns-sk-wrapper\" id=\"skeletonWrapper\"><\/div>\r\n\r\n        <!-- Newsletter\u5217\u8868 -->\r\n        <div class=\"ns-card-list\" id=\"newsletterList\" style=\"display: none;\"><\/div>\r\n\r\n        <!-- \u7a7a\u72b6\u6001 -->\r\n        <div class=\"ns-empty\" id=\"emptyContainer\" style=\"display: none;\">\r\n            <div class=\"empty-text\">\u6682\u65e0\u5185\u5bb9<\/div>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <script>\r\n        const WORDPRESS_API_BASE = 'https:\/\/ukschoolsearch.ai\/wp-json\/wp\/v2';\r\n        const GRADIENT_CONFIG = {\r\n            1: ['#1F68F9', '#185DE7', '#0F4FD0'],\r\n            2: ['#FF3F32', '#E41700']\r\n        };\r\n\r\n        let newsletters = [];\r\n        let sortAsc = false;\r\n        let searchText = '';\r\n\r\n        function initSkeleton() {\r\n            const wrapper = document.getElementById('skeletonWrapper');\r\n            let html = '';\r\n            for(let i=0; i<6; i++) {\r\n                html += `\r\n                <div class=\"ns-sk-card\">\r\n                    <div class=\"ns-sk-img\"><\/div>\r\n                    <div class=\"ns-sk-info\">\r\n                        <div class=\"ns-sk-line short\"><\/div>\r\n                        <div class=\"ns-sk-line long\"><\/div>\r\n                        <div class=\"ns-sk-line\"><\/div>\r\n                        <div class=\"ns-sk-line\"><\/div>\r\n                    <\/div>\r\n                <\/div>`;\r\n            }\r\n            wrapper.innerHTML = html;\r\n        }\r\n\r\n        function toggleLoading(show) {\r\n            const skeleton = document.getElementById('skeletonWrapper');\r\n            const list = document.getElementById('newsletterList');\r\n            const empty = document.getElementById('emptyContainer');\r\n            \r\n            if (show) {\r\n                skeleton.style.display = 'block';\r\n                list.style.display = 'none';\r\n                empty.style.display = 'none';\r\n            } else {\r\n                skeleton.style.display = 'none';\r\n            }\r\n        }\r\n\r\n        function formatShortMonthDate(dateString) {\r\n            const date = new Date(dateString);\r\n            const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\r\n            return `${months[date.getMonth()]} ${date.getDate()}`;\r\n        }\r\n\r\n        function extractExcerpt(htmlContent) {\r\n            const textContent = htmlContent.replace(\/<[^>]*>\/g, '');\r\n            return textContent.length > 150\r\n                ? textContent.substring(0, 150) + '...'\r\n                : textContent;\r\n        }\r\n\r\n        function extractContentImages(content) {\r\n            const images = [];\r\n            try {\r\n                const imgRegex = \/<img[^>]+>\/gi;\r\n                const tags = content.match(imgRegex) || [];\r\n                \r\n                for (const tag of tags) {\r\n                    const srcMatch = tag.match(\/src=[\"']([^\"']+)[\"']\/i);\r\n                    if (srcMatch && srcMatch[1]) {\r\n                        const widthMatch = tag.match(\/width=[\"']?(\\d+)[\"']?\/i);\r\n                        const heightMatch = tag.match(\/height=[\"']?(\\d+)[\"']?\/i);\r\n                        \r\n                        images.push({\r\n                            url: srcMatch[1],\r\n                            width: widthMatch ? parseInt(widthMatch[1]) : 750,\r\n                            height: heightMatch ? parseInt(heightMatch[1]) : 1000\r\n                        });\r\n                    }\r\n                }\r\n            } catch (e) {\r\n                console.error('\u63d0\u53d6\u5185\u5bb9\u56fe\u7247\u65f6\u51fa\u9519:', e);\r\n            }\r\n            return images;\r\n        }\r\n\r\n        function computeContentSig(imgs) {\r\n            const raw = imgs.map(i => `${i.url}|${i.width}|${i.height}`).join('||');\r\n            let h = 0;\r\n            for (let i = 0; i < raw.length; i++) {\r\n                h = (h * 31 + raw.charCodeAt(i)) | 0;\r\n            }\r\n            return String(h);\r\n        }\r\n\r\n        function showError(message) {\r\n            const errorEl = document.getElementById('errorMessage');\r\n            errorEl.textContent = message;\r\n            errorEl.classList.add('active');\r\n            setTimeout(() => errorEl.classList.remove('active'), 5000);\r\n        }\r\n\r\n        async function fetchNewsletters() {\r\n            try {\r\n                if(newsletters.length === 0) toggleLoading(true);\r\n\r\n                console.log('\ud83d\udce1 \u5f00\u59cb\u4ece WordPress \u83b7\u53d6 Newsletter...');\r\n                \r\n                let response = await fetch(`${WORDPRESS_API_BASE}\/newsletters?per_page=100`);\r\n                \r\n                if (response.status === 404) {\r\n                    response = await fetch(`${WORDPRESS_API_BASE}\/newsletter?per_page=100`);\r\n                }\r\n\r\n                if (response.status === 404) {\r\n                    response = await fetch(`${WORDPRESS_API_BASE}\/posts?post_type=newsletters&per_page=100`);\r\n                }\r\n\r\n                if (response.status === 404) {\r\n                    const catRes = await fetch(`${WORDPRESS_API_BASE}\/categories?search=newsletter`);\r\n                    if (catRes.ok) {\r\n                        const cats = await catRes.json();\r\n                        if (Array.isArray(cats) && cats.length > 0) {\r\n                            const catId = cats[0].id;\r\n                            response = await fetch(`${WORDPRESS_API_BASE}\/posts?categories=${catId}&per_page=100`);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (!response.ok) {\r\n                    throw new Error(`HTTP ${response.status}: ${response.statusText}`);\r\n                }\r\n\r\n                const posts = await response.json();\r\n                \r\n                if (!Array.isArray(posts)) {\r\n                    throw new Error('\u8fd4\u56de\u7684\u6570\u636e\u4e0d\u662f\u6570\u7ec4');\r\n                }\r\n\r\n                console.log('\u2705 \u6210\u529f\u83b7\u53d6', posts.length, '\u6761 Newsletter');\r\n\r\n                newsletters = posts.map((post, index) => {\r\n                    const acf = post?.acf || {};\r\n                    const idNum = typeof acf.id === 'number' ? acf.id : Number(post?.id) || index + 1;\r\n                    \r\n                    const parsedGradient = Number(acf.gradient);\r\n                    const safeGradient = (Number.isFinite(parsedGradient) && GRADIENT_CONFIG[parsedGradient])\r\n                        ? parsedGradient\r\n                        : 1;\r\n\r\n                    const contentImages = extractContentImages(post?.content?.rendered || '');\r\n                    const contentSig = computeContentSig(contentImages);\r\n\r\n                    return {\r\n                        key: acf.key || `wp${idNum}`,\r\n                        id: idNum,\r\n                        number: acf.number || `No.${String(index + 1).padStart(3, '0')}`,\r\n                        title: acf.title || post?.title?.rendered || '\u65e0\u6807\u9898',\r\n                        date: acf.date || post?.date || new Date().toISOString(),\r\n                        badge: acf.badge || '\u65b0\u95fb',\r\n                        gradient: safeGradient,\r\n                        image: acf.image || 'https:\/\/via.placeholder.com\/400x400\/1F68F9\/FFFFFF?text=Newsletter',\r\n                        body: acf.body || extractExcerpt(post?.excerpt?.rendered || post?.content?.rendered || ''),\r\n                        url: `\/newsletter\/${idNum}`,\r\n                        isRead: false,\r\n                        isDeleted: false,\r\n                        content: contentImages,\r\n                        contentSig: contentSig\r\n                    };\r\n                });\r\n\r\n                return true;\r\n\r\n            } catch (error) {\r\n                console.error('\u274c \u83b7\u53d6 Newsletter \u5931\u8d25:', error);\r\n                showError('\u52a0\u8f7d\u5931\u8d25: ' + error.message);\r\n                newsletters = getFallbackData();\r\n                return false;\r\n            } finally {\r\n                toggleLoading(false);\r\n            }\r\n        }\r\n\r\n        function getFallbackData() {\r\n            return [\r\n                {\r\n                    key: 'wp001',\r\n                    id: 1,\r\n                    number: 'No.001',\r\n                    title: 'WordPress \u8fde\u63a5\u6d4b\u8bd5',\r\n                    date: '2025-01-30T00:00:00',\r\n                    badge: '\u6d4b\u8bd5',\r\n                    gradient: 1,\r\n                    image: 'https:\/\/via.placeholder.com\/400x400\/1F68F9\/FFFFFF?text=Test',\r\n                    body: '\u8fd9\u662f\u5907\u7528\u6570\u636e...',\r\n                    url: '\/newsletter\/1',\r\n                    isRead: false,\r\n                    isDeleted: false,\r\n                    content: [],\r\n                    contentSig: '0'\r\n                }\r\n            ];\r\n        }\r\n\r\n        function renderNewsletters() {\r\n            const keyword = searchText.trim().toLowerCase();\r\n            let list = newsletters.filter(n => !n.isDeleted);\r\n\r\n            if (keyword) {\r\n                list = list.filter(n => {\r\n                    const searchContent = [\r\n                        n.badge || '',\r\n                        n.date || '',\r\n                        n.body || '',\r\n                        n.number || '',\r\n                        n.title || ''\r\n                    ].join(' ').toLowerCase();\r\n                    return searchContent.includes(keyword);\r\n                });\r\n            }\r\n\r\n            list.sort((a, b) => sortAsc ? a.id - b.id : b.id - a.id);\r\n\r\n            const container = document.getElementById('newsletterList');\r\n            const emptyContainer = document.getElementById('emptyContainer');\r\n\r\n            if (list.length === 0) {\r\n                container.style.display = 'none';\r\n                emptyContainer.style.display = 'block';\r\n                emptyContainer.querySelector('.empty-text').textContent = \r\n                    keyword ? '\u6ca1\u6709\u5339\u914d\u7684\u5185\u5bb9' : '\u6682\u65e0\u5185\u5bb9';\r\n            } else {\r\n                emptyContainer.style.display = 'none';\r\n                container.style.display = 'block';\r\n                \r\n                container.innerHTML = list.map(item => `\r\n                    <div class=\"ns-card\" onclick=\"handleNewsletterClick(${item.id})\">\r\n                        <div class=\"ns-card-img-wrap\">\r\n                            <img decoding=\"async\" \r\n                                src=\"${item.image}\" \r\n                                class=\"ns-card-img\"\r\n                                alt=\"${item.title}\"\r\n                                loading=\"lazy\"\r\n                                onerror=\"this.src='https:\/\/via.placeholder.com\/400x400\/1F68F9\/FFFFFF?text=IMG'\"\r\n                            >\r\n                            <div class=\"ns-badge ns-grad-${item.gradient}\">\r\n                                ${item.badge}\r\n                            <\/div>\r\n                        <\/div>\r\n                        <div class=\"ns-card-content\">\r\n                            <div>\r\n                                <div class=\"ns-card-header\">\r\n                                    <span class=\"ns-card-number\">${item.number}<\/span>\r\n                                    <span class=\"ns-card-date\">${formatShortMonthDate(item.date)}<\/span>\r\n                                <\/div>\r\n                                <div class=\"ns-card-title\">${item.title}<\/div>\r\n                                <div class=\"ns-card-body\">${item.body}<\/div>\r\n                            <\/div>\r\n                        <\/div>\r\n                    <\/div>\r\n                `).join('');\r\n            }\r\n        }\r\n\r\n        \/\/ --- \u6838\u5fc3\u4fee\u6b63\uff1a\u8df3\u8f6c\u94fe\u63a5\u4f7f\u7528\u60a8\u786e\u8ba4\u6709\u6548\u7684\u8def\u5f84 ---\r\n        function handleNewsletterClick(id) {\r\n            const newsletter = newsletters.find(n => n.id === id);\r\n            if (newsletter) {\r\n                \/\/ \u4f7f\u7528\u60a8\u63d0\u4f9b\u7684\u786e\u5207\u7684\u3001\u6709\u6548\u7684URL\u683c\u5f0f\r\n                window.location.href = `https:\/\/ukschoolsearch.ai\/index.php\/newsletter-detail?id=${id}`;\r\n            }\r\n        }\r\n\r\n        document.getElementById('filterButton').addEventListener('click', () => {\r\n            sortAsc = !sortAsc;\r\n            document.getElementById('filterText').textContent = sortAsc ? '\u6700\u65e7' : '\u6700\u65b0';\r\n            renderNewsletters();\r\n        });\r\n\r\n        document.getElementById('searchInput').addEventListener('input', (e) => {\r\n            searchText = e.target.value;\r\n            renderNewsletters();\r\n        });\r\n\r\n        window.addEventListener('DOMContentLoaded', async () => {\r\n            initSkeleton();\r\n            await fetchNewsletters();\r\n            renderNewsletters();\r\n        });\r\n    <\/script>\r\n<\/body>\r\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Newsletter &#8211; UK School Search \u6700\u65b0 \u6682\u65e0\u5185\u5bb9<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-32247","page","type-page","status-publish","hentry"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.2 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Newsletter - SmartGen in UK<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/ukschoolsearch.ai\/index.php\/newsletter\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Newsletter - SmartGen in UK\" \/>\n<meta property=\"og:description\" content=\"Newsletter &#8211; UK School Search \u6700\u65b0 \u6682\u65e0\u5185\u5bb9\" \/>\n<meta property=\"og:url\" content=\"https:\/\/ukschoolsearch.ai\/index.php\/newsletter\/\" \/>\n<meta property=\"og:site_name\" content=\"SmartGen in UK\" \/>\n<meta property=\"article:modified_time\" content=\"2026-01-30T03:54:13+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/ukschoolsearch.ai\/index.php\/newsletter\/\",\"url\":\"https:\/\/ukschoolsearch.ai\/index.php\/newsletter\/\",\"name\":\"Newsletter - SmartGen in UK\",\"isPartOf\":{\"@id\":\"https:\/\/ukschoolsearch.ai\/#website\"},\"datePublished\":\"2026-01-30T02:30:02+00:00\",\"dateModified\":\"2026-01-30T03:54:13+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/ukschoolsearch.ai\/index.php\/newsletter\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/ukschoolsearch.ai\/index.php\/newsletter\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/ukschoolsearch.ai\/index.php\/newsletter\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/ukschoolsearch.ai\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Newsletter\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/ukschoolsearch.ai\/#website\",\"url\":\"https:\/\/ukschoolsearch.ai\/\",\"name\":\"SmartGen in UK\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/ukschoolsearch.ai\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/ukschoolsearch.ai\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/ukschoolsearch.ai\/#organization\",\"name\":\"SmartGen in UK\",\"url\":\"https:\/\/ukschoolsearch.ai\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/ukschoolsearch.ai\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/ukschoolsearch.ai\/wp-content\/uploads\/2024\/06\/SmartGen_logo.png\",\"contentUrl\":\"https:\/\/ukschoolsearch.ai\/wp-content\/uploads\/2024\/06\/SmartGen_logo.png\",\"width\":213,\"height\":213,\"caption\":\"SmartGen in UK\"},\"image\":{\"@id\":\"https:\/\/ukschoolsearch.ai\/#\/schema\/logo\/image\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Newsletter - SmartGen in UK","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/ukschoolsearch.ai\/index.php\/newsletter\/","og_locale":"en_US","og_type":"article","og_title":"Newsletter - SmartGen in UK","og_description":"Newsletter &#8211; UK School Search \u6700\u65b0 \u6682\u65e0\u5185\u5bb9","og_url":"https:\/\/ukschoolsearch.ai\/index.php\/newsletter\/","og_site_name":"SmartGen in UK","article_modified_time":"2026-01-30T03:54:13+00:00","twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/ukschoolsearch.ai\/index.php\/newsletter\/","url":"https:\/\/ukschoolsearch.ai\/index.php\/newsletter\/","name":"Newsletter - SmartGen in UK","isPartOf":{"@id":"https:\/\/ukschoolsearch.ai\/#website"},"datePublished":"2026-01-30T02:30:02+00:00","dateModified":"2026-01-30T03:54:13+00:00","breadcrumb":{"@id":"https:\/\/ukschoolsearch.ai\/index.php\/newsletter\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/ukschoolsearch.ai\/index.php\/newsletter\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/ukschoolsearch.ai\/index.php\/newsletter\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/ukschoolsearch.ai\/"},{"@type":"ListItem","position":2,"name":"Newsletter"}]},{"@type":"WebSite","@id":"https:\/\/ukschoolsearch.ai\/#website","url":"https:\/\/ukschoolsearch.ai\/","name":"SmartGen in UK","description":"","publisher":{"@id":"https:\/\/ukschoolsearch.ai\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/ukschoolsearch.ai\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/ukschoolsearch.ai\/#organization","name":"SmartGen in UK","url":"https:\/\/ukschoolsearch.ai\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ukschoolsearch.ai\/#\/schema\/logo\/image\/","url":"https:\/\/ukschoolsearch.ai\/wp-content\/uploads\/2024\/06\/SmartGen_logo.png","contentUrl":"https:\/\/ukschoolsearch.ai\/wp-content\/uploads\/2024\/06\/SmartGen_logo.png","width":213,"height":213,"caption":"SmartGen in UK"},"image":{"@id":"https:\/\/ukschoolsearch.ai\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/ukschoolsearch.ai\/index.php\/wp-json\/wp\/v2\/pages\/32247","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ukschoolsearch.ai\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ukschoolsearch.ai\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ukschoolsearch.ai\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/ukschoolsearch.ai\/index.php\/wp-json\/wp\/v2\/comments?post=32247"}],"version-history":[{"count":34,"href":"https:\/\/ukschoolsearch.ai\/index.php\/wp-json\/wp\/v2\/pages\/32247\/revisions"}],"predecessor-version":[{"id":32284,"href":"https:\/\/ukschoolsearch.ai\/index.php\/wp-json\/wp\/v2\/pages\/32247\/revisions\/32284"}],"wp:attachment":[{"href":"https:\/\/ukschoolsearch.ai\/index.php\/wp-json\/wp\/v2\/media?parent=32247"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}