UNPKG

@etsoo/website

Version:

ETSOO CMS Based NextJs Website Framework

206 lines (204 loc) 7.58 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import Script from 'next/script'; import React from 'react'; import { SiteUtils } from './SiteUtils'; /** * Local site class * 本地站点类 */ export class LocalSite { /** * Constructor * 构造函数 * @param data Site data */ constructor(data) { this.data = data; } /** * Clear title format * 清除标题格式 * @param title Title */ clearTitle(title) { if (title == null) return undefined; const reg = /\[\[[^\[\]]+\]\]/g; const parts = title.split(reg); let match; let index = 0; while ((match = reg.exec(title)) !== null) { const part = match[0].slice(2, -2); parts.splice(index * 2 + 1, 0, part); index++; } return parts.join(''); } createMenuItem(t, hasIcon) { var _a; return hasIcon ? (_jsxs(React.Fragment, { children: [_jsx("i", { className: (_a = t.icon) !== null && _a !== void 0 ? _a : 'fa fa-fw' }), _jsx("span", { children: t.name })] })) : (t.name); } /** * Create Bootstrap menu * 创建 Bootstrap 菜单 * @param url Current URL * @param hasIcon Take tab logo as icon * @param dropdownClasses Dropdown classes * @returns Component */ createBootstrapMenu(url, hasIcon, dropdownClasses) { // Top menu items const tabs = this.data.tabs; const tops = tabs.filter((tab) => tab.parent == null); dropdownClasses !== null && dropdownClasses !== void 0 ? dropdownClasses : (dropdownClasses = 'dropdown-menu shadow-sm fade-up m-0'); return (_jsx(React.Fragment, { children: tops.map((t) => { const children = tabs.filter((tab) => tab.parent === t.id); if (children.length === 0) { // Skip if 'not display in menu' if (t.layout === 1) return; return (_jsx("a", { href: this.formatUrl(t), className: 'nav-item nav-link' + this.matchUrl(t, url), children: this.createMenuItem(t, hasIcon) }, t.id)); } else { return (_jsxs("div", { className: "dropdown", children: [_jsx("a", { href: this.formatUrl(t), className: 'nav-item nav-link dropdown-toggle' + this.matchUrl(t, url), "data-bs-toggle": "dropdown", children: this.createMenuItem(t, hasIcon) }), _jsx("div", { className: dropdownClasses, children: children.map((c) => (_jsx("a", { href: this.formatUrl(c), className: 'dropdown-item nav-link' + this.matchUrl(c, url), children: c.name }, c.id))) })] }, t.id)); } }) })); } /** * Create Google Analytics service * @returns Component */ createGAService() { const ga = this.getService('GA'); if (ga == null) return; return (_jsxs(React.Fragment, { children: [_jsx(Script, { src: `https://www.googletagmanager.com/gtag/js?id=${ga.app}`, strategy: "afterInteractive" }), _jsx(Script, { id: "google-analytics", strategy: "afterInteractive", children: ` window.dataLayer = window.dataLayer || []; function gtag() { dataLayer.push(arguments); } gtag('js', new Date()); gtag('config', '${ga.app}'); ` })] })); } /** * Create Google reCAPTCHA service * @param domain Service domain, 'R' for recaptcha.net, 'G' for google.com * @returns Component */ createRECAPService(domain = 'G') { const re = this.getService('RECAP'); if (re == null) return; const api = domain === 'G' ? 'google.com' : 'recaptcha.net'; return (_jsxs(React.Fragment, { children: [_jsx(Script, { src: `https://www.${api}/recaptcha/api.js?render=${re.app}`, strategy: "afterInteractive" }), _jsx(Script, { id: "google-recaptcha", strategy: "afterInteractive", children: `window.googleGecaptchaSiteKey = '${re.app}'` })] })); } createTabList(name, urlOrTabs, options) { const tabs = typeof urlOrTabs === 'string' ? this.getListTab((tab) => tab.url === urlOrTabs)[1] : urlOrTabs; const { classNames = 'form-select', emptyOptionLabel = 'Choose...', ...rest } = options !== null && options !== void 0 ? options : {}; return (_jsxs("select", { name: name, id: name, className: classNames, ...rest, children: [_jsx("option", { value: "", children: emptyOptionLabel }), tabs.map((t) => (_jsx("option", { children: t.name }, t.id)))] })); } /** * Create Wechat service * @param onLoad On load handler * @returns Component */ createWXService(onLoad) { const wx = this.getService('WX'); if (wx == null) return; return (_jsx(Script, { src: "/js/jweixin-1.6.0.js", strategy: "lazyOnload", onLoad: () => onLoad })); } /** * Format article URL * 格式化文章链接 * @param item Article link item * @returns Result */ formatLink(item) { return SiteUtils.formatLink(item); } /** * Format title * 格式化标题 * @param title Title */ formatTitle(title, format) { if (title == null) return undefined; const reg = /\[\[[^\[\]]+\]\]/g; const parts = title.split(reg); let match; let index = 0; while ((match = reg.exec(title)) !== null) { const part = format(match[0].slice(2, -2), index); parts.splice(index * 2 + 1, 0, part); index++; } return parts; } /** * Format tab URL * 格式化栏目地址 * @param tab Tab * @returns Result */ formatUrl(tab) { return SiteUtils.formatUrl(tab); } /** * Get resource * 获取资源 * @param id Resource id * @param defaultValue Default value * @returns Result */ getResource(id, defaultValue) { var _a, _b, _c; return ((_c = (_b = (_a = this.data.resources.find((r) => r.id === id)) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : defaultValue) !== null && _c !== void 0 ? _c : id); } /** * Get service * 获取服务 * @param id Service id * @returns Result */ getService(id) { return this.data.services.find((s) => s.id === id); } /** * Get list tab * 获取列表栏目 * @param filter Filter * @returns Result */ getListTab(filter) { filter !== null && filter !== void 0 ? filter : (filter = (t) => t.layout === 1); const tab = this.data.tabs.find(filter); if (tab == null) return [undefined, []]; const children = this.data.tabs.filter((c) => c.parent === tab.id); return [tab, children]; } /** * Match tab * 匹配栏目 * @param tab Tab * @param url URL * @param matchClass Match style clsss name * @returns Result */ matchUrl(tab, url, matchClass = 'active') { let matched = false; if (tab.parent == null) { matched = tab.url === url || (tab.url != '/' && url.startsWith(tab.url)); } else { matched = tab.url === url; } return matched ? ` ${matchClass}` : ''; } }