edgepress 2026.10.1 → 2026.10.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +216 -16
- package/config.yml +99 -127
- package/content/assets/edgepress/brand/avatar.png +0 -0
- package/content/assets/edgepress/brand/deploy-esa.svg +1 -0
- package/content/assets/edgepress/brand/home-hero-768.webp +0 -0
- package/content/assets/edgepress/brand/home-hero.png +0 -0
- package/content/assets/edgepress/brand/home-hero.webp +0 -0
- package/content/assets/edgepress/brand/mascot.png +0 -0
- package/content/assets/edgepress/brand/mascot.webp +0 -0
- package/content/assets/edgepress/brand/og-image.png +0 -0
- package/content/assets/edgepress/brand/og-image.webp +0 -0
- package/content/assets/edgepress/brand/sources/edgepress-avatar-master.png +0 -0
- package/content/assets/edgepress/brand/sources/export-manifest.json +181 -0
- package/content/assets/edgepress/brand/sources/prompts.json +12 -0
- package/content/assets/edgepress/favicon/apple-touch-icon.png +0 -0
- package/content/assets/edgepress/favicon/favicon-16.png +0 -0
- package/content/assets/edgepress/favicon/favicon-32.png +0 -0
- package/content/assets/edgepress/favicon/favicon-48.png +0 -0
- package/content/assets/edgepress/favicon/favicon-64.png +0 -0
- package/content/assets/edgepress/favicon/favicon.ico +0 -0
- package/content/assets/edgepress/icons/LICENSE.txt +43 -0
- package/content/assets/edgepress/icons/arrow-right.svg +16 -0
- package/content/assets/edgepress/icons/arrow-up-right.svg +16 -0
- package/content/assets/edgepress/icons/book-open.svg +16 -0
- package/content/assets/edgepress/icons/check-circle.svg +16 -0
- package/content/assets/edgepress/icons/check.svg +15 -0
- package/content/assets/edgepress/icons/cloud.svg +15 -0
- package/content/assets/edgepress/icons/code.svg +16 -0
- package/content/assets/edgepress/icons/cpu.svg +28 -0
- package/content/assets/edgepress/icons/file-text.svg +19 -0
- package/content/assets/edgepress/icons/github.svg +17 -0
- package/content/assets/edgepress/icons/globe.svg +17 -0
- package/content/assets/edgepress/icons/help-circle.svg +17 -0
- package/content/assets/edgepress/icons/home.svg +16 -0
- package/content/assets/edgepress/icons/layers.svg +17 -0
- package/content/assets/edgepress/icons/layout-grid.svg +18 -0
- package/content/assets/edgepress/icons/mail.svg +16 -0
- package/content/assets/edgepress/icons/newspaper.svg +18 -0
- package/content/assets/edgepress/icons/palette.svg +19 -0
- package/content/assets/edgepress/icons/plug.svg +18 -0
- package/content/assets/edgepress/icons/provenance.json +8 -0
- package/content/assets/edgepress/icons/puzzle.svg +15 -0
- package/content/assets/edgepress/icons/rocket.svg +18 -0
- package/content/assets/edgepress/icons/rss.svg +17 -0
- package/content/assets/edgepress/icons/search.svg +16 -0
- package/content/assets/edgepress/icons/settings.svg +16 -0
- package/content/assets/edgepress/icons/shield-check.svg +16 -0
- package/content/assets/edgepress/icons/sparkles.svg +18 -0
- package/content/assets/edgepress/icons/terminal.svg +16 -0
- package/content/assets/edgepress/icons/x.svg +16 -0
- package/{static → content/assets}/edgepress-markdown-guide.svg +1 -1
- package/content/assets/images/previews/edgepress-en.webp +0 -0
- package/content/assets/images/previews/edgepress-revisions-en.png +0 -0
- package/content/assets/images/previews/edgepress-workflow-en.90f4650b21013786.gif +0 -0
- package/content/assets/images/previews/edgepress-workflow-zh.41f1e0a685f47267.gif +0 -0
- package/content/assets/images/previews/edgepress-zh.webp +0 -0
- package/content/assets/images/previews/provenance.json +49 -0
- package/content/guides/markdown-media.md +38 -0
- package/content/guides/platforms.md +15 -0
- package/content/guides/product-demos.md +37 -0
- package/content/guides/zh-cn.md +62 -0
- package/content/pages/deployment/en.json +74 -0
- package/content/pages/deployment/zh-cn.json +74 -0
- package/content/pages/home/en.json +248 -0
- package/content/pages/home/zh-cn.json +248 -0
- package/content/pages/local-tools/en.json +14 -0
- package/content/pages/local-tools/zh-cn.json +14 -0
- package/content/pages/page-authoring/en.json +107 -0
- package/content/pages/page-authoring/zh-cn.json +107 -0
- package/content/pages/plugin-development/en.json +202 -0
- package/content/pages/plugin-development/zh-cn.json +202 -0
- package/content/pages/privacy-policy/en.json +171 -0
- package/content/pages/privacy-policy/zh-cn.json +171 -0
- package/content/pages/project-introduction/en.json +158 -0
- package/content/pages/project-introduction/zh-cn.json +158 -0
- package/content/pages/quick-start/en.json +325 -0
- package/content/pages/quick-start/zh-cn.json +325 -0
- package/content/pages/theme-development/en.json +353 -0
- package/content/pages/theme-development/zh-cn.json +349 -0
- package/content/posts/2026-09-24-edgepress-release-2026-9-1/en.md +1 -1
- package/content/posts/2026-09-24-edgepress-release-2026-9-1/zh-cn.md +1 -1
- package/content/posts/2026-10-03-edgepress-release-2026-10-3/en.md +16 -0
- package/content/posts/2026-10-03-edgepress-release-2026-10-3/zh-cn.md +16 -0
- package/content/posts/2026-10-03-edgepress-release-202610-4/en.md +22 -0
- package/content/posts/2026-10-03-edgepress-release-202610-4/zh-cn.md +20 -0
- package/content/posts/2026-10-03-edgepress-release-202610-5/en.md +15 -0
- package/content/posts/2026-10-03-edgepress-release-202610-5/zh-cn.md +15 -0
- package/edgeone.json +43 -0
- package/esa.jsonc +9 -0
- package/languages/base/en.json +75 -10
- package/languages/packs/zh-CN.json +74 -9
- package/netlify.toml +6 -0
- package/package.json +37 -6
- package/plugins/consent/index.js +10 -17
- package/project-compatibility.json +142 -25
- package/schemas/pages.schema.json +74 -0
- package/src/assets.js +146 -18
- package/src/browser-audit.js +158 -0
- package/src/build.js +34 -9
- package/src/cli.js +46 -41
- package/src/config.js +114 -63
- package/src/consent-csp.js +137 -0
- package/src/content.js +55 -30
- package/src/data-saver.js +194 -0
- package/src/deploy.js +28 -0
- package/src/document.js +44 -0
- package/src/embed.js +60 -0
- package/src/generators.js +101 -59
- package/src/i18n.js +19 -3
- package/src/icons.js +5 -4
- package/src/image-dimensions.js +17 -0
- package/src/local-tool.js +29 -0
- package/src/maintenance.js +25 -8
- package/src/markdown-fixture.js +20 -0
- package/src/markdown.js +80 -16
- package/src/media-assets.js +19 -0
- package/src/media-viewer.js +47 -0
- package/src/oembed.js +53 -0
- package/src/page-blocks.js +124 -54
- package/src/page-check.js +29 -39
- package/src/plugin-api.js +7 -1
- package/src/post-details.js +60 -0
- package/src/post-template.js +5 -0
- package/src/publication-time.js +47 -0
- package/src/report-path.js +19 -0
- package/src/report-visuals.js +91 -18
- package/src/revision-cards.js +30 -0
- package/src/revision-images.js +44 -0
- package/src/revisions.js +77 -0
- package/src/rss.js +100 -0
- package/src/service-block.js +18 -0
- package/src/theme.js +59 -9
- package/src/video-metadata.js +36 -0
- package/static/edgepress/data-saver.css +12 -0
- package/static/edgepress/data-saver.js +333 -0
- package/static/edgepress/document-viewer.js +35 -0
- package/static/edgepress/external-links-policy.js +14 -0
- package/static/edgepress/external-links.css +13 -0
- package/static/edgepress/external-links.js +120 -0
- package/static/edgepress/fonts/faces.css +2217 -0
- package/static/edgepress/fonts/noto-sans-OFL.txt +93 -0
- package/static/edgepress/fonts/noto-sans-cyrillic-ext-wght-normal.82ff72b28e6610f2.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-cyrillic-wght-normal.6ab64433de6077ca.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-devanagari-wght-normal.ea6a530b75d93de7.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-greek-ext-wght-normal.790b255c10c32e0b.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-greek-wght-normal.7f655207c2f6c140.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-latin-ext-wght-normal.6d5a79315528df19.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-latin-wght-normal.51ca196f49a33e79.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-100-wght-normal.ad5f29028d5699a5.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-101-wght-normal.e189b81fc22ca6af.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-102-wght-normal.941c0c2971fc1d6d.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-103-wght-normal.bafbd591af6493ff.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-104-wght-normal.b0bf80ced89dd61b.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-105-wght-normal.8d8b4e6f4a00621d.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-106-wght-normal.bae74acc629d2e74.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-107-wght-normal.a42eff5010de7b0d.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-108-wght-normal.91882203459867be.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-109-wght-normal.a91f8b038e5ce108.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-110-wght-normal.bbca9081655c4523.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-111-wght-normal.372be010ac0e87cb.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-112-wght-normal.34a4580239eae8dc.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-113-wght-normal.614ab8f616352583.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-114-wght-normal.cf7b8344807a316e.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-115-wght-normal.fb29957c7adccb9a.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-116-wght-normal.a98dc5a726f82141.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-117-wght-normal.d94b5af0c14838af.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-118-wght-normal.76c9ddb85ae4578c.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-119-wght-normal.b3b2374881f4cd93.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-21-wght-normal.c1409c43e55ecff2.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-22-wght-normal.77037ed42ff4e7b0.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-23-wght-normal.38d0df21ac374e93.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-24-wght-normal.8fa21e7e457acf3e.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-25-wght-normal.f760b7a3871d214d.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-26-wght-normal.be8386e7bd7facfe.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-27-wght-normal.4895abcaddbd162e.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-28-wght-normal.82540b6201a9b9ad.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-29-wght-normal.ff21d8fcc60ce391.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-30-wght-normal.1f76f6ffded00b9e.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-31-wght-normal.e6c25be1bb08a63a.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-32-wght-normal.0cda750d7d04a4e1.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-33-wght-normal.b9732b5606bd87c5.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-34-wght-normal.38aa326b4c84902a.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-35-wght-normal.bd98226c8e0aa808.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-36-wght-normal.0db1ca695a491d37.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-37-wght-normal.8df409a4e0a237c2.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-38-wght-normal.672d2d994994a3c3.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-39-wght-normal.272d6d0e153f56e8.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-4-wght-normal.9fafd93ac77b81ff.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-40-wght-normal.5b9ef1ed48420aa7.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-41-wght-normal.30aee47f660fd88a.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-42-wght-normal.ec0014830db682b6.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-43-wght-normal.43df2b5dad9bb835.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-44-wght-normal.acaa6195041b1a92.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-45-wght-normal.8cdb9903f770db21.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-46-wght-normal.6590d0a6fe94571c.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-47-wght-normal.b05afdd32b3bf722.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-48-wght-normal.c9585f7d070700be.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-49-wght-normal.4943895a4dfa5dcf.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-5-wght-normal.e64f57937e3ae4fe.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-50-wght-normal.13e51063d7743cfe.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-51-wght-normal.fd4df1f02c2cb4d7.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-52-wght-normal.06999a39c4c3a7ea.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-53-wght-normal.767b7b9864658d91.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-54-wght-normal.4cd00537a46f6f1a.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-55-wght-normal.0118ec5d8c30b197.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-56-wght-normal.a3e4a78929826930.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-57-wght-normal.7623501009e4a6db.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-58-wght-normal.56ae1a59a32e4a25.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-59-wght-normal.7a377a40e99fd9bc.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-6-wght-normal.17e15c4f0a5bfd92.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-60-wght-normal.3657f66babdf6aff.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-61-wght-normal.23919a2eb11d25dd.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-62-wght-normal.a901edf25bc1cfae.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-63-wght-normal.92f56f713cc0b62f.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-64-wght-normal.4929c9f39a5a4bd9.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-65-wght-normal.8daa61282fb62a11.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-66-wght-normal.6479166925eb462b.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-67-wght-normal.a6b0e11c4c761ffd.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-68-wght-normal.65b77f1fe9d68dae.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-69-wght-normal.b34f765cbbf4d02e.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-70-wght-normal.a99d55c00e4f95b7.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-71-wght-normal.3298bed30dc8d233.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-72-wght-normal.6597209ca9707726.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-73-wght-normal.e7ac1d4930eabd78.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-74-wght-normal.1f0287be83a28e7a.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-75-wght-normal.d9a4bb7bcc2be578.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-76-wght-normal.5a019946bcadcec6.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-77-wght-normal.7c445e85d04f5319.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-78-wght-normal.7d4afb70f641781c.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-79-wght-normal.5798753a721bb4ec.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-80-wght-normal.db887159ca6e46f3.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-81-wght-normal.71e5743bbd225b3d.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-82-wght-normal.8c5094c3785fd04f.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-83-wght-normal.4a60a1ccba905284.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-84-wght-normal.3ed54e59ef4758e3.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-85-wght-normal.e87e0a1342e1778c.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-86-wght-normal.6d3ac3e20959dbcb.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-87-wght-normal.0eeffd5daad5c17b.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-88-wght-normal.b1d9582dfa268463.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-89-wght-normal.8b437aeb9e9fcb5a.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-90-wght-normal.83b0a59e0a5e045a.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-91-wght-normal.382f72b98d4bb9d7.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-97-wght-normal.5e52856457c5cdab.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-98-wght-normal.ffded4e7fd560d93.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-99-wght-normal.54e302c23f11a8fd.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-OFL.txt +93 -0
- package/static/edgepress/fonts/noto-sans-sc-cyrillic-wght-normal.5932d441e7126669.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-latin-ext-wght-normal.e316201f3fc493d1.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-latin-wght-normal.c1d919c8701a86ed.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-sc-vietnamese-wght-normal.cba3d00c8db989f0.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-0-wght-normal.63c21eda5d20203f.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-100-wght-normal.87a7c76301c24a28.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-101-wght-normal.c9e83fc4ffd53746.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-102-wght-normal.9a00ae0e5735852b.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-103-wght-normal.7cfe93b3221f4def.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-104-wght-normal.2d5ac7497d84cb99.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-105-wght-normal.0989885bb16bcd9b.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-106-wght-normal.1faa921b035064e7.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-107-wght-normal.2f6006745ae16d69.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-108-wght-normal.a61e48c10a2cf4b9.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-109-wght-normal.f28c767724736d2d.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-110-wght-normal.4b04bd88c3dc7c5d.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-111-wght-normal.b6251e1967932a52.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-112-wght-normal.e264513b32f90660.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-113-wght-normal.46cb347d88f3338e.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-114-wght-normal.9f9e1e0d0ab2aeb4.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-115-wght-normal.653dd2ab7d551b40.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-116-wght-normal.4718bf3627191297.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-117-wght-normal.b241a9409682af5f.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-118-wght-normal.fda2800dc1c06852.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-119-wght-normal.948af36bd63a72c7.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-19-wght-normal.62191cdc3a10e60a.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-20-wght-normal.65c90892c2e01657.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-21-wght-normal.d3f59b094c334866.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-22-wght-normal.b1983a041d7e4e1f.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-23-wght-normal.16e2163b66c7732a.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-24-wght-normal.72c8561976116537.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-25-wght-normal.b2948d928ce4dd54.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-26-wght-normal.d583236b90abedc9.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-27-wght-normal.7d6073ba07597c9b.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-28-wght-normal.517204d716b089cd.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-29-wght-normal.10189a8f8ca38099.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-30-wght-normal.695a71d72dfab3f7.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-31-wght-normal.868d59473ef0e73c.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-32-wght-normal.92efa2d4b3702ec0.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-33-wght-normal.d2274bcd5636197d.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-34-wght-normal.1ac8c3718ee2eed2.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-35-wght-normal.00b3df730d5a4c73.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-36-wght-normal.6963feb6c628b81f.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-37-wght-normal.a1b4bd294af24cd1.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-38-wght-normal.8edb2f7f2955921b.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-39-wght-normal.37bf7394eb3148c6.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-40-wght-normal.3efa655bc48f9133.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-41-wght-normal.48d47014544ebd5d.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-42-wght-normal.214c733a59d423e7.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-43-wght-normal.c2c9876f138bb20f.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-44-wght-normal.28928bfea29db06a.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-45-wght-normal.bf3743f8155fa9d2.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-46-wght-normal.06970903593781c3.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-47-wght-normal.8932ed83a91794d4.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-48-wght-normal.dfd9225628bcf234.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-49-wght-normal.c27d341ad39d44eb.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-50-wght-normal.01a0f4e7dfba0a56.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-51-wght-normal.5a30022af3d30e0f.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-52-wght-normal.4884f032342a3274.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-53-wght-normal.537adcae44511270.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-54-wght-normal.6bc8c7d3e47c6fde.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-55-wght-normal.725a48711f1e1997.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-56-wght-normal.f43ecaa73e0cd8fc.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-57-wght-normal.15b24e9d42a3270f.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-58-wght-normal.9b2d8a71667d3da6.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-59-wght-normal.a68535a6b3289d89.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-6-wght-normal.32cece1ae80c4f2b.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-60-wght-normal.3b2c56a921d1cad4.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-61-wght-normal.54f51f80a0740878.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-62-wght-normal.ba029c5bb6c07bf1.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-63-wght-normal.380919beec4c7f3d.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-64-wght-normal.f96fe0be479d201f.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-65-wght-normal.7d544b80701fe678.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-66-wght-normal.fab669c07a1e3bee.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-67-wght-normal.0001bb744743fdfa.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-68-wght-normal.1a57eda03886b43c.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-69-wght-normal.017fecc749bcd6d5.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-7-wght-normal.cd0f0cac743dbbfe.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-70-wght-normal.79fb9d70b9534ec7.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-71-wght-normal.04a6ea581b5f1195.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-72-wght-normal.d3a4eb35499157b7.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-73-wght-normal.d81f8484404ee465.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-74-wght-normal.4a5da9e0c2702f7d.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-75-wght-normal.8b87f9c6c164513a.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-76-wght-normal.a71463dbfd9fa7b5.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-77-wght-normal.d094414ea752cd52.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-78-wght-normal.04f7c97bd9cbc73b.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-79-wght-normal.1ed089d037a02049.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-8-wght-normal.d052677dfb5db5bd.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-80-wght-normal.6d41ca59cfd50442.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-81-wght-normal.f09bd0afa8a58114.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-82-wght-normal.7920841c526b1b02.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-83-wght-normal.0c6f7f82db8da0d8.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-84-wght-normal.f37c0a853b31265e.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-85-wght-normal.4173bff087653b82.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-86-wght-normal.dac35605ebec15c4.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-87-wght-normal.8ac85fdd0b15a6bd.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-88-wght-normal.61625b0b21e8407f.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-89-wght-normal.a1da3dccbf00698e.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-90-wght-normal.bf08f0355222a782.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-91-wght-normal.2ecf295bba2bfaa3.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-92-wght-normal.36508326bb68115f.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-97-wght-normal.c712899e0fc9e947.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-98-wght-normal.13a648e521d18d7f.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-99-wght-normal.7f8c9a777e64159a.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-OFL.txt +93 -0
- package/static/edgepress/fonts/noto-sans-tc-cyrillic-wght-normal.dd0980ced8e46cb3.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-latin-ext-wght-normal.817d96335dc52ce6.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-latin-wght-normal.50cb5fb0a522cfaf.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-tc-vietnamese-wght-normal.2a77fb7b70fa304d.woff2 +0 -0
- package/static/edgepress/fonts/noto-sans-vietnamese-wght-normal.791e3f213c155a5b.woff2 +0 -0
- package/static/edgepress/fonts/noto-serif-OFL.txt +93 -0
- package/static/edgepress/fonts/noto-serif-cyrillic-ext-wght-normal.7c7afb20d33e30ec.woff2 +0 -0
- package/static/edgepress/fonts/noto-serif-cyrillic-wght-normal.54e3bd0c4a002b0f.woff2 +0 -0
- package/static/edgepress/fonts/noto-serif-greek-ext-wght-normal.9b3f4c4ff3adefd2.woff2 +0 -0
- package/static/edgepress/fonts/noto-serif-greek-wght-normal.1252037b6f1d6e86.woff2 +0 -0
- package/static/edgepress/fonts/noto-serif-latin-ext-wght-normal.2654f8d1261a420f.woff2 +0 -0
- package/static/edgepress/fonts/noto-serif-latin-wght-normal.46281456234014ce.woff2 +0 -0
- package/static/edgepress/fonts/noto-serif-math-wght-normal.d4a6aba2cb4636b3.woff2 +0 -0
- package/static/edgepress/fonts/noto-serif-vietnamese-wght-normal.fb6a5ed734c2fbe3.woff2 +0 -0
- package/static/edgepress/fonts/provenance.json +1356 -0
- package/static/edgepress/fonts.css +14 -0
- package/static/edgepress/image-viewer.js +23 -0
- package/static/edgepress/images.css +4 -0
- package/static/edgepress/link-directory.css +14 -0
- package/static/edgepress/local-time.js +12 -0
- package/static/edgepress/media-viewer.css +1 -0
- package/static/edgepress/media-viewer.js +111 -0
- package/static/edgepress/navigation-select.js +14 -0
- package/static/edgepress/oembed.js +129 -0
- package/static/edgepress/plugins/backend/external-api.js +4 -0
- package/static/edgepress/plugins/backend/external-widget.js +13 -0
- package/static/edgepress/plugins/consent/choices.js +47 -0
- package/static/edgepress/plugins/consent/manager.js +56 -74
- package/static/edgepress/project-demo.js +93 -0
- package/static/edgepress/search.js +2 -2
- package/static/edgepress/services-consent.js +3 -0
- package/static/edgepress/services.js +15 -0
- package/static/edgepress/webmcp.js +86 -0
- package/tests/assets-runtime.test.mjs +91 -0
- package/tests/audit.test.mjs +142 -0
- package/tests/brand-regression.test.mjs +110 -0
- package/tests/consent-browser.test.mjs +132 -0
- package/tests/consent-config.test.mjs +85 -0
- package/tests/consent-csp.test.mjs +90 -0
- package/tests/data-saver-loading.test.mjs +158 -0
- package/tests/data-saver-network.test.mjs +99 -0
- package/tests/data-saver.test.mjs +294 -0
- package/tests/document-package.test.mjs +28 -0
- package/tests/document-viewer.test.mjs +152 -0
- package/tests/edge-issues.test.mjs +65 -0
- package/tests/embed-syntax.test.mjs +68 -0
- package/tests/external-links.test.mjs +198 -0
- package/tests/fixtures/recording.mp4 +0 -0
- package/tests/fonts.test.mjs +99 -0
- package/tests/image-dimensions.test.mjs +15 -0
- package/tests/image-viewer.test.mjs +36 -0
- package/tests/json-pages.test.mjs +66 -0
- package/tests/link-directory.test.mjs +51 -0
- package/tests/local-tool.test.mjs +34 -0
- package/tests/markdown-media.test.mjs +119 -0
- package/tests/media-block.test.mjs +102 -0
- package/tests/navigation.test.mjs +87 -0
- package/tests/oembed-layout.test.mjs +98 -0
- package/tests/oembed.test.mjs +96 -0
- package/tests/page-authoring.test.mjs +27 -0
- package/tests/page-formatting.test.mjs +37 -0
- package/tests/post-list.test.mjs +96 -0
- package/tests/project-demo.test.mjs +73 -0
- package/tests/publication-time.test.mjs +43 -0
- package/tests/release-version.test.mjs +28 -0
- package/tests/revisions.test.mjs +93 -0
- package/tests/rss.test.mjs +54 -0
- package/tests/services.test.mjs +35 -0
- package/tests/theme-layout.test.mjs +95 -0
- package/tests/video-metadata.test.mjs +28 -0
- package/tests/webmcp.test.mjs +121 -0
- package/tests/writing.test.mjs +101 -0
- package/themes/atelier/assets/style.css +144 -22
- package/themes/atelier/layouts/partials/head.html +8 -1
- package/themes/atelier/layouts/partials/header.html +3 -1
- package/themes/default/assets/data-saver-theme.css +2 -0
- package/themes/default/assets/style.css +139 -23
- package/themes/default/layouts/partials/head.html +9 -2
- package/themes/default/layouts/partials/header.html +3 -1
- package/themes/default/theme.json +1 -0
- package/themes/folio/README.md +7 -0
- package/themes/folio/assets/data-saver-theme.css +3 -0
- package/themes/folio/assets/folio/navigation.js +10 -0
- package/themes/folio/assets/style.css +516 -0
- package/themes/folio/layouts/layout.html +15 -0
- package/themes/folio/layouts/partials/footer.html +6 -0
- package/themes/folio/layouts/partials/head.html +30 -0
- package/themes/folio/layouts/partials/header.html +8 -0
- package/themes/folio/theme.json +7 -0
- package/themes/signal/assets/style.css +143 -21
- package/themes/signal/layouts/partials/head.html +8 -1
- package/themes/signal/layouts/partials/header.html +3 -1
- package/tools/README.md +14 -0
- package/tools/assets/format-pages.mjs +56 -0
- package/tools/assets/generate-brand-assets.py +160 -0
- package/tools/assets/sync-fonts.mjs +71 -0
- package/tools/assets/sync-icons.mjs +17 -0
- package/tools/assets/video-preview.mjs +15 -0
- package/tools/recordings/capture-document-demo.mjs +147 -0
- package/tools/recordings/demo-workbench.mjs +57 -0
- package/tools/recordings/desktop-recording.mjs +92 -0
- package/tools/recordings/provision-vm.sh +18 -0
- package/tools/recordings/start-vm-desktop.sh +28 -0
- package/tools/recordings/vm-desktop.mjs +124 -0
- package/tools/verification/README.md +44 -0
- package/tools/verification/data-saver-site.mjs +405 -0
- package/tools/verification/page-performance.mjs +76 -0
- package/tools/verification/verify-brand-assets.py +52 -0
- package/tools/verification/verify-brand.mjs +180 -0
- package/vercel.json +36 -0
- package/wrangler.jsonc +5 -7
- package/content/pages/home/en.md +0 -99
- package/content/pages/home/zh-cn.md +0 -99
- package/content/pages/plugin-development/en.md +0 -109
- package/content/pages/plugin-development/zh-cn.md +0 -109
- package/content/pages/privacy-policy/en.md +0 -93
- package/content/pages/privacy-policy/zh-cn.md +0 -93
- package/content/pages/project-introduction/en.md +0 -88
- package/content/pages/project-introduction/zh-cn.md +0 -88
- package/content/pages/quick-start/en.md +0 -153
- package/content/pages/quick-start/zh-cn.md +0 -153
- package/content/pages/theme-development/en.md +0 -132
- package/content/pages/theme-development/zh-cn.md +0 -132
- package/src/worker.js +0 -139
- package/static/edgepress/brand/edgepress-mark.svg +0 -7
- package/static/edgepress/brand/mascot-209.webp +0 -0
- package/static/edgepress/brand/mascot-418.png +0 -0
- package/static/edgepress/brand/mascot-418.webp +0 -0
- package/static/edgepress/brand/mascot.png +0 -0
- package/static/edgepress/brand/og-image.png +0 -0
- package/static/edgepress/brand/og-image.svg +0 -46
- package/static/edgepress/icons.svg +0 -24
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../../../schemas/pages.schema.json",
|
|
3
|
+
"title": "用括号看懂 Pages 的包含关系",
|
|
4
|
+
"lang": "zh-CN",
|
|
5
|
+
"slug": "page-authoring",
|
|
6
|
+
"description": "使用 JSON 页面、本地结构说明和可折叠对象,读懂行、单元格与元素。",
|
|
7
|
+
"blocks": [
|
|
8
|
+
{
|
|
9
|
+
"columns": 1,
|
|
10
|
+
"cells": [
|
|
11
|
+
[
|
|
12
|
+
{
|
|
13
|
+
"type": "hero",
|
|
14
|
+
"title": "用括号看懂 Pages 的包含关系",
|
|
15
|
+
"text": "使用 JSON 页面、本地结构说明和可折叠对象,读懂行、单元格与元素。"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"columns": 1,
|
|
22
|
+
"cells": [
|
|
23
|
+
[
|
|
24
|
+
{
|
|
25
|
+
"type": "code",
|
|
26
|
+
"title": "完整的双栏 JSON 页面",
|
|
27
|
+
"language": "json",
|
|
28
|
+
"code": "{\n \"title\": \"My page\",\n \"lang\": \"en\",\n \"slug\": \"my-page\",\n \"blocks\": [\n {\n \"columns\": 2,\n \"cells\": [\n [\n {\n \"type\": \"heading\",\n \"level\": 2,\n \"text\": \"About this project\"\n },\n {\n \"type\": \"text\",\n \"text\": \"A small tool for everyday writing.\"\n }\n ],\n [\n {\n \"type\": \"link-list\",\n \"title\": \"Read more\",\n \"items\": [\n {\n \"label\": \"Project\",\n \"url\": \"/[launge]/project-introduction/\"\n }\n ]\n }\n ]\n ]\n }\n ]\n}"
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"columns": 1,
|
|
35
|
+
"cells": [
|
|
36
|
+
[
|
|
37
|
+
{
|
|
38
|
+
"type": "text",
|
|
39
|
+
"paragraphs": [
|
|
40
|
+
"保存为 content/pages/my-page/en.json。语言文件名须小写,lang 匹配已启用的语言;中文页面可用 zh-cn.json。homepage: true 发布为对应语言首页,slug 定义普通页面路径。JSON 页面不使用 YAML 前置数据,也没有 Markdown 正文。",
|
|
41
|
+
"blocks 数组按顺序放页面行。一行的 columns 从 1 到 4,cells 内须有相同个数的单元格数组。每个单元格至少包含一个元素,元素从上到下显示。",
|
|
42
|
+
"JSON 键名和字符串使用双引号。花括号放对象,方括号放数组,同级项目用逗号分开。不要新增 elements 字段;最内层数组直接放元素。",
|
|
43
|
+
"section 的 blocks 放子元素,不是新的页面行。文字用 text 或 paragraphs,代码用 code 字符串,内部换行使用 \\n。文章仍放在 content/posts,用 Markdown 编写。",
|
|
44
|
+
"本地 $schema 让 VS Code 提供字段说明和结构校验。对象与数组可以逐级折叠,大纲能展示它们的上下关系。旧 .md 页面仍可构建,但同一语言不要同时保留两种页面格式。"
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"columns": 1,
|
|
52
|
+
"cells": [
|
|
53
|
+
[
|
|
54
|
+
{
|
|
55
|
+
"type": "data-table",
|
|
56
|
+
"title": "常用元素(字段)",
|
|
57
|
+
"headers": [
|
|
58
|
+
"用途",
|
|
59
|
+
"元素与关键字段"
|
|
60
|
+
],
|
|
61
|
+
"rows": [
|
|
62
|
+
[
|
|
63
|
+
"Title",
|
|
64
|
+
"heading (level, text)"
|
|
65
|
+
],
|
|
66
|
+
[
|
|
67
|
+
"Prose",
|
|
68
|
+
"text (text OR paragraphs)"
|
|
69
|
+
],
|
|
70
|
+
[
|
|
71
|
+
"Group",
|
|
72
|
+
"section (title, blocks)"
|
|
73
|
+
],
|
|
74
|
+
[
|
|
75
|
+
"Code",
|
|
76
|
+
"code (language, code)"
|
|
77
|
+
],
|
|
78
|
+
[
|
|
79
|
+
"Articles",
|
|
80
|
+
"post-list (title, category OR categories, count)"
|
|
81
|
+
],
|
|
82
|
+
[
|
|
83
|
+
"Document",
|
|
84
|
+
"document (title, src)"
|
|
85
|
+
],
|
|
86
|
+
[
|
|
87
|
+
"Gallery",
|
|
88
|
+
"media-viewer (title, items)"
|
|
89
|
+
]
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
]
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"columns": 1,
|
|
97
|
+
"cells": [
|
|
98
|
+
[
|
|
99
|
+
{
|
|
100
|
+
"type": "text",
|
|
101
|
+
"text": "运行 npm run pages:format 预览迁移,再用 npm run pages:format -- --write 写入。工具在移除旧文件前校验字段值与顺序;随后运行 npm run build 检查实际呈现。"
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../../../schemas/pages.schema.json",
|
|
3
|
+
"title": "Plugin development",
|
|
4
|
+
"lang": "en",
|
|
5
|
+
"slug": "plugin-development",
|
|
6
|
+
"description": "Extend static websites with trusted build plugins and consent-registered external services.",
|
|
7
|
+
"blocks": [
|
|
8
|
+
{
|
|
9
|
+
"columns": 1,
|
|
10
|
+
"cells": [
|
|
11
|
+
[
|
|
12
|
+
{
|
|
13
|
+
"type": "hero",
|
|
14
|
+
"eyebrow": "Extension guide",
|
|
15
|
+
"title": "Connect trusted build code, browser providers, and backend services.",
|
|
16
|
+
"text": "Build-time plugins run in Node. Browser services load only after visitor consent. Backends are independently deployed."
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"columns": 2,
|
|
23
|
+
"cells": [
|
|
24
|
+
[
|
|
25
|
+
{
|
|
26
|
+
"type": "section",
|
|
27
|
+
"title": "Build-time plugins",
|
|
28
|
+
"tone": "soft",
|
|
29
|
+
"blocks": [
|
|
30
|
+
{
|
|
31
|
+
"type": "text",
|
|
32
|
+
"paragraphs": [
|
|
33
|
+
"Local JavaScript modules in plugins/ may transform source documents, register hooks or renderers, and generate routes. They execute with the build process permissions, so only load code reviewed by the project owner.",
|
|
34
|
+
"The starter consent plugin adds a privacy panel after the shared page layout. Build plugins are trusted code and are not deployed as browser scripts."
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"type": "code",
|
|
39
|
+
"title": "Register a route generator",
|
|
40
|
+
"language": "js",
|
|
41
|
+
"code": "export default function projectMeta(api) {\n api.registerGenerator('project-meta', ({ site }) => ({\n path: 'project-meta.json',\n body: JSON.stringify({\n title: site.config.site.title,\n posts: site.posts.length\n }),\n contentType: 'application/json; charset=utf-8'\n }));\n}\n"
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
[
|
|
47
|
+
{
|
|
48
|
+
"type": "section",
|
|
49
|
+
"title": "Tracking, statistics, advertising, and CAPTCHA",
|
|
50
|
+
"tone": "soft",
|
|
51
|
+
"blocks": [
|
|
52
|
+
{
|
|
53
|
+
"type": "text",
|
|
54
|
+
"paragraphs": [
|
|
55
|
+
"Add browser providers in config.yml under plugins.consent.services. Each service needs a unique ID, provider, purpose, dataCategories, recipient, retention, a privacyUrl pointing to the provider's current privacy information, and its public site identifier. privacyUrl must be an HTTPS URL. Localized fields are maps keyed by every enabled locale, such as en and zh-CN.",
|
|
56
|
+
"Available providers include Google Tag Manager and Meta Pixel; Cloudflare Web Analytics, Google Analytics, and Baidu Tongji; Google AdSense; and Cloudflare Turnstile, Google reCAPTCHA, and hCaptcha.",
|
|
57
|
+
"Set plugins.consent.proposedDate to the YYYY-MM-DD date the notice was drafted. Set effectiveDate when the notice takes effect; omit it while no effective date has been set. Updating either date makes saved consent stale, so visitors are asked again.",
|
|
58
|
+
"Provider code is imported only after the visitor accepts that integration. The first layer offers accept and reject together; service data and individual switches are available in its details. Keep CAPTCHA secret keys out of config.yml and client code. The server must submit each CAPTCHA response to the provider verification API before accepting a form."
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"type": "notice",
|
|
63
|
+
"title": "Operator details",
|
|
64
|
+
"text": "Fill privacy.controller.name, privacy.controller.contact, and privacy.policyUrl before configuring any browser provider. The build rejects provider services when the controller name or contact is blank.",
|
|
65
|
+
"tone": "warning"
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"columns": 1,
|
|
74
|
+
"cells": [
|
|
75
|
+
[
|
|
76
|
+
{
|
|
77
|
+
"type": "text",
|
|
78
|
+
"heading": "Optional external services",
|
|
79
|
+
"paragraphs": [
|
|
80
|
+
"Register external-api or external-widget under plugins.consent.services in config.yml. Services require their own HTTPS origin, complete privacy disclosures and explicit visitor consent.",
|
|
81
|
+
"The site is static. API authentication, authorization, CAPTCHA verification, input validation and rate limits belong to the independently deployed backend. Operator Secrets never enter browser configuration."
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"columns": 1,
|
|
89
|
+
"cells": [
|
|
90
|
+
[
|
|
91
|
+
{
|
|
92
|
+
"type": "section",
|
|
93
|
+
"title": "Content security and maintenance",
|
|
94
|
+
"blocks": [
|
|
95
|
+
{
|
|
96
|
+
"type": "text",
|
|
97
|
+
"paragraphs": [
|
|
98
|
+
"The built-in Markdown renderer sanitizes post output. Custom renderers, plugins, themes, and files in static/ are trusted project code; review changes before building or deploying. Do not put secrets in posts, themes, or public assets.",
|
|
99
|
+
"edgepress iterate writes a report-only review plan under .edgepress/reports/. It does not edit source files, update dependencies, or deploy. edgepress security checks dependency advisories. Review the lockfile and generated page report before deployment, and keep a known-good deployment for rollback."
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"type": "code",
|
|
104
|
+
"title": "Review project changes",
|
|
105
|
+
"language": "sh",
|
|
106
|
+
"code": "edgepress security\nedgepress iterate\nedgepress check\nedgepress server\n"
|
|
107
|
+
}
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
]
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"columns": 1,
|
|
115
|
+
"cells": [
|
|
116
|
+
[
|
|
117
|
+
{
|
|
118
|
+
"type": "text",
|
|
119
|
+
"heading": "iask",
|
|
120
|
+
"text": "iask owns comments, styles, identity and stickers. Register an external-widget with backendUrl and moduleUrl under plugins.consent.services; the host only loads it after opt-in."
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"type": "link-list",
|
|
124
|
+
"title": "Install and integrate",
|
|
125
|
+
"items": [
|
|
126
|
+
{
|
|
127
|
+
"label": "Installation and EdgePress integration",
|
|
128
|
+
"url": "https://github.com/jsw-teams/iask/blob/main/docs/edgepress.md"
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"label": "iask release notes",
|
|
132
|
+
"url": "https://github.com/jsw-teams/iask/blob/main/CHANGELOG.md"
|
|
133
|
+
}
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"type": "code",
|
|
138
|
+
"title": "Optional page discussion block",
|
|
139
|
+
"language": "json",
|
|
140
|
+
"code": "{\n \"blocks\": [\n {\n \"columns\": 1,\n \"cells\": [\n [\n {\n \"type\": \"service\",\n \"integration\": \"github-comments\"\n }\n ]\n ]\n }\n ]\n}"
|
|
141
|
+
}
|
|
142
|
+
]
|
|
143
|
+
]
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"columns": 1,
|
|
147
|
+
"cells": [
|
|
148
|
+
[
|
|
149
|
+
{
|
|
150
|
+
"type": "text",
|
|
151
|
+
"heading": "Shared images and videos",
|
|
152
|
+
"text": "Register ishare as an oembed service in plugins.consent.services, with its HTTPS backendUrl and complete privacy disclosures. The page keeps a local placeholder until the visitor consents and clicks Load media. Metadata uses fixed /api and request headers; the attributed iframe remains on the configured service origin."
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"type": "code",
|
|
156
|
+
"title": "Pages embed syntax",
|
|
157
|
+
"language": "json",
|
|
158
|
+
"code": "{\n \"blocks\": [\n {\n \"columns\": 1,\n \"cells\": [\n [\n {\n \"type\": \"text\",\n \"text\": \"!embed[ishare](https://share.js.gripe/s/REPLACE_WITH_REAL_SHARE_ID)\"\n }\n ]\n ]\n }\n ]\n}"
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"type": "link-list",
|
|
162
|
+
"title": "Service documentation",
|
|
163
|
+
"items": [
|
|
164
|
+
{
|
|
165
|
+
"label": "ishare",
|
|
166
|
+
"url": "https://github.com/jsw-teams/ishare/blob/main/docs/zh-cn.md"
|
|
167
|
+
}
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
]
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"columns": 1,
|
|
175
|
+
"cells": [
|
|
176
|
+
[
|
|
177
|
+
{
|
|
178
|
+
"type": "text",
|
|
179
|
+
"heading": "General social media embeds",
|
|
180
|
+
"text": "Only YouTube and X are registered as general media presets; share.js.gripe enables none. Register custom services in config.yml as needed. Set enabled: false to remove its consent entry and network permissions; its block retains a local disabled notice and the original link. oembedEndpoint metadata is cached at build time; the browser still waits for consent and a load click. sourceOrigins validates shared links; embedOrigins permits media hosts; embedScripts contains exact optional vendor script URLs. Instagram and Facebook use official public-content iframes. Private or embed-restricted posts may be unavailable. Replace the Mastodon instance with your actual instance."
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"type": "code",
|
|
184
|
+
"title": "Pages embed syntax",
|
|
185
|
+
"language": "json",
|
|
186
|
+
"code": "{\n \"blocks\": [\n {\n \"columns\": 2,\n \"cells\": [\n [\n {\n \"type\": \"text\",\n \"heading\": \"Watch with context\",\n \"text\": \"Describe the media next to its player.\"\n }\n ],\n [\n {\n \"type\": \"text\",\n \"text\": \"!embed[youtube](https://www.youtube.com/watch?v=jNQXAC9IVRw)\"\n }\n ]\n ]\n }\n ]\n}"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"type": "text",
|
|
190
|
+
"heading": "Custom oEmbed and navigation",
|
|
191
|
+
"text": "Add a flat provider: oembed service in config.yml with disclosures, backendUrl, oembedEndpoint and permitted source/media origins. Public endpoints must not contain secrets; authenticated providers need an external gateway. Pages text blocks use the same !embed[service](URL) syntax as article bodies. Navigation and footer links support target: _self or target: _blank, including dropdown choices."
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"type": "text",
|
|
195
|
+
"heading": "Automatic CSP from service configuration",
|
|
196
|
+
"text": "The build generates a Content-Security-Policy response header and a matching HTML meta policy for static hosting. Enabled consent services contribute only their permitted script, connection, frame and media origins. Disabled services contribute no permissions. CSP does not grant consent: visitors must still allow the service before a resource loads. Custom services can add an optional csp map, for example connect-src: [https://api.example.com]; only HTTPS origins are accepted. Keep first-party upload permissions in the source _headers file. GTM containers that add other providers need those domains explicitly configured."
|
|
197
|
+
}
|
|
198
|
+
]
|
|
199
|
+
]
|
|
200
|
+
}
|
|
201
|
+
]
|
|
202
|
+
}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../../../schemas/pages.schema.json",
|
|
3
|
+
"title": "插件开发",
|
|
4
|
+
"lang": "zh-CN",
|
|
5
|
+
"slug": "plugin-development",
|
|
6
|
+
"description": "使用可信构建插件和经过 consent 注册的外部服务扩展静态网站。",
|
|
7
|
+
"blocks": [
|
|
8
|
+
{
|
|
9
|
+
"columns": 1,
|
|
10
|
+
"cells": [
|
|
11
|
+
[
|
|
12
|
+
{
|
|
13
|
+
"type": "hero",
|
|
14
|
+
"eyebrow": "扩展指南",
|
|
15
|
+
"title": "连接可信构建代码、浏览器供应商和后端服务。",
|
|
16
|
+
"text": "构建插件在 Node 中运行,浏览器服务只在访客选择后加载,后端独立部署。"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"columns": 2,
|
|
23
|
+
"cells": [
|
|
24
|
+
[
|
|
25
|
+
{
|
|
26
|
+
"type": "section",
|
|
27
|
+
"title": "构建插件",
|
|
28
|
+
"tone": "soft",
|
|
29
|
+
"blocks": [
|
|
30
|
+
{
|
|
31
|
+
"type": "text",
|
|
32
|
+
"paragraphs": [
|
|
33
|
+
"plugins/ 中的本地 JavaScript 模块可以转换源文档、注册钩子或渲染器,并生成路由。它们拥有构建进程的权限,因此只应加载项目负责人审查过的代码。",
|
|
34
|
+
"起始同意插件会在共享页面布局后添加隐私面板。构建插件属于可信代码,不会作为浏览器脚本发布。"
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"type": "code",
|
|
39
|
+
"title": "注册路由生成器",
|
|
40
|
+
"language": "js",
|
|
41
|
+
"code": "export default function projectMeta(api) {\n api.registerGenerator('project-meta', ({ site }) => ({\n path: 'project-meta.json',\n body: JSON.stringify({\n title: site.config.site.title,\n posts: site.posts.length\n }),\n contentType: 'application/json; charset=utf-8'\n }));\n}\n"
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
[
|
|
47
|
+
{
|
|
48
|
+
"type": "section",
|
|
49
|
+
"title": "跟踪、统计、广告和人机验证",
|
|
50
|
+
"tone": "soft",
|
|
51
|
+
"blocks": [
|
|
52
|
+
{
|
|
53
|
+
"type": "text",
|
|
54
|
+
"paragraphs": [
|
|
55
|
+
"在 config.yml 的 plugins.consent.services 下添加浏览器供应商。每项需要唯一 ID、provider、purpose、dataCategories、recipient、retention、指向供应商当前隐私说明的 privacyUrl,以及公开站点标识。privacyUrl 必须是 HTTPS 地址。多语言字段需使用语言映射,覆盖已启用的每种语言,例如 en 与 zh-CN。",
|
|
56
|
+
"可用供应商包括 Google Tag Manager 和 Meta Pixel;Cloudflare Web Analytics、Google Analytics 和百度统计;Google AdSense;以及 Cloudflare Turnstile、Google reCAPTCHA 和 hCaptcha。",
|
|
57
|
+
"plugins.consent.proposedDate 必须设置为 YYYY-MM-DD 格式的告知拟定日期。告知生效后再设置 effectiveDate;尚未生效时可以省略。修改任一日期都会使旧的同意记录失效,并重新询问访客。",
|
|
58
|
+
"只有访客接受对应集成后才会导入供应商代码。首层同时提供接受和拒绝,数据详情与逐项开关位于展开内容中。不要把 CAPTCHA 密钥放入 config.yml 或客户端代码。服务器必须在接受表单前将每个 CAPTCHA 响应提交给供应商验证 API。"
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"type": "notice",
|
|
63
|
+
"title": "运营者信息",
|
|
64
|
+
"text": "配置浏览器供应商前,请填写 privacy.controller.name、privacy.controller.contact 和 privacy.policyUrl。控制者名称或联系方式为空时,构建器会拒绝启用供应商服务。",
|
|
65
|
+
"tone": "warning"
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"columns": 1,
|
|
74
|
+
"cells": [
|
|
75
|
+
[
|
|
76
|
+
{
|
|
77
|
+
"type": "text",
|
|
78
|
+
"heading": "可选外部服务",
|
|
79
|
+
"paragraphs": [
|
|
80
|
+
"在 config.yml 的 plugins.consent.services 注册 external-api 或 external-widget。服务使用独立 HTTPS 地址、完整隐私说明和访客明确选择。",
|
|
81
|
+
"网站只提供静态前端。API 身份验证、授权、验证码校验、输入验证和速率限制由独立后端负责,运营者 Secret 不进入浏览器配置。"
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"columns": 1,
|
|
89
|
+
"cells": [
|
|
90
|
+
[
|
|
91
|
+
{
|
|
92
|
+
"type": "section",
|
|
93
|
+
"title": "内容安全与维护",
|
|
94
|
+
"blocks": [
|
|
95
|
+
{
|
|
96
|
+
"type": "text",
|
|
97
|
+
"paragraphs": [
|
|
98
|
+
"内置 Markdown 渲染器会清理文章输出。自定义渲染器、插件、主题和 static/ 中的文件都属于可信项目代码;构建或部署前应审查变更。不要将密钥放在文章、主题或公开资源中。",
|
|
99
|
+
"edgepress iterate 会在 .edgepress/reports/ 下生成只读维护计划,不会修改源文件、更新依赖或部署。edgepress security 检查依赖安全公告。部署前请审查锁文件和页面报告,并保留可用于回滚的已知稳定部署。"
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"type": "code",
|
|
104
|
+
"title": "审查项目变更",
|
|
105
|
+
"language": "sh",
|
|
106
|
+
"code": "edgepress security\nedgepress iterate\nedgepress check\nedgepress server\n"
|
|
107
|
+
}
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
]
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"columns": 1,
|
|
115
|
+
"cells": [
|
|
116
|
+
[
|
|
117
|
+
{
|
|
118
|
+
"type": "text",
|
|
119
|
+
"heading": "我提问",
|
|
120
|
+
"text": "显示经过验证的 GitHub 身份和头像,可从本地图片、GIF 图集中选择表情包,支持删除自己的评论。读者选中评论后才加载讨论。"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"type": "link-list",
|
|
124
|
+
"title": "安装与接入",
|
|
125
|
+
"items": [
|
|
126
|
+
{
|
|
127
|
+
"label": "安装及 EdgePress 接入说明",
|
|
128
|
+
"url": "https://github.com/jsw-teams/iask/blob/main/docs/edgepress.md"
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"label": "我提问 独立更新日志",
|
|
132
|
+
"url": "https://github.com/jsw-teams/iask/blob/main/CHANGELOG.md"
|
|
133
|
+
}
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"type": "code",
|
|
138
|
+
"title": "可选页面评论区块",
|
|
139
|
+
"language": "json",
|
|
140
|
+
"code": "{\n \"blocks\": [\n {\n \"columns\": 1,\n \"cells\": [\n [\n {\n \"type\": \"service\",\n \"integration\": \"github-comments\"\n }\n ]\n ]\n }\n ]\n}"
|
|
141
|
+
}
|
|
142
|
+
]
|
|
143
|
+
]
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"columns": 1,
|
|
147
|
+
"cells": [
|
|
148
|
+
[
|
|
149
|
+
{
|
|
150
|
+
"type": "text",
|
|
151
|
+
"heading": "嵌入分享图片与视频",
|
|
152
|
+
"text": "在 plugins.consent.services 注册 provider: oembed 的 ishare 服务,填写实际 HTTPS backendUrl、用途与隐私披露。页面先显示本地占位,访客授权并点击加载媒体才请求服务。元数据使用固定 /api 和 HTTP 请求头传递,保留作者和来源署名的 iframe 仅使用配置的服务域名。"
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"type": "code",
|
|
156
|
+
"title": "Pages 嵌入语法",
|
|
157
|
+
"language": "json",
|
|
158
|
+
"code": "{\n \"blocks\": [\n {\n \"columns\": 1,\n \"cells\": [\n [\n {\n \"type\": \"text\",\n \"text\": \"!embed[ishare](https://share.js.gripe/s/REPLACE_WITH_REAL_SHARE_ID)\"\n }\n ]\n ]\n }\n ]\n}"
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"type": "link-list",
|
|
162
|
+
"title": "服务说明",
|
|
163
|
+
"items": [
|
|
164
|
+
{
|
|
165
|
+
"label": "ishare",
|
|
166
|
+
"url": "https://github.com/jsw-teams/ishare/blob/main/docs/zh-cn.md"
|
|
167
|
+
}
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
]
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"columns": 1,
|
|
175
|
+
"cells": [
|
|
176
|
+
[
|
|
177
|
+
{
|
|
178
|
+
"type": "text",
|
|
179
|
+
"heading": "通用社交媒体嵌入",
|
|
180
|
+
"text": "通用媒体预设仅保留 YouTube 和 X;share.js.gripe 不启用任何通用平台。自定义平台可按需在 config.yml 注册。逐项设 enabled: false 会移除授权条目和网络权限,区块保留本地未加载说明与原始链接。标准提供方使用 oembedEndpoint,构建阶段缓存元数据;浏览器必须先授权并点击加载。sourceOrigins 指定分享链接域名,embedOrigins 指定播放器与资源域名,embedScripts 是按需加载的完整脚本地址。Instagram 和 Facebook 使用公开内容的官方 iframe,不要求把 Meta 令牌放入前端;私密、禁止嵌入或平台限制的内容仍可能无法显示。Mastodon 需将默认实例替换为实际实例。"
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"type": "code",
|
|
184
|
+
"title": "Pages 嵌入语法",
|
|
185
|
+
"language": "json",
|
|
186
|
+
"code": "{\n \"blocks\": [\n {\n \"columns\": 2,\n \"cells\": [\n [\n {\n \"type\": \"text\",\n \"heading\": \"视频与说明\",\n \"text\": \"在播放器旁介绍内容。\"\n }\n ],\n [\n {\n \"type\": \"text\",\n \"text\": \"!embed[youtube](https://www.youtube.com/watch?v=jNQXAC9IVRw)\"\n }\n ]\n ]\n }\n ]\n}"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"type": "text",
|
|
190
|
+
"heading": "自定义 oEmbed 与导航跳转",
|
|
191
|
+
"text": "在 config.yml 新增 provider: oembed 服务,填写授权说明、backendUrl、oembedEndpoint 与分享链接和媒体域名。公开接口不得包含密钥;需凭据的平台使用外部网关。Pages 的 text 区块与文章正文采用相同的 !embed[服务 ID](URL) 语法。导航和页脚链接含下拉选项均支持 target: _self 或 target: _blank。"
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"type": "text",
|
|
195
|
+
"heading": "按服务配置自动生成 CSP",
|
|
196
|
+
"text": "构建会生成 Content-Security-Policy 响应头,并在 HTML 中加入适用于静态托管的同等策略。启用的服务按配置贡献脚本、连接、iframe 和媒体来源;关闭的服务不贡献网络权限。CSP 只限定网络来源,访客仍需同意后才会加载可选服务。自定义服务可增加 csp 指令映射,例如 connect-src: [https://api.example.com],只接受 HTTPS 来源。本站上传接口等必要权限保留在源 _headers 中;GTM 容器调用额外提供方时需明确配置其域名。"
|
|
197
|
+
}
|
|
198
|
+
]
|
|
199
|
+
]
|
|
200
|
+
}
|
|
201
|
+
]
|
|
202
|
+
}
|